* New -action option and set-action QMP command (Alejandro)

* More vl.c cleanup (myself with help from Daniel and Igor)
 * Remove deprecated options (Philippe, Thomas)
 * Dirty bitmap fix (Zenghui)
 * icount caching speedup (Pavel)
 * SCSI race fix (Maxim)
 * Remove pre-GCC 4.8 code (Marc-André)
 -----BEGIN PGP SIGNATURE-----
 
 iQFIBAABCAAyFiEE8TM4V0tmI4mGbHaCv/vSX3jHroMFAl/Y+BQUHHBib256aW5p
 QHJlZGhhdC5jb20ACgkQv/vSX3jHroOhPwf9GnBgYnsJcMpvsmKPZ0aU7qhCtGxY
 HrlxRXxGSK1kBlbRnIA2XEJe07isQRyT4q3dpLH+cJkA6gBAmBICvO0tHY8eW0OB
 6qbTPdYvrIhjBkeeEy+WGmgU+kw/YXCOCx6TdZFjYm6BqalAMXuTGw82jLlKyOGI
 2Ehc0PNnOTPZuRSmIgs7Kox5lDViJIX1ydMUeWw1lMksosCgeyZzecVdp9Ehmv9O
 SuSgq5ilmsUvzrV9DbYaT3/KinwLI+ZHPCiOd75WWB+cX546iji1nH9aaUHPnwy0
 EsAGza06A93uyiQNOxIPkF7Wd27e+u1VkfsCdOBNS8hy3sOeKhh/yZxkgA==
 =sFe1
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/bonzini-gitlab/tags/for-upstream' into staging

* New -action option and set-action QMP command (Alejandro)
* More vl.c cleanup (myself with help from Daniel and Igor)
* Remove deprecated options (Philippe, Thomas)
* Dirty bitmap fix (Zenghui)
* icount caching speedup (Pavel)
* SCSI race fix (Maxim)
* Remove pre-GCC 4.8 code (Marc-André)

# gpg: Signature made Tue 15 Dec 2020 17:53:24 GMT
# gpg:                using RSA key F13338574B662389866C7682BFFBD25F78C7AE83
# gpg:                issuer "pbonzini@redhat.com"
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" [full]
# gpg:                 aka "Paolo Bonzini <pbonzini@redhat.com>" [full]
# Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4  E2F7 7E15 100C CD36 69B1
#      Subkey fingerprint: F133 3857 4B66 2389 866C  7682 BFFB D25F 78C7 AE83

* remotes/bonzini-gitlab/tags/for-upstream: (45 commits)
  build: -no-pie is no functional linker flag
  scripts/git.orderfile: Keep files with .inc extension sorted
  compiler.h: remove QEMU_GNUC_PREREQ
  linux-user: remove GNUC check
  compiler: remove GNUC check
  xen: remove GNUC check
  poison: remove GNUC check
  compiler.h: explicit case for Clang printf attribute
  virtiofsd: replace _Static_assert with QEMU_BUILD_BUG_ON
  tests: remove GCC < 4 fallbacks
  qemu-plugin.h: remove GCC < 4
  compiler.h: remove GCC < 3 __builtin_expect fallback
  accel/tcg: Remove special case for GCC < 4.6
  qemu/atomic: Drop special case for unsupported compiler
  hw/core: Restrict 'fw-path-provider.c' to system mode emulation
  docs: set CONFDIR when running sphinx
  vl: rename local variable in configure_accelerators
  qemu-option: pass QemuOptsList to opts_accepts_any
  qemu-option: simplify search for end of key
  kvm: Take into account the unaligned section size when preparing bitmap
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

# Conflicts:
#	softmmu/vl.c
This commit is contained in:
Peter Maydell 2020-12-15 21:24:31 +00:00
commit af3f37319c
79 changed files with 1833 additions and 1596 deletions

View File

@ -2356,6 +2356,7 @@ M: Paolo Bonzini <pbonzini@redhat.com>
S: Maintained
F: include/qemu/main-loop.h
F: include/sysemu/runstate.h
F: include/sysemu/runstate-action.h
F: util/main-loop.c
F: util/qemu-timer.c
F: softmmu/vl.c
@ -2364,6 +2365,7 @@ F: softmmu/cpus.c
F: softmmu/cpu-throttle.c
F: softmmu/cpu-timers.c
F: softmmu/icount.c
F: softmmu/runstate-action.c
F: qapi/run-state.json
Read, Copy, Update (RCU)

View File

@ -745,7 +745,7 @@ static int kvm_log_clear_one_slot(KVMSlot *mem, int as_id, uint64_t start,
assert(bmap_start % BITS_PER_LONG == 0);
/* We should never do log_clear before log_sync */
assert(mem->dirty_bmap);
if (start_delta) {
if (start_delta || bmap_npages - size / psize) {
/* Slow path - we need to manipulate a temp bitmap */
bmap_clear = bitmap_new(bmap_npages);
bitmap_copy_with_src_offset(bmap_clear, mem->dirty_bmap,
@ -758,7 +758,10 @@ static int kvm_log_clear_one_slot(KVMSlot *mem, int as_id, uint64_t start,
bitmap_clear(bmap_clear, 0, start_delta);
d.dirty_bitmap = bmap_clear;
} else {
/* Fast path - start address aligns well with BITS_PER_LONG */
/*
* Fast path - both start and size align well with BITS_PER_LONG
* (or the end of memory slot)
*/
d.dirty_bitmap = mem->dirty_bmap + BIT_WORD(bmap_start);
}
@ -2013,7 +2016,6 @@ static int kvm_init(MachineState *ms)
const KVMCapabilityInfo *missing_cap;
int ret;
int type = 0;
const char *kvm_type;
uint64_t dirty_log_manual_caps;
s = KVM_STATE(ms->accelerator);
@ -2069,13 +2071,11 @@ static int kvm_init(MachineState *ms)
}
s->as = g_new0(struct KVMAs, s->nr_as);
kvm_type = qemu_opt_get(qemu_get_machine_opts(), "kvm-type");
if (mc->kvm_type) {
if (object_property_find(OBJECT(current_machine), "kvm-type")) {
g_autofree char *kvm_type = object_property_get_str(OBJECT(current_machine),
"kvm-type",
&error_abort);
type = mc->kvm_type(ms, kvm_type);
} else if (kvm_type) {
ret = -EINVAL;
fprintf(stderr, "Invalid argument kvm-type=%s\n", kvm_type);
goto err;
}
do {

View File

@ -685,7 +685,7 @@ static inline void cpu_loop_exec_tb(CPUState *cpu, TranslationBlock *tb,
insns_left = MIN(0xffff, cpu->icount_budget);
cpu_neg(cpu)->icount_decr.u16.low = insns_left;
cpu->icount_extra = cpu->icount_budget - insns_left;
if (!cpu->icount_extra) {
if (!cpu->icount_extra && insns_left < tb->icount) {
/* Execute any remaining instructions, then let the main loop
* handle the next event.
*/
@ -724,7 +724,7 @@ int cpu_exec(CPUState *cpu)
/* prepare setjmp context for exception handling */
if (sigsetjmp(cpu->jmp_env, 0) != 0) {
#if defined(__clang__) || !QEMU_GNUC_PREREQ(4, 6)
#if defined(__clang__)
/* Some compilers wrongly smash all local variables after
* siglongjmp. There were bug reports for gcc 4.5.0 and clang.
* Reload essential local variables here for those compilers.

View File

@ -2379,7 +2379,7 @@ void dump_exec_info(void)
qemu_printf("Translation buffer state:\n");
/*
* Report total code size including the padding and TB structs;
* otherwise users might think "-tb-size" is not honoured.
* otherwise users might think "-accel tcg,tb-size" is not honoured.
* For avg host size we use the precise numbers from tb_tree_stats though.
*/
qemu_printf("gen code size %zu/%zu\n",

View File

@ -33,6 +33,13 @@
/* MUX driver for serial I/O splitting */
/*
* Set to false by suspend_mux_open. Open events are delayed until
* resume_mux_open. Usually suspend_mux_open is called before
* command line processing and resume_mux_open afterwards.
*/
static bool muxes_opened = true;
/* Called with chr_write_lock held. */
static int mux_chr_write(Chardev *chr, const uint8_t *buf, int len)
{
@ -237,7 +244,7 @@ void mux_chr_send_all_event(Chardev *chr, QEMUChrEvent event)
MuxChardev *d = MUX_CHARDEV(chr);
int i;
if (!machine_init_done) {
if (!muxes_opened) {
return;
}
@ -328,7 +335,7 @@ static void qemu_chr_open_mux(Chardev *chr,
/* only default to opened state if we've realized the initial
* set of muxes
*/
*be_opened = machine_init_done;
*be_opened = muxes_opened;
qemu_chr_fe_init(&d->chr, drv, errp);
}
@ -360,19 +367,42 @@ static void qemu_chr_parse_mux(QemuOpts *opts, ChardevBackend *backend,
* mux will receive CHR_EVENT_OPENED notifications for the BE
* immediately.
*/
static int open_muxes(Chardev *chr)
static void open_muxes(Chardev *chr)
{
/* send OPENED to all already-attached FEs */
mux_chr_send_all_event(chr, CHR_EVENT_OPENED);
/*
* mark mux as OPENED so any new FEs will immediately receive
* OPENED event
*/
chr->be_open = 1;
}
void suspend_mux_open(void)
{
muxes_opened = false;
}
static int chardev_options_parsed_cb(Object *child, void *opaque)
{
Chardev *chr = (Chardev *)child;
ChardevClass *class = CHARDEV_GET_CLASS(chr);
if (!chr->be_open && class->chr_options_parsed) {
class->chr_options_parsed(chr);
}
return 0;
}
void resume_mux_open(void)
{
muxes_opened = true;
object_child_foreach(get_chardevs_root(),
chardev_options_parsed_cb, NULL);
}
static void char_mux_class_init(ObjectClass *oc, void *data)
{
ChardevClass *cc = CHARDEV_CLASS(oc);
@ -383,7 +413,7 @@ static void char_mux_class_init(ObjectClass *oc, void *data)
cc->chr_accept_input = mux_chr_accept_input;
cc->chr_add_watch = mux_chr_add_watch;
cc->chr_be_event = mux_chr_be_event;
cc->chr_machine_done = open_muxes;
cc->chr_options_parsed = open_muxes;
cc->chr_update_read_handler = mux_chr_update_read_handlers;
}

View File

@ -1,69 +0,0 @@
/*
* QEMU System Emulator
*
* Copyright (c) 2003-2008 Fabrice Bellard
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "qemu/osdep.h"
#include "sysemu/sysemu.h"
#include "chardev/char.h"
#include "qemu/error-report.h"
#include "chardev-internal.h"
static int chardev_machine_done_notify_one(Object *child, void *opaque)
{
Chardev *chr = (Chardev *)child;
ChardevClass *class = CHARDEV_GET_CLASS(chr);
if (class->chr_machine_done) {
return class->chr_machine_done(chr);
}
return 0;
}
static void chardev_machine_done_hook(Notifier *notifier, void *unused)
{
int ret = object_child_foreach(get_chardevs_root(),
chardev_machine_done_notify_one, NULL);
if (ret) {
error_report("Failed to call chardev machine_done hooks");
exit(1);
}
}
static Notifier chardev_machine_done_notify = {
.notify = chardev_machine_done_hook,
};
static void register_types(void)
{
/*
* This must be done after machine init, since we register FEs with muxes
* as part of realize functions like serial_isa_realizefn when -nographic
* is specified.
*/
qemu_add_machine_init_done_notifier(&chardev_machine_done_notify);
}
type_init(register_types);

View File

@ -25,7 +25,7 @@ chardev_ss.add(when: 'CONFIG_WIN32', if_true: files(
chardev_ss = chardev_ss.apply(config_host, strict: false)
softmmu_ss.add(files('chardev-sysemu.c', 'msmouse.c', 'wctablet.c', 'testdev.c'))
softmmu_ss.add(files('msmouse.c', 'wctablet.c', 'testdev.c'))
chardev_modules = {}

3
configure vendored
View File

@ -2137,7 +2137,6 @@ EOF
# Check we support --no-pie first; we will need this for building ROMs.
if compile_prog "-Werror -fno-pie" "-no-pie"; then
CFLAGS_NOPIE="-fno-pie"
LDFLAGS_NOPIE="-no-pie"
fi
if test "$static" = "yes"; then
@ -2153,7 +2152,6 @@ if test "$static" = "yes"; then
fi
elif test "$pie" = "no"; then
CONFIGURE_CFLAGS="$CFLAGS_NOPIE $CONFIGURE_CFLAGS"
CONFIGURE_LDFLAGS="$LDFLAGS_NOPIE $CONFIGURE_LDFLAGS"
elif compile_prog "-Werror -fPIE -DPIE" "-pie"; then
CONFIGURE_CFLAGS="-fPIE -DPIE $CONFIGURE_CFLAGS"
CONFIGURE_LDFLAGS="-pie $CONFIGURE_LDFLAGS"
@ -6714,7 +6712,6 @@ echo "QEMU_CXXFLAGS=$QEMU_CXXFLAGS" >> $config_host_mak
echo "GLIB_CFLAGS=$glib_cflags" >> $config_host_mak
echo "GLIB_LIBS=$glib_libs" >> $config_host_mak
echo "QEMU_LDFLAGS=$QEMU_LDFLAGS" >> $config_host_mak
echo "LDFLAGS_NOPIE=$LDFLAGS_NOPIE" >> $config_host_mak
echo "LD_I386_EMULATION=$ld_i386_emulation" >> $config_host_mak
echo "EXESUF=$EXESUF" >> $config_host_mak
echo "HOST_DSOSUF=$HOST_DSOSUF" >> $config_host_mak

View File

@ -9,7 +9,7 @@ endif
# Check if tools are available to build documentation.
build_docs = false
if sphinx_build.found()
SPHINX_ARGS = [sphinx_build]
SPHINX_ARGS = ['env', 'CONFDIR=' + qemu_confdir, sphinx_build]
# If we're making warnings fatal, apply this to Sphinx runs as well
if get_option('werror')
SPHINX_ARGS += [ '-W' ]

View File

@ -75,12 +75,6 @@ The ``pretty=on|off`` switch has no effect for HMP monitors, but is
silently ignored. Using the switch with HMP monitors will become an
error in the future.
``-realtime`` (since 4.1)
'''''''''''''''''''''''''
The ``-realtime mlock=on|off`` argument has been replaced by the
``-overcommit mem-lock=on|off`` argument.
RISC-V ``-bios`` (since 5.1)
''''''''''''''''''''''''''''
@ -100,19 +94,6 @@ QEMU 5.1 has three options:
to the user to load all the images they need.
3. ``-bios <file>`` - Tells QEMU to load the specified file as the firmwrae.
``-tb-size`` option (since 5.0)
'''''''''''''''''''''''''''''''
QEMU 5.0 introduced an alternative syntax to specify the size of the translation
block cache, ``-accel tcg,tb-size=``. The new syntax deprecates the
previously available ``-tb-size`` option.
``-show-cursor`` option (since 5.0)
'''''''''''''''''''''''''''''''''''
Use ``-display sdl,show-cursor=on`` or
``-display gtk,show-cursor=on`` instead.
``Configuring floppies with ``-global``
'''''''''''''''''''''''''''''''''''''''
@ -493,230 +474,3 @@ nanoMIPS ISA
The ``nanoMIPS`` ISA has never been upstreamed to any compiler toolchain.
As it is hard to generate binaries for it, declare it deprecated.
Recently removed features
=========================
What follows is a record of recently removed, formerly deprecated
features that serves as a record for users who have encountered
trouble after a recent upgrade.
System emulator command line arguments
--------------------------------------
``-net ...,name=``\ *name* (removed in 5.1)
'''''''''''''''''''''''''''''''''''''''''''
The ``name`` parameter of the ``-net`` option was a synonym
for the ``id`` parameter, which should now be used instead.
``-no-kvm`` (removed in 5.2)
''''''''''''''''''''''''''''
The ``-no-kvm`` argument was a synonym for setting ``-machine accel=tcg``.
QEMU Machine Protocol (QMP) commands
------------------------------------
``block-dirty-bitmap-add`` "autoload" parameter (since 4.2.0)
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
The "autoload" parameter has been ignored since 2.12.0. All bitmaps
are automatically loaded from qcow2 images.
``cpu-add`` (removed in 5.2)
''''''''''''''''''''''''''''
Use ``device_add`` for hotplugging vCPUs instead of ``cpu-add``. See
documentation of ``query-hotpluggable-cpus`` for additional details.
Human Monitor Protocol (HMP) commands
-------------------------------------
The ``hub_id`` parameter of ``hostfwd_add`` / ``hostfwd_remove`` (removed in 5.0)
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
The ``[hub_id name]`` parameter tuple of the 'hostfwd_add' and
'hostfwd_remove' HMP commands has been replaced by ``netdev_id``.
``cpu-add`` (removed in 5.2)
''''''''''''''''''''''''''''
Use ``device_add`` for hotplugging vCPUs instead of ``cpu-add``. See
documentation of ``query-hotpluggable-cpus`` for additional details.
Guest Emulator ISAs
-------------------
RISC-V ISA privilege specification version 1.09.1 (removed in 5.1)
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
The RISC-V ISA privilege specification version 1.09.1 has been removed.
QEMU supports both the newer version 1.10.0 and the ratified version 1.11.0, these
should be used instead of the 1.09.1 version.
System emulator CPUS
--------------------
KVM guest support on 32-bit Arm hosts (removed in 5.2)
''''''''''''''''''''''''''''''''''''''''''''''''''''''
The Linux kernel has dropped support for allowing 32-bit Arm systems
to host KVM guests as of the 5.7 kernel. Accordingly, QEMU is deprecating
its support for this configuration and will remove it in a future version.
Running 32-bit guests on a 64-bit Arm host remains supported.
RISC-V ISA Specific CPUs (removed in 5.1)
'''''''''''''''''''''''''''''''''''''''''
The RISC-V cpus with the ISA version in the CPU name have been removed. The
four CPUs are: ``rv32gcsu-v1.9.1``, ``rv32gcsu-v1.10.0``, ``rv64gcsu-v1.9.1`` and
``rv64gcsu-v1.10.0``. Instead the version can be specified via the CPU ``priv_spec``
option when using the ``rv32`` or ``rv64`` CPUs.
RISC-V no MMU CPUs (removed in 5.1)
'''''''''''''''''''''''''''''''''''
The RISC-V no MMU cpus have been removed. The two CPUs: ``rv32imacu-nommu`` and
``rv64imacu-nommu`` can no longer be used. Instead the MMU status can be specified
via the CPU ``mmu`` option when using the ``rv32`` or ``rv64`` CPUs.
System emulator machines
------------------------
``spike_v1.9.1`` and ``spike_v1.10`` (removed in 5.1)
'''''''''''''''''''''''''''''''''''''''''''''''''''''
The version specific Spike machines have been removed in favour of the
generic ``spike`` machine. If you need to specify an older version of the RISC-V
spec you can use the ``-cpu rv64gcsu,priv_spec=v1.10.0`` command line argument.
mips ``r4k`` platform (removed in 5.2)
''''''''''''''''''''''''''''''''''''''
This machine type was very old and unmaintained. Users should use the ``malta``
machine type instead.
Related binaries
----------------
``qemu-nbd --partition`` (removed in 5.0)
'''''''''''''''''''''''''''''''''''''''''
The ``qemu-nbd --partition $digit`` code (also spelled ``-P``)
could only handle MBR partitions, and never correctly handled logical
partitions beyond partition 5. Exporting a partition can still be
done by utilizing the ``--image-opts`` option with a raw blockdev
using the ``offset`` and ``size`` parameters layered on top of
any other existing blockdev. For example, if partition 1 is 100MiB
long starting at 1MiB, the old command::
qemu-nbd -t -P 1 -f qcow2 file.qcow2
can be rewritten as::
qemu-nbd -t --image-opts driver=raw,offset=1M,size=100M,file.driver=qcow2,file.file.driver=file,file.file.filename=file.qcow2
``qemu-img convert -n -o`` (removed in 5.1)
'''''''''''''''''''''''''''''''''''''''''''
All options specified in ``-o`` are image creation options, so
they are now rejected when used with ``-n`` to skip image creation.
``qemu-img create -b bad file $size`` (removed in 5.1)
''''''''''''''''''''''''''''''''''''''''''''''''''''''
When creating an image with a backing file that could not be opened,
``qemu-img create`` used to issue a warning about the failure but
proceed with the image creation if an explicit size was provided.
However, as the ``-u`` option exists for this purpose, it is safer to
enforce that any failure to open the backing image (including if the
backing file is missing or an incorrect format was specified) is an
error when ``-u`` is not used.
Command line options
--------------------
``-smp`` (invalid topologies) (removed 5.2)
'''''''''''''''''''''''''''''''''''''''''''
CPU topology properties should describe whole machine topology including
possible CPUs.
However, historically it was possible to start QEMU with an incorrect topology
where *n* <= *sockets* * *cores* * *threads* < *maxcpus*,
which could lead to an incorrect topology enumeration by the guest.
Support for invalid topologies is removed, the user must ensure
topologies described with -smp include all possible cpus, i.e.
*sockets* * *cores* * *threads* = *maxcpus*.
``-numa`` node (without memory specified) (removed 5.2)
'''''''''''''''''''''''''''''''''''''''''''''''''''''''
Splitting RAM by default between NUMA nodes had the same issues as ``mem``
parameter with the difference that the role of the user plays QEMU using
implicit generic or board specific splitting rule.
Use ``memdev`` with *memory-backend-ram* backend or ``mem`` (if
it's supported by used machine type) to define mapping explicitly instead.
Users of existing VMs, wishing to preserve the same RAM distribution, should
configure it explicitly using ``-numa node,memdev`` options. Current RAM
distribution can be retrieved using HMP command ``info numa`` and if separate
memory devices (pc|nv-dimm) are present use ``info memory-device`` and subtract
device memory from output of ``info numa``.
``-numa node,mem=``\ *size* (removed in 5.1)
''''''''''''''''''''''''''''''''''''''''''''
The parameter ``mem`` of ``-numa node`` was used to assign a part of
guest RAM to a NUMA node. But when using it, it's impossible to manage a specified
RAM chunk on the host side (like bind it to a host node, setting bind policy, ...),
so the guest ends up with the fake NUMA configuration with suboptiomal performance.
However since 2014 there is an alternative way to assign RAM to a NUMA node
using parameter ``memdev``, which does the same as ``mem`` and adds
means to actually manage node RAM on the host side. Use parameter ``memdev``
with *memory-backend-ram* backend as replacement for parameter ``mem``
to achieve the same fake NUMA effect or a properly configured
*memory-backend-file* backend to actually benefit from NUMA configuration.
New machine versions (since 5.1) will not accept the option but it will still
work with old machine types. User can check the QAPI schema to see if the legacy
option is supported by looking at MachineInfo::numa-mem-supported property.
``-mem-path`` fallback to RAM (removed in 5.0)
''''''''''''''''''''''''''''''''''''''''''''''
If guest RAM allocation from file pointed by ``mem-path`` failed,
QEMU was falling back to allocating from RAM, which might have resulted
in unpredictable behavior since the backing file specified by the user
as ignored. Currently, users are responsible for making sure the backing storage
specified with ``-mem-path`` can actually provide the guest RAM configured with
``-m`` and QEMU fails to start up if RAM allocation is unsuccessful.
``-smp`` (invalid topologies) (removed 5.2)
'''''''''''''''''''''''''''''''''''''''''''
CPU topology properties should describe whole machine topology including
possible CPUs.
However, historically it was possible to start QEMU with an incorrect topology
where *n* <= *sockets* * *cores* * *threads* < *maxcpus*,
which could lead to an incorrect topology enumeration by the guest.
Support for invalid topologies is removed, the user must ensure
topologies described with -smp include all possible cpus, i.e.
*sockets* * *cores* * *threads* = *maxcpus*.
``-machine enforce-config-section=on|off`` (removed 5.2)
''''''''''''''''''''''''''''''''''''''''''''''''''''''''
The ``enforce-config-section`` property was replaced by the
``-global migration.send-configuration={on|off}`` option.
Block devices
-------------
VXHS backend (removed in 5.1)
'''''''''''''''''''''''''''''
The VXHS code does not compile since v2.12.0. It was removed in 5.1.

View File

@ -35,5 +35,6 @@ Contents:
targets
security
deprecated
removed-features
build-platforms
license

View File

@ -0,0 +1,243 @@
Removed features
================
What follows is a record of recently removed, formerly deprecated
features that serves as a record for users who have encountered
trouble after a recent upgrade.
System emulator command line arguments
--------------------------------------
``-net ...,name=``\ *name* (removed in 5.1)
'''''''''''''''''''''''''''''''''''''''''''
The ``name`` parameter of the ``-net`` option was a synonym
for the ``id`` parameter, which should now be used instead.
``-no-kvm`` (removed in 5.2)
''''''''''''''''''''''''''''
The ``-no-kvm`` argument was a synonym for setting ``-machine accel=tcg``.
``-realtime`` (removed in 6.0)
''''''''''''''''''''''''''''''
The ``-realtime mlock=on|off`` argument has been replaced by the
``-overcommit mem-lock=on|off`` argument.
``-show-cursor`` option (since 5.0)
'''''''''''''''''''''''''''''''''''
Use ``-display sdl,show-cursor=on``, ``-display gtk,show-cursor=on``
or ``-display default,show-cursor=on`` instead.
``-tb-size`` option (removed in 6.0)
''''''''''''''''''''''''''''''''''''
QEMU 5.0 introduced an alternative syntax to specify the size of the translation
block cache, ``-accel tcg,tb-size=``.
QEMU Machine Protocol (QMP) commands
------------------------------------
``block-dirty-bitmap-add`` "autoload" parameter (removed in 4.2.0)
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
The "autoload" parameter has been ignored since 2.12.0. All bitmaps
are automatically loaded from qcow2 images.
``cpu-add`` (removed in 5.2)
''''''''''''''''''''''''''''
Use ``device_add`` for hotplugging vCPUs instead of ``cpu-add``. See
documentation of ``query-hotpluggable-cpus`` for additional details.
Human Monitor Protocol (HMP) commands
-------------------------------------
The ``hub_id`` parameter of ``hostfwd_add`` / ``hostfwd_remove`` (removed in 5.0)
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
The ``[hub_id name]`` parameter tuple of the 'hostfwd_add' and
'hostfwd_remove' HMP commands has been replaced by ``netdev_id``.
``cpu-add`` (removed in 5.2)
''''''''''''''''''''''''''''
Use ``device_add`` for hotplugging vCPUs instead of ``cpu-add``. See
documentation of ``query-hotpluggable-cpus`` for additional details.
Guest Emulator ISAs
-------------------
RISC-V ISA privilege specification version 1.09.1 (removed in 5.1)
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
The RISC-V ISA privilege specification version 1.09.1 has been removed.
QEMU supports both the newer version 1.10.0 and the ratified version 1.11.0, these
should be used instead of the 1.09.1 version.
System emulator CPUS
--------------------
KVM guest support on 32-bit Arm hosts (removed in 5.2)
''''''''''''''''''''''''''''''''''''''''''''''''''''''
The Linux kernel has dropped support for allowing 32-bit Arm systems
to host KVM guests as of the 5.7 kernel. Accordingly, QEMU is deprecating
its support for this configuration and will remove it in a future version.
Running 32-bit guests on a 64-bit Arm host remains supported.
RISC-V ISA Specific CPUs (removed in 5.1)
'''''''''''''''''''''''''''''''''''''''''
The RISC-V cpus with the ISA version in the CPU name have been removed. The
four CPUs are: ``rv32gcsu-v1.9.1``, ``rv32gcsu-v1.10.0``, ``rv64gcsu-v1.9.1`` and
``rv64gcsu-v1.10.0``. Instead the version can be specified via the CPU ``priv_spec``
option when using the ``rv32`` or ``rv64`` CPUs.
RISC-V no MMU CPUs (removed in 5.1)
'''''''''''''''''''''''''''''''''''
The RISC-V no MMU cpus have been removed. The two CPUs: ``rv32imacu-nommu`` and
``rv64imacu-nommu`` can no longer be used. Instead the MMU status can be specified
via the CPU ``mmu`` option when using the ``rv32`` or ``rv64`` CPUs.
System emulator machines
------------------------
``spike_v1.9.1`` and ``spike_v1.10`` (removed in 5.1)
'''''''''''''''''''''''''''''''''''''''''''''''''''''
The version specific Spike machines have been removed in favour of the
generic ``spike`` machine. If you need to specify an older version of the RISC-V
spec you can use the ``-cpu rv64gcsu,priv_spec=v1.10.0`` command line argument.
mips ``r4k`` platform (removed in 5.2)
''''''''''''''''''''''''''''''''''''''
This machine type was very old and unmaintained. Users should use the ``malta``
machine type instead.
Related binaries
----------------
``qemu-nbd --partition`` (removed in 5.0)
'''''''''''''''''''''''''''''''''''''''''
The ``qemu-nbd --partition $digit`` code (also spelled ``-P``)
could only handle MBR partitions, and never correctly handled logical
partitions beyond partition 5. Exporting a partition can still be
done by utilizing the ``--image-opts`` option with a raw blockdev
using the ``offset`` and ``size`` parameters layered on top of
any other existing blockdev. For example, if partition 1 is 100MiB
long starting at 1MiB, the old command::
qemu-nbd -t -P 1 -f qcow2 file.qcow2
can be rewritten as::
qemu-nbd -t --image-opts driver=raw,offset=1M,size=100M,file.driver=qcow2,file.file.driver=file,file.file.filename=file.qcow2
``qemu-img convert -n -o`` (removed in 5.1)
'''''''''''''''''''''''''''''''''''''''''''
All options specified in ``-o`` are image creation options, so
they are now rejected when used with ``-n`` to skip image creation.
``qemu-img create -b bad file $size`` (removed in 5.1)
''''''''''''''''''''''''''''''''''''''''''''''''''''''
When creating an image with a backing file that could not be opened,
``qemu-img create`` used to issue a warning about the failure but
proceed with the image creation if an explicit size was provided.
However, as the ``-u`` option exists for this purpose, it is safer to
enforce that any failure to open the backing image (including if the
backing file is missing or an incorrect format was specified) is an
error when ``-u`` is not used.
Command line options
--------------------
``-smp`` (invalid topologies) (removed 5.2)
'''''''''''''''''''''''''''''''''''''''''''
CPU topology properties should describe whole machine topology including
possible CPUs.
However, historically it was possible to start QEMU with an incorrect topology
where *n* <= *sockets* * *cores* * *threads* < *maxcpus*,
which could lead to an incorrect topology enumeration by the guest.
Support for invalid topologies is removed, the user must ensure
topologies described with -smp include all possible cpus, i.e.
*sockets* * *cores* * *threads* = *maxcpus*.
``-numa`` node (without memory specified) (removed 5.2)
'''''''''''''''''''''''''''''''''''''''''''''''''''''''
Splitting RAM by default between NUMA nodes had the same issues as ``mem``
parameter with the difference that the role of the user plays QEMU using
implicit generic or board specific splitting rule.
Use ``memdev`` with *memory-backend-ram* backend or ``mem`` (if
it's supported by used machine type) to define mapping explicitly instead.
Users of existing VMs, wishing to preserve the same RAM distribution, should
configure it explicitly using ``-numa node,memdev`` options. Current RAM
distribution can be retrieved using HMP command ``info numa`` and if separate
memory devices (pc|nv-dimm) are present use ``info memory-device`` and subtract
device memory from output of ``info numa``.
``-numa node,mem=``\ *size* (removed in 5.1)
''''''''''''''''''''''''''''''''''''''''''''
The parameter ``mem`` of ``-numa node`` was used to assign a part of
guest RAM to a NUMA node. But when using it, it's impossible to manage a specified
RAM chunk on the host side (like bind it to a host node, setting bind policy, ...),
so the guest ends up with the fake NUMA configuration with suboptiomal performance.
However since 2014 there is an alternative way to assign RAM to a NUMA node
using parameter ``memdev``, which does the same as ``mem`` and adds
means to actually manage node RAM on the host side. Use parameter ``memdev``
with *memory-backend-ram* backend as replacement for parameter ``mem``
to achieve the same fake NUMA effect or a properly configured
*memory-backend-file* backend to actually benefit from NUMA configuration.
New machine versions (since 5.1) will not accept the option but it will still
work with old machine types. User can check the QAPI schema to see if the legacy
option is supported by looking at MachineInfo::numa-mem-supported property.
``-mem-path`` fallback to RAM (removed in 5.0)
''''''''''''''''''''''''''''''''''''''''''''''
If guest RAM allocation from file pointed by ``mem-path`` failed,
QEMU was falling back to allocating from RAM, which might have resulted
in unpredictable behavior since the backing file specified by the user
as ignored. Currently, users are responsible for making sure the backing storage
specified with ``-mem-path`` can actually provide the guest RAM configured with
``-m`` and QEMU fails to start up if RAM allocation is unsuccessful.
``-smp`` (invalid topologies) (removed 5.2)
'''''''''''''''''''''''''''''''''''''''''''
CPU topology properties should describe whole machine topology including
possible CPUs.
However, historically it was possible to start QEMU with an incorrect topology
where *n* <= *sockets* * *cores* * *threads* < *maxcpus*,
which could lead to an incorrect topology enumeration by the guest.
Support for invalid topologies is removed, the user must ensure
topologies described with -smp include all possible cpus, i.e.
*sockets* * *cores* * *threads* = *maxcpus*.
``-machine enforce-config-section=on|off`` (removed 5.2)
''''''''''''''''''''''''''''''''''''''''''''''''''''''''
The ``enforce-config-section`` property was replaced by the
``-global migration.send-configuration={on|off}`` option.
Block devices
-------------
VXHS backend (removed in 5.1)
'''''''''''''''''''''''''''''
The VXHS code did not compile since v2.12.0. It was removed in 5.1.

View File

@ -45,6 +45,7 @@ ERST
.params = "",
.help = "quit the emulator",
.cmd = hmp_quit,
.flags = "p",
},
SRST

View File

@ -1299,7 +1299,7 @@ void arm_load_kernel(ARMCPU *cpu, MachineState *ms, struct arm_boot_info *info)
info->kernel_filename = ms->kernel_filename;
info->kernel_cmdline = ms->kernel_cmdline;
info->initrd_filename = ms->initrd_filename;
info->dtb_filename = qemu_opt_get(qemu_get_machine_opts(), "dtb");
info->dtb_filename = ms->dtb;
info->dtb_limit = 0;
/* Load the kernel. */

View File

@ -286,10 +286,9 @@ HotpluggableCPUList *qmp_query_hotpluggable_cpus(Error **errp)
void qmp_set_numa_node(NumaOptions *cmd, Error **errp)
{
if (!runstate_check(RUN_STATE_PRECONFIG)) {
error_setg(errp, "The command is permitted only in '%s' state",
RunState_str(RUN_STATE_PRECONFIG));
return;
if (phase_check(PHASE_MACHINE_INITIALIZED)) {
error_setg(errp, "The command is permitted only before the machine has been created");
return;
}
set_numa_options(MACHINE(qdev_get_machine()), cmd, errp);

View File

@ -16,16 +16,21 @@
#include "sysemu/replay.h"
#include "qemu/units.h"
#include "hw/boards.h"
#include "hw/loader.h"
#include "qapi/error.h"
#include "qapi/qapi-visit-common.h"
#include "qapi/visitor.h"
#include "hw/sysbus.h"
#include "sysemu/cpus.h"
#include "sysemu/sysemu.h"
#include "sysemu/reset.h"
#include "sysemu/runstate.h"
#include "sysemu/numa.h"
#include "qemu/error-report.h"
#include "sysemu/qtest.h"
#include "hw/pci/pci.h"
#include "hw/mem/nvdimm.h"
#include "migration/global_state.h"
#include "migration/vmstate.h"
GlobalProperty hw_compat_5_2[] = {};
@ -216,6 +221,8 @@ GlobalProperty hw_compat_2_1[] = {
};
const size_t hw_compat_2_1_len = G_N_ELEMENTS(hw_compat_2_1);
MachineState *current_machine;
static char *machine_get_kernel(Object *obj, Error **errp)
{
MachineState *ms = MACHINE(obj);
@ -1167,17 +1174,16 @@ void machine_run_board_init(MachineState *machine)
}
machine_class->init(machine);
phase_advance(PHASE_MACHINE_INITIALIZED);
}
static NotifierList machine_init_done_notifiers =
NOTIFIER_LIST_INITIALIZER(machine_init_done_notifiers);
bool machine_init_done;
void qemu_add_machine_init_done_notifier(Notifier *notify)
{
notifier_list_add(&machine_init_done_notifiers, notify);
if (machine_init_done) {
if (phase_check(PHASE_MACHINE_READY)) {
notify->notify(notify, NULL);
}
}
@ -1187,10 +1193,48 @@ void qemu_remove_machine_init_done_notifier(Notifier *notify)
notifier_remove(notify);
}
void qemu_run_machine_init_done_notifiers(void)
void qdev_machine_creation_done(void)
{
machine_init_done = true;
cpu_synchronize_all_post_init();
if (current_machine->boot_once) {
qemu_boot_set(current_machine->boot_once, &error_fatal);
qemu_register_reset(restore_boot_order, g_strdup(current_machine->boot_order));
}
/*
* ok, initial machine setup is done, starting from now we can
* only create hotpluggable devices
*/
phase_advance(PHASE_MACHINE_READY);
qdev_assert_realized_properly();
/* TODO: once all bus devices are qdevified, this should be done
* when bus is created by qdev.c */
/*
* TODO: If we had a main 'reset container' that the whole system
* lived in, we could reset that using the multi-phase reset
* APIs. For the moment, we just reset the sysbus, which will cause
* all devices hanging off it (and all their child buses, recursively)
* to be reset. Note that this will *not* reset any Device objects
* which are not attached to some part of the qbus tree!
*/
qemu_register_reset(resettable_cold_reset_fn, sysbus_get_default());
notifier_list_notify(&machine_init_done_notifiers, NULL);
if (rom_check_and_register_reset() != 0) {
exit(1);
}
replay_start();
/* This checkpoint is required by replay to separate prior clock
reading from the other reads, because timer polling functions query
clock values from the log. */
replay_checkpoint(CHECKPOINT_RESET);
qemu_system_reset(SHUTDOWN_CAUSE_NONE);
register_global_state();
}
static const TypeInfo machine_info = {

View File

@ -1,7 +1,6 @@
# core qdev-related obj files, also used by *-user and unit tests
hwcore_files = files(
'bus.c',
'fw-path-provider.c',
'hotplug.c',
'qdev-properties.c',
'qdev.c',
@ -25,6 +24,7 @@ common_ss.add(when: 'CONFIG_SPLIT_IRQ', if_true: files('split-irq.c'))
common_ss.add(when: 'CONFIG_XILINX_AXI', if_true: files('stream.c'))
softmmu_ss.add(files(
'fw-path-provider.c',
'loader.c',
'machine-hmp-cmds.c',
'machine.c',

View File

@ -41,7 +41,6 @@
#include "migration/vmstate.h"
#include "trace.h"
bool qdev_hotplug = false;
static bool qdev_hot_added = false;
bool qdev_hot_removed = false;
@ -404,7 +403,7 @@ void qdev_unrealize(DeviceState *dev)
object_property_set_bool(OBJECT(dev), "realized", false, &error_abort);
}
static int qdev_assert_realized_properly(Object *obj, void *opaque)
static int qdev_assert_realized_properly_cb(Object *obj, void *opaque)
{
DeviceState *dev = DEVICE(object_dynamic_cast(obj, TYPE_DEVICE));
DeviceClass *dc;
@ -417,16 +416,10 @@ static int qdev_assert_realized_properly(Object *obj, void *opaque)
return 0;
}
void qdev_machine_creation_done(void)
void qdev_assert_realized_properly(void)
{
/*
* ok, initial machine setup is done, starting from now we can
* only create hotpluggable devices
*/
qdev_hotplug = true;
object_child_foreach_recursive(object_get_root(),
qdev_assert_realized_properly, NULL);
qdev_assert_realized_properly_cb, NULL);
}
bool qdev_machine_modified(void)
@ -911,7 +904,7 @@ static void device_initfn(Object *obj)
{
DeviceState *dev = DEVICE(obj);
if (qdev_hotplug) {
if (phase_check(PHASE_MACHINE_READY)) {
dev->hotplugged = 1;
qdev_hot_added = true;
}
@ -1144,6 +1137,19 @@ Object *qdev_get_machine(void)
return dev;
}
static MachineInitPhase machine_phase;
bool phase_check(MachineInitPhase phase)
{
return machine_phase >= phase;
}
void phase_advance(MachineInitPhase phase)
{
assert(machine_phase == phase - 1);
machine_phase = phase;
}
static const TypeInfo device_type_info = {
.name = TYPE_DEVICE,
.parent = TYPE_OBJECT,

View File

@ -34,6 +34,7 @@
#include "sysemu/device_tree.h"
#include "sysemu/reset.h"
#include "sysemu/sysemu.h"
#include "hw/boards.h"
#include "hw/loader.h"
#include "elf.h"
#include "qemu/cutils.h"
@ -116,16 +117,14 @@ void microblaze_load_kernel(MicroBlazeCPU *cpu, hwaddr ddr_base,
const char *dtb_filename,
void (*machine_cpu_reset)(MicroBlazeCPU *))
{
QemuOpts *machine_opts;
const char *kernel_filename;
const char *kernel_cmdline;
const char *dtb_arg;
char *filename = NULL;
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");
kernel_filename = current_machine->kernel_filename;
kernel_cmdline = current_machine->kernel_cmdline;
dtb_arg = current_machine->dtb;
/* default to pcbios dtb as passed by machine_init */
if (!dtb_arg && dtb_filename) {
filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, dtb_filename);

View File

@ -39,6 +39,7 @@
#include "sysemu/device_tree.h"
#include "sysemu/reset.h"
#include "sysemu/sysemu.h"
#include "hw/boards.h"
#include "hw/loader.h"
#include "elf.h"
@ -120,16 +121,14 @@ void nios2_load_kernel(Nios2CPU *cpu, hwaddr ddr_base,
const char *dtb_filename,
void (*machine_cpu_reset)(Nios2CPU *))
{
QemuOpts *machine_opts;
const char *kernel_filename;
const char *kernel_cmdline;
const char *dtb_arg;
char *filename = NULL;
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");
kernel_filename = current_machine->kernel_filename;
kernel_cmdline = current_machine->kernel_cmdline;
dtb_arg = current_machine->dtb;
/* default to pcbios dtb as passed by machine_init */
if (!dtb_arg) {
filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, dtb_filename);

View File

@ -179,6 +179,7 @@ static uint64_t msix_table_mmio_read(void *opaque, hwaddr addr,
{
PCIDevice *dev = opaque;
assert(addr + size <= dev->msix_entries_nr * PCI_MSIX_ENTRY_SIZE);
return pci_get_long(dev->msix_table + addr);
}
@ -189,6 +190,8 @@ static void msix_table_mmio_write(void *opaque, hwaddr addr,
int vector = addr / PCI_MSIX_ENTRY_SIZE;
bool was_masked;
assert(addr + size <= dev->msix_entries_nr * PCI_MSIX_ENTRY_SIZE);
was_masked = msix_is_masked(dev, vector);
pci_set_long(dev->msix_table + addr, val);
msix_handle_mask_update(dev, vector, was_masked);

View File

@ -1062,7 +1062,7 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev,
address_space_init(&pci_dev->bus_master_as,
&pci_dev->bus_master_container_region, pci_dev->name);
if (qdev_hotplug) {
if (phase_check(PHASE_MACHINE_READY)) {
pci_init_bus_master(pci_dev);
}
pci_dev->irq_state = 0;

View File

@ -343,9 +343,8 @@ static int ppce500_load_device_tree(PPCE500MachineState *pms,
pmc->pci_pio_base >> 32, pmc->pci_pio_base,
0x0, 0x10000,
};
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");
const char *dtb_file = machine->dtb;
const char *toplevel_compat = machine->dt_compatible;
if (dtb_file) {
char *filename;

View File

@ -3275,6 +3275,19 @@ static void spapr_instance_init(Object *obj)
{
SpaprMachineState *spapr = SPAPR_MACHINE(obj);
SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
MachineState *ms = MACHINE(spapr);
MachineClass *mc = MACHINE_GET_CLASS(ms);
/*
* NVDIMM support went live in 5.1 without considering that, in
* other archs, the user needs to enable NVDIMM support with the
* 'nvdimm' machine option and the default behavior is NVDIMM
* support disabled. It is too late to roll back to the standard
* behavior without breaking 5.1 guests.
*/
if (mc->nvdimm_supported) {
ms->nvdimms_state->is_enabled = true;
}
spapr->htab_fd = -1;
spapr->use_hotplug_event_source = true;

View File

@ -27,10 +27,8 @@
#include "hw/ppc/spapr_nvdimm.h"
#include "hw/mem/nvdimm.h"
#include "qemu/nvdimm-utils.h"
#include "qemu/option.h"
#include "hw/ppc/fdt.h"
#include "qemu/range.h"
#include "sysemu/sysemu.h"
#include "hw/ppc/spapr_numa.h"
bool spapr_nvdimm_validate(HotplugHandler *hotplug_dev, NVDIMMDevice *nvdimm,
@ -38,7 +36,6 @@ bool spapr_nvdimm_validate(HotplugHandler *hotplug_dev, NVDIMMDevice *nvdimm,
{
const MachineClass *mc = MACHINE_GET_CLASS(hotplug_dev);
const MachineState *ms = MACHINE(hotplug_dev);
const char *nvdimm_opt = qemu_opt_get(qemu_get_machine_opts(), "nvdimm");
g_autofree char *uuidstr = NULL;
QemuUUID uuid;
int ret;
@ -48,16 +45,7 @@ bool spapr_nvdimm_validate(HotplugHandler *hotplug_dev, NVDIMMDevice *nvdimm,
return false;
}
/*
* NVDIMM support went live in 5.1 without considering that, in
* other archs, the user needs to enable NVDIMM support with the
* 'nvdimm' machine option and the default behavior is NVDIMM
* support disabled. It is too late to roll back to the standard
* behavior without breaking 5.1 guests. What we can do is to
* ensure that, if the user sets nvdimm=off, we error out
* regardless of being 5.1 or newer.
*/
if (!ms->nvdimms_state->is_enabled && nvdimm_opt) {
if (!ms->nvdimms_state->is_enabled) {
error_setg(errp, "nvdimm device found but 'nvdimm=off' was set");
return false;
}

View File

@ -152,7 +152,7 @@ static int xilinx_load_device_tree(hwaddr addr,
int r;
const char *dtb_filename;
dtb_filename = qemu_opt_get(qemu_get_machine_opts(), "dtb");
dtb_filename = current_machine->dtb;
if (dtb_filename) {
fdt = load_device_tree(dtb_filename, &fdt_size);
if (!fdt) {

View File

@ -100,14 +100,12 @@ static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
int cpu;
uint32_t *cells;
char *nodename;
const char *dtb_filename;
char ethclk_names[] = "pclk\0hclk";
uint32_t plic_phandle, prci_phandle, gpio_phandle, phandle = 1;
uint32_t hfclk_phandle, rtcclk_phandle, phy_phandle;
dtb_filename = qemu_opt_get(qemu_get_machine_opts(), "dtb");
if (dtb_filename) {
fdt = s->fdt = load_device_tree(dtb_filename, &s->fdt_size);
if (ms->dtb) {
fdt = s->fdt = load_device_tree(ms->dtb, &s->fdt_size);
if (!fdt) {
error_report("load_device_tree() failed");
exit(1);

View File

@ -181,7 +181,6 @@ static void create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
{
void *fdt;
int i, cpu, socket;
const char *dtb_filename;
MachineState *mc = MACHINE(s);
uint64_t addr, size;
uint32_t *clint_cells, *plic_cells;
@ -195,9 +194,8 @@ static void create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
hwaddr flashsize = virt_memmap[VIRT_FLASH].size / 2;
hwaddr flashbase = virt_memmap[VIRT_FLASH].base;
dtb_filename = qemu_opt_get(qemu_get_machine_opts(), "dtb");
if (dtb_filename) {
fdt = s->fdt = load_device_tree(dtb_filename, &s->fdt_size);
if (mc->dtb) {
fdt = s->fdt = load_device_tree(mc->dtb, &s->fdt_size);
if (!fdt) {
error_report("load_device_tree() failed");
exit(1);

View File

@ -170,6 +170,8 @@ static void scsi_dma_restart_bh(void *opaque)
scsi_req_unref(req);
}
aio_context_release(blk_get_aio_context(s->conf.blk));
/* Drop the reference that was acquired in scsi_dma_restart_cb */
object_unref(OBJECT(s));
}
void scsi_req_retry(SCSIRequest *req)
@ -188,6 +190,8 @@ static void scsi_dma_restart_cb(void *opaque, int running, RunState state)
}
if (!s->bh) {
AioContext *ctx = blk_get_aio_context(s->conf.blk);
/* The reference is dropped in scsi_dma_restart_bh.*/
object_ref(OBJECT(s));
s->bh = aio_bh_new(ctx, scsi_dma_restart_bh, s);
qemu_bh_schedule(s->bh);
}

View File

@ -97,7 +97,7 @@ void usb_wakeup(USBEndpoint *ep, unsigned int stream)
USBDevice *dev = ep->dev;
USBBus *bus = usb_bus_from_device(dev);
if (!qdev_hotplug) {
if (!phase_check(PHASE_MACHINE_READY)) {
/*
* This is machine init cold plug. No need to wakeup anyone,
* all devices will be reset anyway. And trying to wakeup can

View File

@ -930,7 +930,7 @@ static int virtio_iommu_set_page_size_mask(IOMMUMemoryRegion *mr,
* accept it. Having a different masks is possible but the guest will use
* sub-optimal block sizes, so warn about it.
*/
if (qdev_hotplug) {
if (phase_check(PHASE_MACHINE_READY)) {
int new_granule = ctz64(new_mask);
int cur_granule = ctz64(cur_mask);

View File

@ -233,11 +233,10 @@ static void xtfpga_init(const XtfpgaBoardDesc *board, MachineState *machine)
qemu_irq *extints;
DriveInfo *dinfo;
PFlashCFI01 *flash = NULL;
QemuOpts *machine_opts = qemu_get_machine_opts();
const char *kernel_filename = qemu_opt_get(machine_opts, "kernel");
const char *kernel_cmdline = qemu_opt_get(machine_opts, "append");
const char *dtb_filename = qemu_opt_get(machine_opts, "dtb");
const char *initrd_filename = qemu_opt_get(machine_opts, "initrd");
const char *kernel_filename = machine->kernel_filename;
const char *kernel_cmdline = machine->kernel_cmdline;
const char *dtb_filename = machine->dtb;
const char *initrd_filename = machine->initrd_filename;
const unsigned system_io_size = 224 * MiB;
uint32_t freq = 10000000;
int n;

View File

@ -270,8 +270,7 @@ struct ChardevClass {
void (*chr_set_echo)(Chardev *chr, bool echo);
void (*chr_set_fe_open)(Chardev *chr, int fe_open);
void (*chr_be_event)(Chardev *s, QEMUChrEvent event);
/* Return 0 if succeeded, 1 if failed */
int (*chr_machine_done)(Chardev *chr);
void (*chr_options_parsed)(Chardev *chr);
};
Chardev *qemu_chardev_new(const char *id, const char *typename,
@ -283,6 +282,9 @@ extern int term_escape_char;
GSource *qemu_chr_timeout_add_ms(Chardev *chr, guint ms,
GSourceFunc func, void *private);
void suspend_mux_open(void);
void resume_mux_open(void);
/* console.c */
void qemu_chr_parse_vc(QemuOpts *opts, ChardevBackend *backend, Error **errp);

View File

@ -105,4 +105,7 @@ int ram_block_discard_range(RAMBlock *rb, uint64_t start, size_t length);
#endif
/* vl.c */
extern int singlestep;
#endif /* CPU_COMMON_H */

View File

@ -676,7 +676,4 @@ hwaddr memory_region_section_get_iotlb(CPUState *cpu,
MemoryRegionSection *section);
#endif
/* vl.c */
extern int singlestep;
#endif

View File

@ -3,7 +3,6 @@
#ifndef HW_POISON_H
#define HW_POISON_H
#ifdef __GNUC__
#pragma GCC poison TARGET_I386
#pragma GCC poison TARGET_X86_64
@ -93,4 +92,3 @@
#pragma GCC poison CONFIG_SOFTMMU
#endif
#endif

View File

@ -780,12 +780,12 @@ const VMStateDescription *qdev_get_vmsd(DeviceState *dev);
const char *qdev_fw_name(DeviceState *dev);
void qdev_assert_realized_properly(void);
Object *qdev_get_machine(void);
/* FIXME: make this a link<> */
bool qdev_set_parent_bus(DeviceState *dev, BusState *bus, Error **errp);
extern bool qdev_hotplug;
extern bool qdev_hot_removed;
char *qdev_get_dev_path(DeviceState *dev);
@ -811,4 +811,35 @@ void device_listener_unregister(DeviceListener *listener);
*/
bool qdev_should_hide_device(QemuOpts *opts);
typedef enum MachineInitPhase {
/* current_machine is NULL. */
PHASE_NO_MACHINE,
/* current_machine is not NULL, but current_machine->accel is NULL. */
PHASE_MACHINE_CREATED,
/*
* current_machine->accel is not NULL, but the machine properties have
* not been validated and machine_class->init has not yet been called.
*/
PHASE_ACCEL_CREATED,
/*
* machine_class->init has been called, thus creating any embedded
* devices and validating machine properties. Devices created at
* this time are considered to be cold-plugged.
*/
PHASE_MACHINE_INITIALIZED,
/*
* QEMU is ready to start CPUs and devices created at this time
* are considered to be hot-plugged. The monitor is not restricted
* to "preconfig" commands.
*/
PHASE_MACHINE_READY,
} MachineInitPhase;
extern bool phase_check(MachineInitPhase phase);
extern void phase_advance(MachineInitPhase phase);
#endif

View File

@ -206,21 +206,12 @@ typedef struct __name##_back_ring __name##_back_ring_t
#define RING_HAS_UNCONSUMED_RESPONSES(_r) \
((_r)->sring->rsp_prod - (_r)->rsp_cons)
#ifdef __GNUC__
#define RING_HAS_UNCONSUMED_REQUESTS(_r) ({ \
unsigned int req = (_r)->sring->req_prod - (_r)->req_cons; \
unsigned int rsp = RING_SIZE(_r) - \
((_r)->req_cons - (_r)->rsp_prod_pvt); \
req < rsp ? req : rsp; \
})
#else
/* Same as above, but without the nice GCC ({ ... }) syntax. */
#define RING_HAS_UNCONSUMED_REQUESTS(_r) \
((((_r)->sring->req_prod - (_r)->req_cons) < \
(RING_SIZE(_r) - ((_r)->req_cons - (_r)->rsp_prod_pvt))) ? \
((_r)->sring->req_prod - (_r)->req_cons) : \
(RING_SIZE(_r) - ((_r)->req_cons - (_r)->rsp_prod_pvt)))
#endif
/* Direct access to individual ring elements, by index. */
#define RING_GET_REQUEST(_r, _idx) \

View File

@ -48,6 +48,7 @@ void qmp_disable_command(QmpCommandList *cmds, const char *name);
void qmp_enable_command(QmpCommandList *cmds, const char *name);
bool qmp_command_is_enabled(const QmpCommand *cmd);
bool qmp_command_available(const QmpCommand *cmd, Error **errp);
const char *qmp_command_name(const QmpCommand *cmd);
bool qmp_has_success_response(const QmpCommand *cmd);
QDict *qmp_error_response(Error *err);

View File

@ -241,23 +241,6 @@
#else /* __ATOMIC_RELAXED */
/*
* We use GCC builtin if it's available, as that can use mfence on
* 32-bit as well, e.g. if built with -march=pentium-m. However, on
* i386 the spec is buggy, and the implementation followed it until
* 4.3 (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36793).
*/
#if defined(__i386__) || defined(__x86_64__)
#if !QEMU_GNUC_PREREQ(4, 4)
#if defined __x86_64__
#define smp_mb() ({ asm volatile("mfence" ::: "memory"); (void)0; })
#else
#define smp_mb() ({ asm volatile("lock; addl $0,0(%%esp) " ::: "memory"); (void)0; })
#endif
#endif
#endif
#ifdef __alpha__
#define smp_read_barrier_depends() asm volatile("mb":::"memory")
#endif

View File

@ -11,17 +11,6 @@
#define QEMU_STATIC_ANALYSIS 1
#endif
/*----------------------------------------------------------------------------
| The macro QEMU_GNUC_PREREQ tests for minimum version of the GNU C compiler.
| The code is a copy of SOFTFLOAT_GNUC_PREREQ, see softfloat-macros.h.
*----------------------------------------------------------------------------*/
#if defined(__GNUC__) && defined(__GNUC_MINOR__)
# define QEMU_GNUC_PREREQ(maj, min) \
((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
#else
# define QEMU_GNUC_PREREQ(maj, min) 0
#endif
#define QEMU_NORETURN __attribute__ ((__noreturn__))
#define QEMU_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
@ -44,10 +33,6 @@
#endif
#ifndef likely
#if __GNUC__ < 3
#define __builtin_expect(x, n) (x)
#endif
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
#endif
@ -68,14 +53,10 @@
(offsetof(container, field) + sizeof_field(container, field))
/* Convert from a base type to a parent type, with compile time checking. */
#ifdef __GNUC__
#define DO_UPCAST(type, field, dev) ( __extension__ ( { \
char __attribute__((unused)) offset_must_be_zero[ \
-offsetof(type, field)]; \
container_of(dev, type, field);}))
#else
#define DO_UPCAST(type, field, dev) container_of(dev, type, field)
#endif
#define typeof_field(type, field) typeof(((type *)0)->field)
#define type_check(t1,t2) ((t1*)0 - (t2*)0)
@ -103,21 +84,19 @@
#define QEMU_BUILD_BUG_ON_ZERO(x) (sizeof(QEMU_BUILD_BUG_ON_STRUCT(x)) - \
sizeof(QEMU_BUILD_BUG_ON_STRUCT(x)))
#if defined __GNUC__
# if !QEMU_GNUC_PREREQ(4, 4)
/* gcc versions before 4.4.x don't support gnu_printf, so use printf. */
# define GCC_FMT_ATTR(n, m) __attribute__((format(printf, n, m)))
# else
/* Use gnu_printf when supported (qemu uses standard format strings). */
# define GCC_FMT_ATTR(n, m) __attribute__((format(gnu_printf, n, m)))
# if defined(_WIN32)
/* Map __printf__ to __gnu_printf__ because we want standard format strings
* even when MinGW or GLib include files use __printf__. */
# define __printf__ __gnu_printf__
# endif
# endif
#if defined(__clang__)
/* clang doesn't support gnu_printf, so use printf. */
# define GCC_FMT_ATTR(n, m) __attribute__((format(printf, n, m)))
#else
#define GCC_FMT_ATTR(n, m)
/* Use gnu_printf (qemu uses standard format strings). */
# define GCC_FMT_ATTR(n, m) __attribute__((format(gnu_printf, n, m)))
# if defined(_WIN32)
/*
* Map __printf__ to __gnu_printf__ because we want standard format strings even
* when MinGW or GLib include files use __printf__.
*/
# define __printf__ __gnu_printf__
# endif
#endif
#ifndef __has_warning

View File

@ -45,7 +45,7 @@ static inline void qemu_plugin_add_opts(void)
}
void qemu_plugin_opt_parse(const char *optarg, QemuPluginList *head);
int qemu_plugin_load_list(QemuPluginList *head);
int qemu_plugin_load_list(QemuPluginList *head, Error **errp);
union qemu_plugin_cb_sig {
qemu_plugin_simple_cb_t simple;
@ -199,7 +199,7 @@ static inline void qemu_plugin_opt_parse(const char *optarg,
exit(1);
}
static inline int qemu_plugin_load_list(QemuPluginList *head)
static inline int qemu_plugin_load_list(QemuPluginList *head, Error **errp)
{
return 0;
}

View File

@ -28,13 +28,8 @@
#endif
#define QEMU_PLUGIN_LOCAL
#else
#if __GNUC__ >= 4
#define QEMU_PLUGIN_EXPORT __attribute__((visibility("default")))
#define QEMU_PLUGIN_LOCAL __attribute__((visibility("hidden")))
#else
#define QEMU_PLUGIN_EXPORT
#define QEMU_PLUGIN_LOCAL
#endif
#define QEMU_PLUGIN_EXPORT __attribute__((visibility("default")))
#define QEMU_PLUGIN_LOCAL __attribute__((visibility("hidden")))
#endif
typedef uint64_t qemu_plugin_id_t;

View File

@ -0,0 +1,19 @@
/*
* Copyright (c) 2020 Oracle and/or its affiliates.
*
* This work is licensed under the terms of the GNU GPL, version 2.
* See the COPYING file in the top-level directory.
*
*/
#ifndef RUNSTATE_ACTION_H
#define RUNSTATE_ACTION_H
#include "qapi/qapi-commands-run-state.h"
/* in softmmu/runstate-action.c */
extern RebootAction reboot_action;
extern ShutdownAction shutdown_action;
extern PanicAction panic_action;
#endif /* RUNSTATE_ACTION_H */

View File

@ -41,7 +41,6 @@ typedef enum WakeupReason {
QEMU_WAKEUP_REASON_OTHER,
} WakeupReason;
void qemu_exit_preconfig_request(void);
void qemu_system_reset_request(ShutdownCause reason);
void qemu_system_suspend_request(void);
void qemu_register_suspend_notifier(Notifier *notifier);

View File

@ -16,14 +16,14 @@ extern bool qemu_uuid_set;
void qemu_add_exit_notifier(Notifier *notify);
void qemu_remove_exit_notifier(Notifier *notify);
extern bool machine_init_done;
void qemu_run_machine_init_done_notifiers(void);
void qemu_add_machine_init_done_notifier(Notifier *notify);
void qemu_remove_machine_init_done_notifier(Notifier *notify);
void configure_rtc(QemuOpts *opts);
void qemu_init_subsystems(void);
extern int autostart;
typedef enum {
@ -43,7 +43,6 @@ extern int win2k_install_hack;
extern int alt_grab;
extern int ctrl_grab;
extern int graphic_rotate;
extern int no_shutdown;
extern int old_param;
extern int boot_menu;
extern bool boot_strict;
@ -103,8 +102,6 @@ typedef void QEMUBootSetHandler(void *opaque, const char *boot_order,
void qemu_register_boot_set(QEMUBootSetHandler *func, void *opaque);
void qemu_boot_set(const char *boot_order, Error **errp);
QemuOpts *qemu_get_machine_opts(void);
bool defaults_enabled(void);
void qemu_init(int argc, char **argv, char **envp);

View File

@ -671,9 +671,7 @@ int main(int argc, char **argv, char **envp)
exit(1);
}
trace_init_file();
if (qemu_plugin_load_list(&plugins)) {
exit(1);
}
qemu_plugin_load_list(&plugins, &error_fatal);
/* Zero out regs */
memset(regs, 0, sizeof(struct target_pt_regs));

View File

@ -24,7 +24,6 @@ struct syscallname {
abi_long, abi_long, abi_long);
};
#ifdef __GNUC__
/*
* It is possible that target doesn't have syscall that uses
* following flags but we don't want the compiler to warn
@ -32,9 +31,6 @@ struct syscallname {
* functions. It is ok to keep them while not used.
*/
#define UNUSED __attribute__ ((unused))
#else
#define UNUSED
#endif
/*
* Structure used to translate flag values into strings. This is

View File

@ -24,6 +24,7 @@
#include "qemu/osdep.h"
#include <dirent.h>
#include "hw/qdev-core.h"
#include "monitor-internal.h"
#include "qapi/error.h"
#include "qapi/qmp/qdict.h"
@ -215,7 +216,7 @@ static bool cmd_can_preconfig(const HMPCommand *cmd)
static bool cmd_available(const HMPCommand *cmd)
{
return !runstate_check(RUN_STATE_PRECONFIG) || cmd_can_preconfig(cmd);
return phase_check(PHASE_MACHINE_READY) || cmd_can_preconfig(cmd);
}
static void help_cmd_dump_one(Monitor *mon,
@ -658,8 +659,8 @@ static const HMPCommand *monitor_parse_command(MonitorHMP *hmp_mon,
return NULL;
}
if (!cmd_available(cmd)) {
monitor_printf(mon, "Command '%.*s' not available with -preconfig "
"until after exit_preconfig.\n",
monitor_printf(mon, "Command '%.*s' not available "
"until machine initialization has completed.\n",
(int)(p - cmdp_start), cmdp_start);
return NULL;
}

View File

@ -26,6 +26,7 @@
#include "ui/vnc.h"
#include "sysemu/kvm.h"
#include "sysemu/runstate.h"
#include "sysemu/runstate-action.h"
#include "sysemu/arch_init.h"
#include "sysemu/blockdev.h"
#include "sysemu/block-backend.h"
@ -72,7 +73,7 @@ UuidInfo *qmp_query_uuid(Error **errp)
void qmp_quit(Error **errp)
{
no_shutdown = 0;
shutdown_action = SHUTDOWN_ACTION_POWEROFF;
qemu_system_shutdown_request(SHUTDOWN_CAUSE_HOST_QMP_QUIT);
}
@ -102,16 +103,6 @@ void qmp_system_powerdown(Error **errp)
qemu_system_powerdown_request();
}
void qmp_x_exit_preconfig(Error **errp)
{
if (!runstate_check(RUN_STATE_PRECONFIG)) {
error_setg(errp, "The command is permitted only in '%s' state",
RunState_str(RUN_STATE_PRECONFIG));
return;
}
qemu_exit_preconfig_request();
}
void qmp_cont(Error **errp)
{
BlockBackend *blk;

View File

@ -41,7 +41,6 @@ override CFLAGS += $(call cc-option, $(Wa)-32)
LD_I386_EMULATION ?= elf_i386
override LDFLAGS = -m $(LD_I386_EMULATION) -T $(SRC_DIR)/flat.lds
override LDFLAGS += $(LDFLAGS_NOPIE)
all: multiboot.bin linuxboot.bin linuxboot_dma.bin kvmvapic.bin pvh.bin

View File

@ -150,7 +150,7 @@ static uint64_t xorshift64star(uint64_t x)
return x * UINT64_C(2685821657736338717);
}
static int plugin_load(struct qemu_plugin_desc *desc, const qemu_info_t *info)
static int plugin_load(struct qemu_plugin_desc *desc, const qemu_info_t *info, Error **errp)
{
qemu_plugin_install_func_t install;
struct qemu_plugin_ctx *ctx;
@ -163,37 +163,37 @@ static int plugin_load(struct qemu_plugin_desc *desc, const qemu_info_t *info)
ctx->handle = g_module_open(desc->path, G_MODULE_BIND_LOCAL);
if (ctx->handle == NULL) {
error_report("%s: %s", __func__, g_module_error());
error_setg(errp, "Could not load plugin %s: %s", desc->path, g_module_error());
goto err_dlopen;
}
if (!g_module_symbol(ctx->handle, "qemu_plugin_install", &sym)) {
error_report("%s: %s", __func__, g_module_error());
error_setg(errp, "Could not load plugin %s: %s", desc->path, g_module_error());
goto err_symbol;
}
install = (qemu_plugin_install_func_t) sym;
/* symbol was found; it could be NULL though */
if (install == NULL) {
error_report("%s: %s: qemu_plugin_install is NULL",
__func__, desc->path);
error_setg(errp, "Could not load plugin %s: qemu_plugin_install is NULL",
desc->path);
goto err_symbol;
}
if (!g_module_symbol(ctx->handle, "qemu_plugin_version", &sym)) {
error_report("TCG plugin %s does not declare API version %s",
desc->path, g_module_error());
error_setg(errp, "Could not load plugin %s: plugin does not declare API version %s",
desc->path, g_module_error());
goto err_symbol;
} else {
int version = *(int *)sym;
if (version < QEMU_PLUGIN_MIN_VERSION) {
error_report("TCG plugin %s requires API version %d, but "
"this QEMU supports only a minimum version of %d",
desc->path, version, QEMU_PLUGIN_MIN_VERSION);
error_setg(errp, "Could not load plugin %s: plugin requires API version %d, but "
"this QEMU supports only a minimum version of %d",
desc->path, version, QEMU_PLUGIN_MIN_VERSION);
goto err_symbol;
} else if (version > QEMU_PLUGIN_VERSION) {
error_report("TCG plugin %s requires API version %d, but "
"this QEMU supports only up to version %d",
desc->path, version, QEMU_PLUGIN_VERSION);
error_setg(errp, "Could not load plugin %s: plugin requires API version %d, but "
"this QEMU supports only up to version %d",
desc->path, version, QEMU_PLUGIN_VERSION);
goto err_symbol;
}
}
@ -220,8 +220,8 @@ static int plugin_load(struct qemu_plugin_desc *desc, const qemu_info_t *info)
rc = install(ctx->id, info, desc->argc, desc->argv);
ctx->installing = false;
if (rc) {
error_report("%s: qemu_plugin_install returned error code %d",
__func__, rc);
error_setg(errp, "Could not load plugin %s: qemu_plugin_install returned error code %d",
desc->path, rc);
/*
* we cannot rely on the plugin doing its own cleanup, so
* call a full uninstall if the plugin did not yet call it.
@ -263,7 +263,7 @@ static void plugin_desc_free(struct qemu_plugin_desc *desc)
* Note: the descriptor of each successfully installed plugin is removed
* from the list given by @head.
*/
int qemu_plugin_load_list(QemuPluginList *head)
int qemu_plugin_load_list(QemuPluginList *head, Error **errp)
{
struct qemu_plugin_desc *desc, *next;
g_autofree qemu_info_t *info = g_new0(qemu_info_t, 1);
@ -283,7 +283,7 @@ int qemu_plugin_load_list(QemuPluginList *head)
QTAILQ_FOREACH_SAFE(desc, head, entry, next) {
int err;
err = plugin_load(desc, info);
err = plugin_load(desc, info, errp);
if (err) {
return err;
}

View File

@ -219,7 +219,8 @@
# -> { "execute": "quit" }
# <- { "return": {} }
##
{ 'command': 'quit' }
{ 'command': 'quit',
'allow-preconfig': true }
##
# @MonitorMode:

View File

@ -167,10 +167,7 @@ QDict *qmp_dispatch(const QmpCommandList *cmds, QObject *request,
goto out;
}
if (runstate_check(RUN_STATE_PRECONFIG) &&
!(cmd->options & QCO_ALLOW_PRECONFIG)) {
error_setg(&err, "The command '%s' isn't permitted in '%s' state",
cmd->name, RunState_str(RUN_STATE_PRECONFIG));
if (!qmp_command_available(cmd, &err)) {
goto out;
}

View File

@ -50,15 +50,12 @@
# @colo: guest is paused to save/restore VM state under colo checkpoint,
# VM can not get into this state unless colo capability is enabled
# for migration. (since 2.8)
# @preconfig: QEMU is paused before board specific init callback is executed.
# The state is reachable only if the --preconfig CLI option is used.
# (Since 3.0)
##
{ 'enum': 'RunState',
'data': [ 'debug', 'inmigrate', 'internal-error', 'io-error', 'paused',
'postmigrate', 'prelaunch', 'finish-migrate', 'restore-vm',
'running', 'save-vm', 'shutdown', 'suspended', 'watchdog',
'guest-panicked', 'colo', 'preconfig' ] }
'guest-panicked', 'colo' ] }
##
# @ShutdownCause:
@ -328,6 +325,46 @@
'data': [ 'reset', 'shutdown', 'poweroff', 'pause', 'debug', 'none',
'inject-nmi' ] }
##
# @RebootAction:
#
# Possible QEMU actions upon guest reboot
#
# @none: Reset the VM
#
# @shutdown: Shutdown the VM and exit
#
# Since: 6.0
##
{ 'enum': 'RebootAction',
'data': [ 'none', 'shutdown' ] }
##
# @ShutdownAction:
#
# Possible QEMU actions upon guest shutdown
#
# @poweroff: Shutdown the VM and exit
#
# @pause: pause the VM#
#
# Since: 6.0
##
{ 'enum': 'ShutdownAction',
'data': [ 'poweroff', 'pause' ] }
##
# @PanicAction:
#
# @none: Continue VM execution
#
# @pause: Pause the VM
#
# Since: 6.0
##
{ 'enum': 'PanicAction',
'data': [ 'poweroff', 'pause', 'none' ] }
##
# @watchdog-set-action:
#
@ -337,6 +374,40 @@
##
{ 'command': 'watchdog-set-action', 'data' : {'action': 'WatchdogAction'} }
##
# @set-action:
#
# Set the actions that will be taken by the emulator in response to guest
# events.
#
# @reboot: @RebootAction action taken on guest reboot.
#
# @shutdown: @ShutdownAction action taken on guest shutdown.
#
# @panic: @PanicAction action taken on guest panic.
#
# @watchdog: @WatchdogAction action taken when watchdog timer expires .
#
# Returns: Nothing on success.
#
# Since: 6.0
#
# Example:
#
# -> { "execute": "set-action",
# "arguments": { "reboot": "shutdown",
# "shutdown" : "pause",
# "panic": "pause",
# "watchdog": "inject-nmi" } }
# <- { "return": {} }
##
{ 'command': 'set-action',
'data': { '*reboot': 'RebootAction',
'*shutdown': 'ShutdownAction',
'*panic': 'PanicAction',
'*watchdog': 'WatchdogAction' },
'allow-preconfig': true }
##
# @GUEST_PANICKED:
#

View File

@ -3713,17 +3713,6 @@ SRST
Do not start CPU at startup (you must type 'c' in the monitor).
ERST
DEF("realtime", HAS_ARG, QEMU_OPTION_realtime,
"-realtime [mlock=on|off]\n"
" run qemu with realtime features\n"
" mlock=on|off controls mlock support (default: on)\n",
QEMU_ARCH_ALL)
SRST
``-realtime mlock=on|off``
Run qemu with realtime features. mlocking qemu and guest memory can
be enabled via ``mlock=on`` (enabled by default).
ERST
DEF("overcommit", HAS_ARG, QEMU_OPTION_overcommit,
"-overcommit [mem-lock=on|off][cpu-pm=on|off]\n"
" run qemu with overcommit hints\n"
@ -3739,8 +3728,7 @@ SRST
Locking qemu and guest memory can be enabled via ``mem-lock=on``
(disabled by default). This works when host memory is not
overcommitted and reduces the worst-case latency for guest. This is
equivalent to ``realtime``.
overcommitted and reduces the worst-case latency for guest.
Guest ability to manage power state of host cpus (increasing latency
for other processes on the same host cpu, but decreasing latency for
@ -3894,6 +3882,31 @@ SRST
changes to the disk image.
ERST
DEF("action", HAS_ARG, QEMU_OPTION_action,
"-action reboot=none|shutdown\n"
" action when guest reboots [default=none]\n"
"-action shutdown=poweroff|pause\n"
" action when guest shuts down [default=poweroff]\n"
"-action panic=poweroff|pause|none\n"
" action when guest panics [default=poweroff]\n"
"-action watchdog=reset|shutdown|poweroff|inject-nmi|pause|debug|none\n"
" action when watchdog fires [default=reset]\n",
QEMU_ARCH_ALL)
SRST
``-action event=action``
The action parameter serves to modify QEMU's default behavior when
certain guest events occur. It provides a generic method for specifying the
same behaviors that are modified by the ``-no-reboot`` and ``-no-shutdown``
parameters.
Examples:
``-action panic=none``
``-action reboot=shutdown,shutdown=pause``
``-watchdog i6300esb -action watchdog=pause``
ERST
DEF("loadvm", HAS_ARG, QEMU_OPTION_loadvm, \
"-loadvm [tag|id]\n" \
" start right away with a saved state (loadvm in monitor)\n",
@ -4079,21 +4092,6 @@ SRST
ERST
DEF("show-cursor", 0, QEMU_OPTION_show_cursor, \
"-show-cursor show cursor\n", QEMU_ARCH_ALL)
SRST
``-show-cursor``
Show cursor.
ERST
DEF("tb-size", HAS_ARG, QEMU_OPTION_tb_size, \
"-tb-size n set TB size\n", QEMU_ARCH_ALL)
SRST
``-tb-size n``
Set TCG translation block cache size. Deprecated, use
'\ ``-accel tcg,tb-size=n``\ ' instead.
ERST
DEF("incoming", HAS_ARG, QEMU_OPTION_incoming, \
"-incoming tcp:[host]:port[,to=maxport][,ipv4][,ipv6]\n" \
"-incoming rdma:host:port[,ipv4][,ipv6]\n" \

View File

@ -19,7 +19,6 @@
*/
/* From qemu/compiler.h */
#define QEMU_GNUC_PREREQ(maj, min) 1
#define QEMU_NORETURN __attribute__ ((__noreturn__))
#define QEMU_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
#define QEMU_SENTINEL __attribute__((sentinel))

View File

@ -12,6 +12,7 @@
# Documentation
docs/*
*.rst
*.rst.inc
# build system
configure
@ -28,9 +29,11 @@ qga/*.json
# headers
*.h
*.h.inc
# decoding tree specification
*.decode
# code
*.c
*.c.inc

View File

@ -526,7 +526,7 @@ int qemu_fdt_add_subnode(void *fdt, const char *name)
void qemu_fdt_dumpdtb(void *fdt, int size)
{
const char *dumpdtb = qemu_opt_get(qemu_get_machine_opts(), "dumpdtb");
const char *dumpdtb = current_machine->dumpdtb;
if (dumpdtb) {
/* Dump the dtb to a file and quit */

72
softmmu/globals.c Normal file
View File

@ -0,0 +1,72 @@
/*
* Global variables that (mostly) should not exist
*
* Copyright (c) 2003-2020 QEMU contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "qemu/osdep.h"
#include "exec/cpu-common.h"
#include "hw/display/vga.h"
#include "hw/i386/pc.h"
#include "hw/i386/x86.h"
#include "hw/loader.h"
#include "hw/xen/xen.h"
#include "net/net.h"
#include "sysemu/cpus.h"
#include "sysemu/sysemu.h"
enum vga_retrace_method vga_retrace_method = VGA_RETRACE_DUMB;
int display_opengl;
const char* keyboard_layout;
bool enable_mlock;
bool enable_cpu_pm;
int nb_nics;
NICInfo nd_table[MAX_NICS];
int autostart = 1;
int vga_interface_type = VGA_NONE;
Chardev *parallel_hds[MAX_PARALLEL_PORTS];
int win2k_install_hack;
int singlestep;
int fd_bootchk = 1;
int graphic_rotate;
QEMUOptionRom option_rom[MAX_OPTION_ROMS];
int nb_option_roms;
int old_param;
const char *qemu_name;
int alt_grab;
int ctrl_grab;
unsigned int nb_prom_envs;
const char *prom_envs[MAX_PROM_ENVS];
int boot_menu;
bool boot_strict;
uint8_t *boot_splash_filedata;
int only_migratable; /* turn it off unless user states otherwise */
int icount_align_option;
/* The bytes in qemu_uuid are in the order specified by RFC4122, _not_ in the
* little-endian "wire format" described in the SMBIOS 2.6 specification.
*/
QemuUUID qemu_uuid;
bool qemu_uuid_set;
uint32_t xen_domid;
enum xen_mode xen_mode = XEN_EMULATE;
bool xen_domid_restrict;

View File

@ -1548,7 +1548,6 @@ void memory_region_init_ram_shared_nomigrate(MemoryRegion *mr,
mr->terminates = true;
mr->destructor = memory_region_destructor_ram;
mr->ram_block = qemu_ram_alloc(size, share, mr, &err);
mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0;
if (err) {
mr->size = int128_zero();
object_unparent(OBJECT(mr));
@ -1573,7 +1572,6 @@ void memory_region_init_resizeable_ram(MemoryRegion *mr,
mr->destructor = memory_region_destructor_ram;
mr->ram_block = qemu_ram_alloc_resizeable(size, max_size, resized,
mr, &err);
mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0;
if (err) {
mr->size = int128_zero();
object_unparent(OBJECT(mr));
@ -1598,7 +1596,6 @@ void memory_region_init_ram_from_file(MemoryRegion *mr,
mr->destructor = memory_region_destructor_ram;
mr->align = align;
mr->ram_block = qemu_ram_alloc_from_file(size, mr, ram_flags, path, &err);
mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0;
if (err) {
mr->size = int128_zero();
object_unparent(OBJECT(mr));
@ -1622,7 +1619,6 @@ void memory_region_init_ram_from_fd(MemoryRegion *mr,
mr->ram_block = qemu_ram_alloc_from_fd(size, mr,
share ? RAM_SHARED : 0,
fd, &err);
mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0;
if (err) {
mr->size = int128_zero();
object_unparent(OBJECT(mr));
@ -1641,7 +1637,6 @@ void memory_region_init_ram_ptr(MemoryRegion *mr,
mr->ram = true;
mr->terminates = true;
mr->destructor = memory_region_destructor_ram;
mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0;
/* qemu_ram_alloc_from_ptr cannot fail with ptr != NULL. */
assert(ptr != NULL);
@ -1661,7 +1656,7 @@ void memory_region_init_ram_device_ptr(MemoryRegion *mr,
mr->ops = &ram_device_mem_ops;
mr->opaque = mr;
mr->destructor = memory_region_destructor_ram;
mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0;
/* qemu_ram_alloc_from_ptr cannot fail with ptr != NULL. */
assert(ptr != NULL);
mr->ram_block = qemu_ram_alloc_from_ptr(size, ptr, mr, &error_fatal);
@ -1819,6 +1814,11 @@ uint8_t memory_region_get_dirty_log_mask(MemoryRegion *mr)
memory_region_is_iommu(mr))) {
mask |= (1 << DIRTY_MEMORY_MIGRATION);
}
if (tcg_enabled() && rb) {
/* TCG only cares about dirty memory logging for RAM, not IOMMU. */
mask |= (1 << DIRTY_MEMORY_CODE);
}
return mask;
}

View File

@ -4,14 +4,17 @@ specific_ss.add(when: 'CONFIG_SOFTMMU', if_true: [files(
'cpus.c',
'cpu-throttle.c',
'datadir.c',
'globals.c',
'physmem.c',
'ioport.c',
'rtc.c',
'runstate.c',
'memory.c',
'memory_mapping.c',
'qtest.c',
'vl.c',
'cpu-timers.c',
'runstate-action.c',
)])
specific_ss.add(when: ['CONFIG_SOFTMMU', 'CONFIG_TCG'], if_true: [files(

View File

@ -3255,6 +3255,7 @@ int64_t address_space_cache_init(MemoryRegionCache *cache,
AddressSpaceDispatch *d;
hwaddr l;
MemoryRegion *mr;
Int128 diff;
assert(len > 0);
@ -3263,6 +3264,15 @@ int64_t address_space_cache_init(MemoryRegionCache *cache,
d = flatview_to_dispatch(cache->fv);
cache->mrs = *address_space_translate_internal(d, addr, &cache->xlat, &l, true);
/*
* cache->xlat is now relative to cache->mrs.mr, not to the section itself.
* Take that into account to compute how many bytes are there between
* cache->xlat and the end of the section.
*/
diff = int128_sub(cache->mrs.size,
int128_make64(cache->xlat - cache->mrs.offset_within_region));
l = int128_get64(int128_min(diff, int128_make64(l)));
mr = cache->mrs.mr;
memory_region_ref(mr);
if (memory_access_is_direct(mr, is_write)) {

View File

@ -25,6 +25,7 @@
#include "sysemu/arch_init.h"
#include "qapi/error.h"
#include "qapi/qapi-commands-qdev.h"
#include "qapi/qmp/dispatch.h"
#include "qapi/qmp/qdict.h"
#include "qapi/qmp/qerror.h"
#include "qemu/config-file.h"
@ -244,7 +245,7 @@ static DeviceClass *qdev_get_device_class(const char **driver, Error **errp)
dc = DEVICE_CLASS(oc);
if (!dc->user_creatable ||
(qdev_hotplug && !dc->hotpluggable)) {
(phase_check(PHASE_MACHINE_READY) && !dc->hotpluggable)) {
error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "driver",
"a pluggable device type");
return NULL;
@ -626,7 +627,7 @@ DeviceState *qdev_device_add(QemuOpts *opts, Error **errp)
}
}
if (qdev_hotplug && bus && !qbus_is_hotpluggable(bus)) {
if (phase_check(PHASE_MACHINE_READY) && bus && !qbus_is_hotpluggable(bus)) {
error_setg(errp, QERR_BUS_NO_HOTPLUG, bus->name);
return NULL;
}
@ -640,15 +641,17 @@ DeviceState *qdev_device_add(QemuOpts *opts, Error **errp)
dev = qdev_new(driver);
/* Check whether the hotplug is allowed by the machine */
if (qdev_hotplug && !qdev_hotplug_allowed(dev, errp)) {
goto err_del_dev;
}
if (phase_check(PHASE_MACHINE_READY)) {
if (!qdev_hotplug_allowed(dev, errp)) {
goto err_del_dev;
}
if (!bus && qdev_hotplug && !qdev_get_machine_hotplug_handler(dev)) {
/* No bus, no machine hotplug handler --> device is not hotpluggable */
error_setg(errp, "Device '%s' can not be hotplugged on this machine",
driver);
goto err_del_dev;
if (!bus && !qdev_get_machine_hotplug_handler(dev)) {
/* No bus, no machine hotplug handler --> device is not hotpluggable */
error_setg(errp, "Device '%s' can not be hotplugged on this machine",
driver);
goto err_del_dev;
}
}
qdev_set_id(dev, qemu_opts_id(opts));
@ -983,3 +986,14 @@ int qemu_global_option(const char *str)
return 0;
}
bool qmp_command_available(const QmpCommand *cmd, Error **errp)
{
if (!phase_check(PHASE_MACHINE_READY) &&
!(cmd->options & QCO_ALLOW_PRECONFIG)) {
error_setg(errp, "The command '%s' is permitted only after machine initialization has completed",
cmd->name);
return false;
}
return true;
}

46
softmmu/runstate-action.c Normal file
View File

@ -0,0 +1,46 @@
/*
* Copyright (c) 2020 Oracle and/or its affiliates.
*
* This work is licensed under the terms of the GNU GPL, version 2.
* See the COPYING file in the top-level directory.
*
*/
#include "qemu/osdep.h"
#include "sysemu/runstate-action.h"
#include "sysemu/watchdog.h"
#include "qemu/config-file.h"
#include "qapi/error.h"
#include "qemu/option_int.h"
RebootAction reboot_action = REBOOT_ACTION_NONE;
ShutdownAction shutdown_action = SHUTDOWN_ACTION_POWEROFF;
PanicAction panic_action = PANIC_ACTION_POWEROFF;
/*
* Receives actions to be applied for specific guest events
* and sets the internal state as requested.
*/
void qmp_set_action(bool has_reboot, RebootAction reboot,
bool has_shutdown, ShutdownAction shutdown,
bool has_panic, PanicAction panic,
bool has_watchdog, WatchdogAction watchdog,
Error **errp)
{
if (has_reboot) {
reboot_action = reboot;
}
if (has_panic) {
panic_action = panic;
}
if (has_watchdog) {
qmp_watchdog_set_action(watchdog, errp);
}
/* Process shutdown last, in case the panic action needs to be altered */
if (has_shutdown) {
shutdown_action = shutdown;
}
}

812
softmmu/runstate.c Normal file
View File

@ -0,0 +1,812 @@
/*
* QEMU main system emulation loop
*
* Copyright (c) 2003-2020 QEMU contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "qemu/osdep.h"
#include "audio/audio.h"
#include "block/block.h"
#include "chardev/char.h"
#include "crypto/cipher.h"
#include "crypto/init.h"
#include "exec/cpu-common.h"
#include "exec/exec-all.h"
#include "exec/gdbstub.h"
#include "hw/boards.h"
#include "migration/misc.h"
#include "migration/postcopy-ram.h"
#include "monitor/monitor.h"
#include "net/net.h"
#include "net/vhost_net.h"
#include "qapi/error.h"
#include "qapi/qapi-commands-run-state.h"
#include "qapi/qapi-events-run-state.h"
#include "qemu-common.h"
#include "qemu/error-report.h"
#include "qemu/job.h"
#include "qemu/module.h"
#include "qemu/plugin.h"
#include "qemu/sockets.h"
#include "qemu/thread.h"
#include "qom/object.h"
#include "qom/object_interfaces.h"
#include "sysemu/cpus.h"
#include "sysemu/qtest.h"
#include "sysemu/replay.h"
#include "sysemu/reset.h"
#include "sysemu/runstate.h"
#include "sysemu/runstate-action.h"
#include "sysemu/sysemu.h"
#include "sysemu/tpm.h"
#include "trace.h"
static NotifierList exit_notifiers =
NOTIFIER_LIST_INITIALIZER(exit_notifiers);
static RunState current_run_state = RUN_STATE_PRELAUNCH;
/* We use RUN_STATE__MAX but any invalid value will do */
static RunState vmstop_requested = RUN_STATE__MAX;
static QemuMutex vmstop_lock;
typedef struct {
RunState from;
RunState to;
} RunStateTransition;
static const RunStateTransition runstate_transitions_def[] = {
{ RUN_STATE_PRELAUNCH, RUN_STATE_INMIGRATE },
{ RUN_STATE_DEBUG, RUN_STATE_RUNNING },
{ RUN_STATE_DEBUG, RUN_STATE_FINISH_MIGRATE },
{ RUN_STATE_DEBUG, RUN_STATE_PRELAUNCH },
{ RUN_STATE_INMIGRATE, RUN_STATE_INTERNAL_ERROR },
{ RUN_STATE_INMIGRATE, RUN_STATE_IO_ERROR },
{ RUN_STATE_INMIGRATE, RUN_STATE_PAUSED },
{ RUN_STATE_INMIGRATE, RUN_STATE_RUNNING },
{ RUN_STATE_INMIGRATE, RUN_STATE_SHUTDOWN },
{ RUN_STATE_INMIGRATE, RUN_STATE_SUSPENDED },
{ RUN_STATE_INMIGRATE, RUN_STATE_WATCHDOG },
{ RUN_STATE_INMIGRATE, RUN_STATE_GUEST_PANICKED },
{ RUN_STATE_INMIGRATE, RUN_STATE_FINISH_MIGRATE },
{ RUN_STATE_INMIGRATE, RUN_STATE_PRELAUNCH },
{ RUN_STATE_INMIGRATE, RUN_STATE_POSTMIGRATE },
{ RUN_STATE_INMIGRATE, RUN_STATE_COLO },
{ RUN_STATE_INTERNAL_ERROR, RUN_STATE_PAUSED },
{ RUN_STATE_INTERNAL_ERROR, RUN_STATE_FINISH_MIGRATE },
{ RUN_STATE_INTERNAL_ERROR, RUN_STATE_PRELAUNCH },
{ RUN_STATE_IO_ERROR, RUN_STATE_RUNNING },
{ RUN_STATE_IO_ERROR, RUN_STATE_FINISH_MIGRATE },
{ RUN_STATE_IO_ERROR, RUN_STATE_PRELAUNCH },
{ RUN_STATE_PAUSED, RUN_STATE_RUNNING },
{ RUN_STATE_PAUSED, RUN_STATE_FINISH_MIGRATE },
{ RUN_STATE_PAUSED, RUN_STATE_POSTMIGRATE },
{ RUN_STATE_PAUSED, RUN_STATE_PRELAUNCH },
{ RUN_STATE_PAUSED, RUN_STATE_COLO},
{ RUN_STATE_POSTMIGRATE, RUN_STATE_RUNNING },
{ RUN_STATE_POSTMIGRATE, RUN_STATE_FINISH_MIGRATE },
{ RUN_STATE_POSTMIGRATE, RUN_STATE_PRELAUNCH },
{ RUN_STATE_PRELAUNCH, RUN_STATE_RUNNING },
{ RUN_STATE_PRELAUNCH, RUN_STATE_FINISH_MIGRATE },
{ RUN_STATE_PRELAUNCH, RUN_STATE_INMIGRATE },
{ RUN_STATE_FINISH_MIGRATE, RUN_STATE_RUNNING },
{ RUN_STATE_FINISH_MIGRATE, RUN_STATE_PAUSED },
{ RUN_STATE_FINISH_MIGRATE, RUN_STATE_POSTMIGRATE },
{ RUN_STATE_FINISH_MIGRATE, RUN_STATE_PRELAUNCH },
{ RUN_STATE_FINISH_MIGRATE, RUN_STATE_COLO},
{ RUN_STATE_RESTORE_VM, RUN_STATE_RUNNING },
{ RUN_STATE_RESTORE_VM, RUN_STATE_PRELAUNCH },
{ RUN_STATE_COLO, RUN_STATE_RUNNING },
{ RUN_STATE_RUNNING, RUN_STATE_DEBUG },
{ RUN_STATE_RUNNING, RUN_STATE_INTERNAL_ERROR },
{ RUN_STATE_RUNNING, RUN_STATE_IO_ERROR },
{ RUN_STATE_RUNNING, RUN_STATE_PAUSED },
{ RUN_STATE_RUNNING, RUN_STATE_FINISH_MIGRATE },
{ RUN_STATE_RUNNING, RUN_STATE_RESTORE_VM },
{ RUN_STATE_RUNNING, RUN_STATE_SAVE_VM },
{ RUN_STATE_RUNNING, RUN_STATE_SHUTDOWN },
{ RUN_STATE_RUNNING, RUN_STATE_WATCHDOG },
{ RUN_STATE_RUNNING, RUN_STATE_GUEST_PANICKED },
{ RUN_STATE_RUNNING, RUN_STATE_COLO},
{ RUN_STATE_SAVE_VM, RUN_STATE_RUNNING },
{ RUN_STATE_SHUTDOWN, RUN_STATE_PAUSED },
{ RUN_STATE_SHUTDOWN, RUN_STATE_FINISH_MIGRATE },
{ RUN_STATE_SHUTDOWN, RUN_STATE_PRELAUNCH },
{ RUN_STATE_SHUTDOWN, RUN_STATE_COLO },
{ RUN_STATE_DEBUG, RUN_STATE_SUSPENDED },
{ RUN_STATE_RUNNING, RUN_STATE_SUSPENDED },
{ RUN_STATE_SUSPENDED, RUN_STATE_RUNNING },
{ RUN_STATE_SUSPENDED, RUN_STATE_FINISH_MIGRATE },
{ RUN_STATE_SUSPENDED, RUN_STATE_PRELAUNCH },
{ RUN_STATE_SUSPENDED, RUN_STATE_COLO},
{ RUN_STATE_WATCHDOG, RUN_STATE_RUNNING },
{ RUN_STATE_WATCHDOG, RUN_STATE_FINISH_MIGRATE },
{ RUN_STATE_WATCHDOG, RUN_STATE_PRELAUNCH },
{ RUN_STATE_WATCHDOG, RUN_STATE_COLO},
{ RUN_STATE_GUEST_PANICKED, RUN_STATE_RUNNING },
{ RUN_STATE_GUEST_PANICKED, RUN_STATE_FINISH_MIGRATE },
{ RUN_STATE_GUEST_PANICKED, RUN_STATE_PRELAUNCH },
{ RUN_STATE__MAX, RUN_STATE__MAX },
};
static bool runstate_valid_transitions[RUN_STATE__MAX][RUN_STATE__MAX];
bool runstate_check(RunState state)
{
return current_run_state == state;
}
bool runstate_store(char *str, size_t size)
{
const char *state = RunState_str(current_run_state);
size_t len = strlen(state) + 1;
if (len > size) {
return false;
}
memcpy(str, state, len);
return true;
}
static void runstate_init(void)
{
const RunStateTransition *p;
memset(&runstate_valid_transitions, 0, sizeof(runstate_valid_transitions));
for (p = &runstate_transitions_def[0]; p->from != RUN_STATE__MAX; p++) {
runstate_valid_transitions[p->from][p->to] = true;
}
qemu_mutex_init(&vmstop_lock);
}
/* This function will abort() on invalid state transitions */
void runstate_set(RunState new_state)
{
assert(new_state < RUN_STATE__MAX);
trace_runstate_set(current_run_state, RunState_str(current_run_state),
new_state, RunState_str(new_state));
if (current_run_state == new_state) {
return;
}
if (!runstate_valid_transitions[current_run_state][new_state]) {
error_report("invalid runstate transition: '%s' -> '%s'",
RunState_str(current_run_state),
RunState_str(new_state));
abort();
}
current_run_state = new_state;
}
int runstate_is_running(void)
{
return runstate_check(RUN_STATE_RUNNING);
}
bool runstate_needs_reset(void)
{
return runstate_check(RUN_STATE_INTERNAL_ERROR) ||
runstate_check(RUN_STATE_SHUTDOWN);
}
StatusInfo *qmp_query_status(Error **errp)
{
StatusInfo *info = g_malloc0(sizeof(*info));
info->running = runstate_is_running();
info->singlestep = singlestep;
info->status = current_run_state;
return info;
}
bool qemu_vmstop_requested(RunState *r)
{
qemu_mutex_lock(&vmstop_lock);
*r = vmstop_requested;
vmstop_requested = RUN_STATE__MAX;
qemu_mutex_unlock(&vmstop_lock);
return *r < RUN_STATE__MAX;
}
void qemu_system_vmstop_request_prepare(void)
{
qemu_mutex_lock(&vmstop_lock);
}
void qemu_system_vmstop_request(RunState state)
{
vmstop_requested = state;
qemu_mutex_unlock(&vmstop_lock);
qemu_notify_event();
}
struct VMChangeStateEntry {
VMChangeStateHandler *cb;
void *opaque;
QTAILQ_ENTRY(VMChangeStateEntry) entries;
int priority;
};
static QTAILQ_HEAD(, VMChangeStateEntry) vm_change_state_head =
QTAILQ_HEAD_INITIALIZER(vm_change_state_head);
/**
* qemu_add_vm_change_state_handler_prio:
* @cb: the callback to invoke
* @opaque: user data passed to the callback
* @priority: low priorities execute first when the vm runs and the reverse is
* true when the vm stops
*
* Register a callback function that is invoked when the vm starts or stops
* running.
*
* Returns: an entry to be freed using qemu_del_vm_change_state_handler()
*/
VMChangeStateEntry *qemu_add_vm_change_state_handler_prio(
VMChangeStateHandler *cb, void *opaque, int priority)
{
VMChangeStateEntry *e;
VMChangeStateEntry *other;
e = g_malloc0(sizeof(*e));
e->cb = cb;
e->opaque = opaque;
e->priority = priority;
/* Keep list sorted in ascending priority order */
QTAILQ_FOREACH(other, &vm_change_state_head, entries) {
if (priority < other->priority) {
QTAILQ_INSERT_BEFORE(other, e, entries);
return e;
}
}
QTAILQ_INSERT_TAIL(&vm_change_state_head, e, entries);
return e;
}
VMChangeStateEntry *qemu_add_vm_change_state_handler(VMChangeStateHandler *cb,
void *opaque)
{
return qemu_add_vm_change_state_handler_prio(cb, opaque, 0);
}
void qemu_del_vm_change_state_handler(VMChangeStateEntry *e)
{
QTAILQ_REMOVE(&vm_change_state_head, e, entries);
g_free(e);
}
void vm_state_notify(int running, RunState state)
{
VMChangeStateEntry *e, *next;
trace_vm_state_notify(running, state, RunState_str(state));
if (running) {
QTAILQ_FOREACH_SAFE(e, &vm_change_state_head, entries, next) {
e->cb(e->opaque, running, state);
}
} else {
QTAILQ_FOREACH_REVERSE_SAFE(e, &vm_change_state_head, entries, next) {
e->cb(e->opaque, running, state);
}
}
}
static ShutdownCause reset_requested;
static ShutdownCause shutdown_requested;
static int shutdown_signal;
static pid_t shutdown_pid;
static int powerdown_requested;
static int debug_requested;
static int suspend_requested;
static WakeupReason wakeup_reason;
static NotifierList powerdown_notifiers =
NOTIFIER_LIST_INITIALIZER(powerdown_notifiers);
static NotifierList suspend_notifiers =
NOTIFIER_LIST_INITIALIZER(suspend_notifiers);
static NotifierList wakeup_notifiers =
NOTIFIER_LIST_INITIALIZER(wakeup_notifiers);
static NotifierList shutdown_notifiers =
NOTIFIER_LIST_INITIALIZER(shutdown_notifiers);
static uint32_t wakeup_reason_mask = ~(1 << QEMU_WAKEUP_REASON_NONE);
ShutdownCause qemu_shutdown_requested_get(void)
{
return shutdown_requested;
}
ShutdownCause qemu_reset_requested_get(void)
{
return reset_requested;
}
static int qemu_shutdown_requested(void)
{
return qatomic_xchg(&shutdown_requested, SHUTDOWN_CAUSE_NONE);
}
static void qemu_kill_report(void)
{
if (!qtest_driver() && shutdown_signal) {
if (shutdown_pid == 0) {
/* This happens for eg ^C at the terminal, so it's worth
* avoiding printing an odd message in that case.
*/
error_report("terminating on signal %d", shutdown_signal);
} else {
char *shutdown_cmd = qemu_get_pid_name(shutdown_pid);
error_report("terminating on signal %d from pid " FMT_pid " (%s)",
shutdown_signal, shutdown_pid,
shutdown_cmd ? shutdown_cmd : "<unknown process>");
g_free(shutdown_cmd);
}
shutdown_signal = 0;
}
}
static ShutdownCause qemu_reset_requested(void)
{
ShutdownCause r = reset_requested;
if (r && replay_checkpoint(CHECKPOINT_RESET_REQUESTED)) {
reset_requested = SHUTDOWN_CAUSE_NONE;
return r;
}
return SHUTDOWN_CAUSE_NONE;
}
static int qemu_suspend_requested(void)
{
int r = suspend_requested;
if (r && replay_checkpoint(CHECKPOINT_SUSPEND_REQUESTED)) {
suspend_requested = 0;
return r;
}
return false;
}
static WakeupReason qemu_wakeup_requested(void)
{
return wakeup_reason;
}
static int qemu_powerdown_requested(void)
{
int r = powerdown_requested;
powerdown_requested = 0;
return r;
}
static int qemu_debug_requested(void)
{
int r = debug_requested;
debug_requested = 0;
return r;
}
/*
* Reset the VM. Issue an event unless @reason is SHUTDOWN_CAUSE_NONE.
*/
void qemu_system_reset(ShutdownCause reason)
{
MachineClass *mc;
mc = current_machine ? MACHINE_GET_CLASS(current_machine) : NULL;
cpu_synchronize_all_states();
if (mc && mc->reset) {
mc->reset(current_machine);
} else {
qemu_devices_reset();
}
if (reason && reason != SHUTDOWN_CAUSE_SUBSYSTEM_RESET) {
qapi_event_send_reset(shutdown_caused_by_guest(reason), reason);
}
cpu_synchronize_all_post_reset();
}
/*
* Wake the VM after suspend.
*/
static void qemu_system_wakeup(void)
{
MachineClass *mc;
mc = current_machine ? MACHINE_GET_CLASS(current_machine) : NULL;
if (mc && mc->wakeup) {
mc->wakeup(current_machine);
}
}
void qemu_system_guest_panicked(GuestPanicInformation *info)
{
qemu_log_mask(LOG_GUEST_ERROR, "Guest crashed");
if (current_cpu) {
current_cpu->crash_occurred = true;
}
/*
* TODO: Currently the available panic actions are: none, pause, and
* poweroff, but in principle debug and reset could be supported as well.
* Investigate any potential use cases for the unimplemented actions.
*/
if (panic_action == PANIC_ACTION_PAUSE) {
qapi_event_send_guest_panicked(GUEST_PANIC_ACTION_PAUSE,
!!info, info);
vm_stop(RUN_STATE_GUEST_PANICKED);
} else if (panic_action == PANIC_ACTION_POWEROFF) {
qapi_event_send_guest_panicked(GUEST_PANIC_ACTION_POWEROFF,
!!info, info);
vm_stop(RUN_STATE_GUEST_PANICKED);
qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_PANIC);
} else {
qapi_event_send_guest_panicked(GUEST_PANIC_ACTION_RUN,
!!info, info);
}
if (info) {
if (info->type == GUEST_PANIC_INFORMATION_TYPE_HYPER_V) {
qemu_log_mask(LOG_GUEST_ERROR, "\nHV crash parameters: (%#"PRIx64
" %#"PRIx64" %#"PRIx64" %#"PRIx64" %#"PRIx64")\n",
info->u.hyper_v.arg1,
info->u.hyper_v.arg2,
info->u.hyper_v.arg3,
info->u.hyper_v.arg4,
info->u.hyper_v.arg5);
} else if (info->type == GUEST_PANIC_INFORMATION_TYPE_S390) {
qemu_log_mask(LOG_GUEST_ERROR, " on cpu %d: %s\n"
"PSW: 0x%016" PRIx64 " 0x%016" PRIx64"\n",
info->u.s390.core,
S390CrashReason_str(info->u.s390.reason),
info->u.s390.psw_mask,
info->u.s390.psw_addr);
}
qapi_free_GuestPanicInformation(info);
}
}
void qemu_system_guest_crashloaded(GuestPanicInformation *info)
{
qemu_log_mask(LOG_GUEST_ERROR, "Guest crash loaded");
qapi_event_send_guest_crashloaded(GUEST_PANIC_ACTION_RUN,
!!info, info);
if (info) {
qapi_free_GuestPanicInformation(info);
}
}
void qemu_system_reset_request(ShutdownCause reason)
{
if (reboot_action == REBOOT_ACTION_SHUTDOWN &&
reason != SHUTDOWN_CAUSE_SUBSYSTEM_RESET) {
shutdown_requested = reason;
} else {
reset_requested = reason;
}
cpu_stop_current();
qemu_notify_event();
}
static void qemu_system_suspend(void)
{
pause_all_vcpus();
notifier_list_notify(&suspend_notifiers, NULL);
runstate_set(RUN_STATE_SUSPENDED);
qapi_event_send_suspend();
}
void qemu_system_suspend_request(void)
{
if (runstate_check(RUN_STATE_SUSPENDED)) {
return;
}
suspend_requested = 1;
cpu_stop_current();
qemu_notify_event();
}
void qemu_register_suspend_notifier(Notifier *notifier)
{
notifier_list_add(&suspend_notifiers, notifier);
}
void qemu_system_wakeup_request(WakeupReason reason, Error **errp)
{
trace_system_wakeup_request(reason);
if (!runstate_check(RUN_STATE_SUSPENDED)) {
error_setg(errp,
"Unable to wake up: guest is not in suspended state");
return;
}
if (!(wakeup_reason_mask & (1 << reason))) {
return;
}
runstate_set(RUN_STATE_RUNNING);
wakeup_reason = reason;
qemu_notify_event();
}
void qemu_system_wakeup_enable(WakeupReason reason, bool enabled)
{
if (enabled) {
wakeup_reason_mask |= (1 << reason);
} else {
wakeup_reason_mask &= ~(1 << reason);
}
}
void qemu_register_wakeup_notifier(Notifier *notifier)
{
notifier_list_add(&wakeup_notifiers, notifier);
}
static bool wakeup_suspend_enabled;
void qemu_register_wakeup_support(void)
{
wakeup_suspend_enabled = true;
}
bool qemu_wakeup_suspend_enabled(void)
{
return wakeup_suspend_enabled;
}
void qemu_system_killed(int signal, pid_t pid)
{
shutdown_signal = signal;
shutdown_pid = pid;
shutdown_action = SHUTDOWN_ACTION_POWEROFF;
/* Cannot call qemu_system_shutdown_request directly because
* we are in a signal handler.
*/
shutdown_requested = SHUTDOWN_CAUSE_HOST_SIGNAL;
qemu_notify_event();
}
void qemu_system_shutdown_request(ShutdownCause reason)
{
trace_qemu_system_shutdown_request(reason);
replay_shutdown_request(reason);
shutdown_requested = reason;
qemu_notify_event();
}
static void qemu_system_powerdown(void)
{
qapi_event_send_powerdown();
notifier_list_notify(&powerdown_notifiers, NULL);
}
static void qemu_system_shutdown(ShutdownCause cause)
{
qapi_event_send_shutdown(shutdown_caused_by_guest(cause), cause);
notifier_list_notify(&shutdown_notifiers, &cause);
}
void qemu_system_powerdown_request(void)
{
trace_qemu_system_powerdown_request();
powerdown_requested = 1;
qemu_notify_event();
}
void qemu_register_powerdown_notifier(Notifier *notifier)
{
notifier_list_add(&powerdown_notifiers, notifier);
}
void qemu_register_shutdown_notifier(Notifier *notifier)
{
notifier_list_add(&shutdown_notifiers, notifier);
}
void qemu_system_debug_request(void)
{
debug_requested = 1;
qemu_notify_event();
}
static bool main_loop_should_exit(void)
{
RunState r;
ShutdownCause request;
if (qemu_debug_requested()) {
vm_stop(RUN_STATE_DEBUG);
}
if (qemu_suspend_requested()) {
qemu_system_suspend();
}
request = qemu_shutdown_requested();
if (request) {
qemu_kill_report();
qemu_system_shutdown(request);
if (shutdown_action == SHUTDOWN_ACTION_PAUSE) {
vm_stop(RUN_STATE_SHUTDOWN);
} else {
return true;
}
}
request = qemu_reset_requested();
if (request) {
pause_all_vcpus();
qemu_system_reset(request);
resume_all_vcpus();
/*
* runstate can change in pause_all_vcpus()
* as iothread mutex is unlocked
*/
if (!runstate_check(RUN_STATE_RUNNING) &&
!runstate_check(RUN_STATE_INMIGRATE) &&
!runstate_check(RUN_STATE_FINISH_MIGRATE)) {
runstate_set(RUN_STATE_PRELAUNCH);
}
}
if (qemu_wakeup_requested()) {
pause_all_vcpus();
qemu_system_wakeup();
notifier_list_notify(&wakeup_notifiers, &wakeup_reason);
wakeup_reason = QEMU_WAKEUP_REASON_NONE;
resume_all_vcpus();
qapi_event_send_wakeup();
}
if (qemu_powerdown_requested()) {
qemu_system_powerdown();
}
if (qemu_vmstop_requested(&r)) {
vm_stop(r);
}
return false;
}
void qemu_main_loop(void)
{
#ifdef CONFIG_PROFILER
int64_t ti;
#endif
while (!main_loop_should_exit()) {
#ifdef CONFIG_PROFILER
ti = profile_getclock();
#endif
main_loop_wait(false);
#ifdef CONFIG_PROFILER
dev_time += profile_getclock() - ti;
#endif
}
}
void qemu_add_exit_notifier(Notifier *notify)
{
notifier_list_add(&exit_notifiers, notify);
}
void qemu_remove_exit_notifier(Notifier *notify)
{
notifier_remove(notify);
}
static void qemu_run_exit_notifiers(void)
{
notifier_list_notify(&exit_notifiers, NULL);
}
void qemu_init_subsystems(void)
{
Error *err;
os_set_line_buffering();
module_call_init(MODULE_INIT_TRACE);
qemu_init_cpu_list();
qemu_init_cpu_loop();
qemu_mutex_lock_iothread();
atexit(qemu_run_exit_notifiers);
module_call_init(MODULE_INIT_QOM);
module_call_init(MODULE_INIT_MIGRATION);
runstate_init();
precopy_infrastructure_init();
postcopy_infrastructure_init();
monitor_init_globals();
if (qcrypto_init(&err) < 0) {
error_reportf_err(err, "cannot initialize crypto: ");
exit(1);
}
os_setup_early_signal_handling();
bdrv_init_with_whitelist();
socket_init();
}
void qemu_cleanup(void)
{
gdbserver_cleanup();
/*
* cleaning up the migration object cancels any existing migration
* try to do this early so that it also stops using devices.
*/
migration_shutdown();
/*
* We must cancel all block jobs while the block layer is drained,
* or cancelling will be affected by throttling and thus may block
* for an extended period of time.
* vm_shutdown() will bdrv_drain_all(), so we may as well include
* it in the drained section.
* We do not need to end this section, because we do not want any
* requests happening from here on anyway.
*/
bdrv_drain_all_begin();
/* No more vcpu or device emulation activity beyond this point */
vm_shutdown();
replay_finish();
job_cancel_sync_all();
bdrv_close_all();
/* vhost-user must be cleaned up before chardevs. */
tpm_cleanup();
net_cleanup();
audio_cleanup();
monitor_cleanup();
qemu_chr_cleanup();
user_creatable_cleanup();
/* TODO: unref root container, check all devices are ok */
}

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +0,0 @@
#include "qemu/osdep.h"
#include "sysemu/sysemu.h"
bool machine_init_done = true;
void qemu_add_machine_init_done_notifier(Notifier *notify)
{
}

View File

@ -21,7 +21,6 @@ stub_ss.add(files('iothread-lock.c'))
stub_ss.add(files('isa-bus.c'))
stub_ss.add(files('is-daemonized.c'))
stub_ss.add(when: 'CONFIG_LINUX_AIO', if_true: files('linux-aio.c'))
stub_ss.add(files('machine-init-done.c'))
stub_ss.add(files('migr-blocker.c'))
stub_ss.add(files('monitor.c'))
stub_ss.add(files('monitor-core.c'))
@ -29,6 +28,7 @@ stub_ss.add(files('pci-bus.c'))
stub_ss.add(files('pci-host-piix.c'))
stub_ss.add(files('qemu-timer-notify-cb.c'))
stub_ss.add(files('qmp_memory_device.c'))
stub_ss.add(files('qmp-command-available.c'))
stub_ss.add(files('qtest.c'))
stub_ss.add(files('ram-block.c'))
stub_ss.add(files('ramfb.c'))

View File

@ -0,0 +1,7 @@
#include "qemu/osdep.h"
#include "qapi/qmp/dispatch.h"
bool qmp_command_available(const QmpCommand *cmd, Error **errp)
{
return true;
}

View File

@ -304,7 +304,7 @@ class Engine(object):
argv_source += ["-mem-path", "/dev/shm",
"-mem-prealloc"]
if hardware._locked_pages:
argv_source += ["-realtime", "mlock=on"]
argv_source += ["-overcommit", "mem-lock=on"]
if hardware._huge_pages:
pass

View File

@ -48,6 +48,55 @@ static void test_lp1878642_pci_bus_get_irq_level_assert(void)
qtest_quit(s);
}
/*
* Here a MemoryRegionCache pointed to an MMIO region but had a
* larger size than the underlying region.
*/
static void test_mmio_oob_from_memory_region_cache(void)
{
QTestState *s;
s = qtest_init("-M pc-q35-5.2 -display none -m 512M "
"-device virtio-scsi,num_queues=8,addr=03.0 ");
qtest_outl(s, 0xcf8, 0x80001811);
qtest_outb(s, 0xcfc, 0x6e);
qtest_outl(s, 0xcf8, 0x80001824);
qtest_outl(s, 0xcf8, 0x80001813);
qtest_outl(s, 0xcfc, 0xa080000);
qtest_outl(s, 0xcf8, 0x80001802);
qtest_outl(s, 0xcfc, 0x5a175a63);
qtest_outb(s, 0x6e08, 0x9e);
qtest_writeb(s, 0x9f003, 0xff);
qtest_writeb(s, 0x9f004, 0x01);
qtest_writeb(s, 0x9e012, 0x0e);
qtest_writeb(s, 0x9e01b, 0x0e);
qtest_writeb(s, 0x9f006, 0x01);
qtest_writeb(s, 0x9f008, 0x01);
qtest_writeb(s, 0x9f00a, 0x01);
qtest_writeb(s, 0x9f00c, 0x01);
qtest_writeb(s, 0x9f00e, 0x01);
qtest_writeb(s, 0x9f010, 0x01);
qtest_writeb(s, 0x9f012, 0x01);
qtest_writeb(s, 0x9f014, 0x01);
qtest_writeb(s, 0x9f016, 0x01);
qtest_writeb(s, 0x9f018, 0x01);
qtest_writeb(s, 0x9f01a, 0x01);
qtest_writeb(s, 0x9f01c, 0x01);
qtest_writeb(s, 0x9f01e, 0x01);
qtest_writeb(s, 0x9f020, 0x01);
qtest_writeb(s, 0x9f022, 0x01);
qtest_writeb(s, 0x9f024, 0x01);
qtest_writeb(s, 0x9f026, 0x01);
qtest_writeb(s, 0x9f028, 0x01);
qtest_writeb(s, 0x9f02a, 0x01);
qtest_writeb(s, 0x9f02c, 0x01);
qtest_writeb(s, 0x9f02e, 0x01);
qtest_writeb(s, 0x9f030, 0x01);
qtest_outb(s, 0x6e10, 0x00);
qtest_quit(s);
}
int main(int argc, char **argv)
{
const char *arch = qtest_get_arch();
@ -59,6 +108,8 @@ int main(int argc, char **argv)
test_lp1878263_megasas_zero_iov_cnt);
qtest_add_func("fuzz/test_lp1878642_pci_bus_get_irq_level_assert",
test_lp1878642_pci_bus_get_irq_level_assert);
qtest_add_func("fuzz/test_mmio_oob_from_memory_region_cache",
test_mmio_oob_from_memory_region_cache);
}
return g_test_run();

View File

@ -11,13 +11,36 @@
#include "libqos/libqtest.h"
#include "qapi/qmp/qdict.h"
static void test_panic_nopause(void)
{
uint8_t val;
QDict *response, *data;
QTestState *qts;
qts = qtest_init("-device pvpanic -action panic=none");
val = qtest_inb(qts, 0x505);
g_assert_cmpuint(val, ==, 3);
qtest_outb(qts, 0x505, 0x1);
response = qtest_qmp_eventwait_ref(qts, "GUEST_PANICKED");
g_assert(qdict_haskey(response, "data"));
data = qdict_get_qdict(response, "data");
g_assert(qdict_haskey(data, "action"));
g_assert_cmpstr(qdict_get_str(data, "action"), ==, "run");
qobject_unref(response);
qtest_quit(qts);
}
static void test_panic(void)
{
uint8_t val;
QDict *response, *data;
QTestState *qts;
qts = qtest_init("-device pvpanic");
qts = qtest_init("-device pvpanic -action panic=pause");
val = qtest_inb(qts, 0x505);
g_assert_cmpuint(val, ==, 3);
@ -40,6 +63,7 @@ int main(int argc, char **argv)
g_test_init(&argc, &argv, NULL);
qtest_add_func("/pvpanic/panic", test_panic);
qtest_add_func("/pvpanic/panic-nopause", test_panic_nopause);
ret = g_test_run();

View File

@ -295,7 +295,7 @@ static void test_qmp_preconfig(void)
rsp = qtest_qmp(qs, "{ 'execute': 'query-status' }");
ret = qdict_get_qdict(rsp, "return");
g_assert(ret);
g_assert_cmpstr(qdict_get_try_str(ret, "status"), ==, "preconfig");
g_assert_cmpstr(qdict_get_try_str(ret, "status"), ==, "prelaunch");
qobject_unref(rsp);
/* exit preconfig state */

View File

@ -73,11 +73,9 @@ static void print_int64(int i, int64_t num)
#ifndef SNANF
/* Signaling NaN macros, if supported. */
# if __GNUC_PREREQ(3, 3)
# define SNANF (__builtin_nansf (""))
# define SNAN (__builtin_nans (""))
# define SNANL (__builtin_nansl (""))
# endif
# define SNANF (__builtin_nansf (""))
# define SNAN (__builtin_nans (""))
# define SNANL (__builtin_nansl (""))
#endif
float single_numbers[] = { -SNANF,

View File

@ -807,15 +807,6 @@ void fuse_remove_signal_handlers(struct fuse_session *se);
*
* On 32bit systems please add -D_FILE_OFFSET_BITS=64 to your compile flags!
*/
#if defined(__GNUC__) && \
(__GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ >= 6) && \
!defined __cplusplus
_Static_assert(sizeof(off_t) == 8, "fuse: off_t must be 64bit");
#else
struct _fuse_off_t_must_be_64bit_dummy_struct {
unsigned _fuse_off_t_must_be_64bit:((sizeof(off_t) == 8) ? 1 : -1);
};
#endif
QEMU_BUILD_BUG_ON(sizeof(off_t) != 8);
#endif /* FUSE_COMMON_H_ */

View File

@ -1345,7 +1345,7 @@ static QemuConsole *new_console(DisplayState *ds, console_type_t console_type,
if (QTAILQ_EMPTY(&consoles)) {
s->index = 0;
QTAILQ_INSERT_TAIL(&consoles, s, next);
} else if (console_type != GRAPHIC_CONSOLE || qdev_hotplug) {
} else if (console_type != GRAPHIC_CONSOLE || phase_check(PHASE_MACHINE_READY)) {
QemuConsole *last = QTAILQ_LAST(&consoles);
s->index = last->index + 1;
QTAILQ_INSERT_TAIL(&consoles, s, next);

View File

@ -30,6 +30,7 @@
#include "ui/input.h"
#include "ui/sdl2.h"
#include "sysemu/runstate.h"
#include "sysemu/runstate-action.h"
#include "sysemu/sysemu.h"
#include "ui/win32-kbd-hook.h"
@ -606,7 +607,7 @@ static void handle_windowevent(SDL_Event *ev)
allow_close = false;
}
if (allow_close) {
no_shutdown = 0;
shutdown_action = SHUTDOWN_ACTION_POWEROFF;
qemu_system_shutdown_request(SHUTDOWN_CAUSE_HOST_UI);
}
} else {
@ -653,7 +654,7 @@ void sdl2_poll_events(struct sdl2_console *scon)
allow_close = false;
}
if (allow_close) {
no_shutdown = 0;
shutdown_action = SHUTDOWN_ACTION_POWEROFF;
qemu_system_shutdown_request(SHUTDOWN_CAUSE_HOST_UI);
}
break;

View File

@ -38,27 +38,19 @@
#include "qemu/help_option.h"
/*
* Extracts the name of an option from the parameter string (p points at the
* Extracts the name of an option from the parameter string (@p points at the
* first byte of the option name)
*
* The option name is delimited by delim (usually , or =) or the string end
* and is copied into option. The caller is responsible for free'ing option
* when no longer required.
* The option name is @len characters long and is copied into @option. The
* caller is responsible for free'ing @option when no longer required.
*
* The return value is the position of the delimiter/zero byte after the option
* name in p.
* name in @p.
*/
static const char *get_opt_name(const char *p, char **option, char delim)
static const char *get_opt_name(const char *p, char **option, size_t len)
{
char *offset = strchr(p, delim);
if (offset) {
*option = g_strndup(p, offset - p);
return offset;
} else {
*option = g_strdup(p);
return p + strlen(p);
}
*option = g_strndup(p, len);
return p + len;
}
/*
@ -468,16 +460,16 @@ static bool qemu_opt_parse(QemuOpt *opt, Error **errp)
}
}
static bool opts_accepts_any(const QemuOpts *opts)
static bool opts_accepts_any(const QemuOptsList *list)
{
return opts->list->desc[0].name == NULL;
return list->desc[0].name == NULL;
}
int qemu_opt_unset(QemuOpts *opts, const char *name)
{
QemuOpt *opt = qemu_opt_find(opts, name);
assert(opts_accepts_any(opts));
assert(opts_accepts_any(opts->list));
if (opt == NULL) {
return -1;
@ -508,9 +500,10 @@ static bool opt_validate(QemuOpt *opt, bool *help_wanted,
Error **errp)
{
const QemuOptDesc *desc;
const QemuOptsList *list = opt->opts->list;
desc = find_desc_by_name(opt->opts->list->desc, opt->name);
if (!desc && !opts_accepts_any(opt->opts)) {
desc = find_desc_by_name(list->desc, opt->name);
if (!desc && !opts_accepts_any(list)) {
error_setg(errp, QERR_INVALID_PARAMETER, opt->name);
if (help_wanted && is_help_option(opt->name)) {
*help_wanted = true;
@ -543,9 +536,10 @@ bool qemu_opt_set_bool(QemuOpts *opts, const char *name, bool val,
{
QemuOpt *opt;
const QemuOptDesc *desc;
const QemuOptsList *list = opts->list;
desc = find_desc_by_name(opts->list->desc, name);
if (!desc && !opts_accepts_any(opts)) {
desc = find_desc_by_name(list->desc, name);
if (!desc && !opts_accepts_any(list)) {
error_setg(errp, QERR_INVALID_PARAMETER, name);
return false;
}
@ -565,9 +559,10 @@ bool qemu_opt_set_number(QemuOpts *opts, const char *name, int64_t val,
{
QemuOpt *opt;
const QemuOptDesc *desc;
const QemuOptsList *list = opts->list;
desc = find_desc_by_name(opts->list->desc, name);
if (!desc && !opts_accepts_any(opts)) {
desc = find_desc_by_name(list->desc, name);
if (!desc && !opts_accepts_any(list)) {
error_setg(errp, QERR_INVALID_PARAMETER, name);
return false;
}
@ -766,12 +761,11 @@ static const char *get_opt_name_value(const char *params,
const char *firstname,
char **name, char **value)
{
const char *p, *pe, *pc;
const char *p;
size_t len;
pe = strchr(params, '=');
pc = strchr(params, ',');
if (!pe || (pc && pc < pe)) {
len = strcspn(params, "=,");
if (params[len] != '=') {
/* found "foo,more" */
if (firstname) {
/* implicitly named first option */
@ -779,7 +773,7 @@ static const char *get_opt_name_value(const char *params,
p = get_opt_value(params, value);
} else {
/* option without value, must be a flag */
p = get_opt_name(params, name, ',');
p = get_opt_name(params, name, len);
if (strncmp(*name, "no", 2) == 0) {
memmove(*name, *name + 2, strlen(*name + 2) + 1);
*value = g_strdup("off");
@ -789,7 +783,7 @@ static const char *get_opt_name_value(const char *params,
}
} else {
/* found "foo=bar,more" */
p = get_opt_name(params, name, '=');
p = get_opt_name(params, name, len);
assert(*p == '=');
p++;
p = get_opt_value(p, value);
@ -1116,7 +1110,7 @@ bool qemu_opts_validate(QemuOpts *opts, const QemuOptDesc *desc, Error **errp)
{
QemuOpt *opt;
assert(opts_accepts_any(opts));
assert(opts_accepts_any(opts->list));
QTAILQ_FOREACH(opt, &opts->head, next) {
opt->desc = find_desc_by_name(desc, opt->name);