mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge tag 'pull-maintainer-9.1-rc3-160824-1' of https://gitlab.com/stsquad/qemu into staging
Some fixes for 9.1-rc3 (build, replay, docs, plugins) - re-enable gdbsim-r5f562n8 test - ensure updates to python deps re-trigger configure - tweak configure detection of GDB MTE support - make checkpatch emit more warnings on updating headers - allow i386 access_ptr to force slow path for plugins - fixe some replay regressions - update the replay-dump tool - better handle muxed chardev during replay - clean up TCG plugins docs to mention scoreboards - fix plugin scoreboard race condition # -----BEGIN PGP SIGNATURE----- # # iQEzBAABCgAdFiEEZoWumedRZ7yvyN81+9DbCVqeKkQFAma/UJcACgkQ+9DbCVqe # KkT51gf/buOo0leJnBkYDTPWOOsDupW/nUUqOlTStvpKGEVNZgmxH0V4ffdCNO8E # P4xQpD8WrpFKZHu2zE7EmXJ6/wkSp2BeSPcZ8lhld8jKNY3ksBlsCwb26/D9WsWK # /JaqAegdg3fwCgbcQ057dRlKJV2ojjWD/JqPWa5G9AIlSqiHEfvcTj9t33BpJKXC # xV7Yt1TZExkfkCAny54Sx4O6oiDhvSgJmWCUGIVE2W39+g3jUKf2tvbggR5MEIH3 # fJ/F2vmcnllmK21awiRa9/WVZ55+Cbgj6PlLf/Qh6rhzooTMy+x0G+5BkNtZwNCs # 8qFu8vFkuJM9YwDw9btaz3b+nG8Mzg== # =HUN1 # -----END PGP SIGNATURE----- # gpg: Signature made Fri 16 Aug 2024 11:13:59 PM AEST # gpg: using RSA key 6685AE99E75167BCAFC8DF35FBD0DB095A9E2A44 # gpg: Good signature from "Alex Bennée (Master Work Key) <alex.bennee@linaro.org>" [full] * tag 'pull-maintainer-9.1-rc3-160824-1' of https://gitlab.com/stsquad/qemu: (21 commits) plugins: fix race condition with scoreboards docs/devel: update tcg-plugins page docs: Fix some typos (found by typos) and grammar issues savevm: Fix load_snapshot error path crash virtio-net: Use virtual time for RSC timers virtio-net: Use replay_schedule_bh_event for bhs that affect machine state chardev: set record/replay on the base device of a muxed device tests/avocado: replay_kernel.py add x86-64 q35 machine test Revert "replay: stop us hanging in rr_wait_io_event" replay: allow runstate shutdown->running when replaying trace tests/avocado: excercise scripts/replay-dump.py in replay tests scripts/replay-dump.py: rejig decoders in event number order scripts/replay-dump.py: Update to current rr record format buildsys: Fix building without plugins on Darwin target/i386: allow access_ptr to force slow path on failed probe scripts/checkpatch: more checks on files imported from Linux configure: Fix GDB version detection for GDB_HAS_MTE configure: Avoid use of param. expansion when using gdb_version configure: Fix arch detection for GDB_HAS_MTE Makefile: trigger re-configure on updated pythondeps ... Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
@@ -78,7 +78,8 @@ x := $(shell rm -rf meson-private meson-info meson-logs)
|
||||
endif
|
||||
|
||||
# 1. ensure config-host.mak is up-to-date
|
||||
config-host.mak: $(SRC_PATH)/configure $(SRC_PATH)/scripts/meson-buildoptions.sh $(SRC_PATH)/VERSION
|
||||
config-host.mak: $(SRC_PATH)/configure $(SRC_PATH)/scripts/meson-buildoptions.sh \
|
||||
$(SRC_PATH)/pythondeps.toml $(SRC_PATH)/VERSION
|
||||
@echo config-host.mak is out-of-date, running configure
|
||||
@if test -f meson-private/coredata.dat; then \
|
||||
./config.status --skip-meson; \
|
||||
|
||||
@@ -109,7 +109,7 @@ static void rr_wait_io_event(void)
|
||||
{
|
||||
CPUState *cpu;
|
||||
|
||||
while (all_cpu_threads_idle() && replay_can_wait()) {
|
||||
while (all_cpu_threads_idle()) {
|
||||
rr_stop_kick_timer();
|
||||
qemu_cond_wait_bql(first_cpu->halt_cond);
|
||||
}
|
||||
|
||||
+50
-21
@@ -615,11 +615,24 @@ ChardevBackend *qemu_chr_parse_opts(QemuOpts *opts, Error **errp)
|
||||
return backend;
|
||||
}
|
||||
|
||||
Chardev *qemu_chr_new_from_opts(QemuOpts *opts, GMainContext *context,
|
||||
Error **errp)
|
||||
static void qemu_chardev_set_replay(Chardev *chr, Error **errp)
|
||||
{
|
||||
if (replay_mode != REPLAY_MODE_NONE) {
|
||||
if (CHARDEV_GET_CLASS(chr)->chr_ioctl) {
|
||||
error_setg(errp, "Replay: ioctl is not supported "
|
||||
"for serial devices yet");
|
||||
return;
|
||||
}
|
||||
qemu_chr_set_feature(chr, QEMU_CHAR_FEATURE_REPLAY);
|
||||
replay_register_char_driver(chr);
|
||||
}
|
||||
}
|
||||
|
||||
static Chardev *__qemu_chr_new_from_opts(QemuOpts *opts, GMainContext *context,
|
||||
bool replay, Error **errp)
|
||||
{
|
||||
const ChardevClass *cc;
|
||||
Chardev *chr = NULL;
|
||||
Chardev *base = NULL, *chr = NULL;
|
||||
ChardevBackend *backend = NULL;
|
||||
const char *name = qemu_opt_get(opts, "backend");
|
||||
const char *id = qemu_opts_id(opts);
|
||||
@@ -657,11 +670,11 @@ Chardev *qemu_chr_new_from_opts(QemuOpts *opts, GMainContext *context,
|
||||
chr = qemu_chardev_new(bid ? bid : id,
|
||||
object_class_get_name(OBJECT_CLASS(cc)),
|
||||
backend, context, errp);
|
||||
|
||||
if (chr == NULL) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
base = chr;
|
||||
if (bid) {
|
||||
Chardev *mux;
|
||||
qapi_free_ChardevBackend(backend);
|
||||
@@ -681,11 +694,25 @@ Chardev *qemu_chr_new_from_opts(QemuOpts *opts, GMainContext *context,
|
||||
out:
|
||||
qapi_free_ChardevBackend(backend);
|
||||
g_free(bid);
|
||||
|
||||
if (replay && base) {
|
||||
/* RR should be set on the base device, not the mux */
|
||||
qemu_chardev_set_replay(base, errp);
|
||||
}
|
||||
|
||||
return chr;
|
||||
}
|
||||
|
||||
Chardev *qemu_chr_new_noreplay(const char *label, const char *filename,
|
||||
bool permit_mux_mon, GMainContext *context)
|
||||
Chardev *qemu_chr_new_from_opts(QemuOpts *opts, GMainContext *context,
|
||||
Error **errp)
|
||||
{
|
||||
/* XXX: should this really not record/replay? */
|
||||
return __qemu_chr_new_from_opts(opts, context, false, errp);
|
||||
}
|
||||
|
||||
static Chardev *__qemu_chr_new(const char *label, const char *filename,
|
||||
bool permit_mux_mon, GMainContext *context,
|
||||
bool replay)
|
||||
{
|
||||
const char *p;
|
||||
Chardev *chr;
|
||||
@@ -693,14 +720,22 @@ Chardev *qemu_chr_new_noreplay(const char *label, const char *filename,
|
||||
Error *err = NULL;
|
||||
|
||||
if (strstart(filename, "chardev:", &p)) {
|
||||
return qemu_chr_find(p);
|
||||
chr = qemu_chr_find(p);
|
||||
if (replay) {
|
||||
qemu_chardev_set_replay(chr, &err);
|
||||
if (err) {
|
||||
error_report_err(err);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return chr;
|
||||
}
|
||||
|
||||
opts = qemu_chr_parse_compat(label, filename, permit_mux_mon);
|
||||
if (!opts)
|
||||
return NULL;
|
||||
|
||||
chr = qemu_chr_new_from_opts(opts, context, &err);
|
||||
chr = __qemu_chr_new_from_opts(opts, context, replay, &err);
|
||||
if (!chr) {
|
||||
error_report_err(err);
|
||||
goto out;
|
||||
@@ -722,24 +757,18 @@ out:
|
||||
return chr;
|
||||
}
|
||||
|
||||
Chardev *qemu_chr_new_noreplay(const char *label, const char *filename,
|
||||
bool permit_mux_mon, GMainContext *context)
|
||||
{
|
||||
return __qemu_chr_new(label, filename, permit_mux_mon, context, false);
|
||||
}
|
||||
|
||||
static Chardev *qemu_chr_new_permit_mux_mon(const char *label,
|
||||
const char *filename,
|
||||
bool permit_mux_mon,
|
||||
GMainContext *context)
|
||||
{
|
||||
Chardev *chr;
|
||||
chr = qemu_chr_new_noreplay(label, filename, permit_mux_mon, context);
|
||||
if (chr) {
|
||||
if (replay_mode != REPLAY_MODE_NONE) {
|
||||
qemu_chr_set_feature(chr, QEMU_CHAR_FEATURE_REPLAY);
|
||||
}
|
||||
if (qemu_chr_replay(chr) && CHARDEV_GET_CLASS(chr)->chr_ioctl) {
|
||||
error_report("Replay: ioctl is not supported "
|
||||
"for serial devices yet");
|
||||
}
|
||||
replay_register_char_driver(chr);
|
||||
}
|
||||
return chr;
|
||||
return __qemu_chr_new(label, filename, permit_mux_mon, context, true);
|
||||
}
|
||||
|
||||
Chardev *qemu_chr_new(const char *label, const char *filename,
|
||||
|
||||
@@ -1103,8 +1103,10 @@ fi
|
||||
# gdb test
|
||||
|
||||
if test -n "$gdb_bin"; then
|
||||
gdb_version=$($gdb_bin --version | head -n 1)
|
||||
if version_ge ${gdb_version##* } 9.1; then
|
||||
gdb_version_string=$($gdb_bin --version | head -n 1)
|
||||
# Extract last field in the version string
|
||||
gdb_version=${gdb_version_string##* }
|
||||
if version_ge $gdb_version 9.1; then
|
||||
gdb_arches=$($python "$source_path/scripts/probe-gdb-support.py" $gdb_bin)
|
||||
else
|
||||
gdb_bin=""
|
||||
@@ -1673,7 +1675,7 @@ for target in $target_list; do
|
||||
echo "GDB=$gdb_bin" >> $config_target_mak
|
||||
fi
|
||||
|
||||
if test "${arch}" = "aarch64" && version_ge ${gdb_version##* } 15.0; then
|
||||
if test "${gdb_arches#*aarch64}" != "$gdb_arches" && version_ge $gdb_version 15.1; then
|
||||
echo "GDB_HAS_MTE=y" >> $config_target_mak
|
||||
fi
|
||||
|
||||
|
||||
@@ -207,8 +207,8 @@ Once built a program can be run with multiple plugins loaded each with
|
||||
their own arguments::
|
||||
|
||||
$QEMU $OTHER_QEMU_ARGS \
|
||||
-plugin contrib/plugin/libhowvec.so,inline=on,count=hint \
|
||||
-plugin contrib/plugin/libhotblocks.so
|
||||
-plugin contrib/plugins/libhowvec.so,inline=on,count=hint \
|
||||
-plugin contrib/plugins/libhotblocks.so
|
||||
|
||||
Arguments are plugin specific and can be used to modify their
|
||||
behaviour. In this case the howvec plugin is being asked to use inline
|
||||
@@ -219,6 +219,14 @@ Linux user-mode emulation also evaluates the environment variable
|
||||
|
||||
QEMU_PLUGIN="file=contrib/plugins/libhowvec.so,inline=on,count=hint" $QEMU
|
||||
|
||||
QEMU plugins avoid to write directly to stdin/stderr, and use the log provided
|
||||
by the API (see function ``qemu_plugin_outs``).
|
||||
To show output, you may use this additional parameter::
|
||||
|
||||
$QEMU $OTHER_QEMU_ARGS \
|
||||
-d plugin \
|
||||
-plugin contrib/plugins/libhowvec.so,inline=on,count=hint
|
||||
|
||||
Example Plugins
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -260,8 +268,7 @@ Behaviour can be tweaked with the following arguments:
|
||||
* - Option
|
||||
- Description
|
||||
* - inline=true|false
|
||||
- Use faster inline addition of a single counter. Not per-cpu and not
|
||||
thread safe.
|
||||
- Use faster inline addition of a single counter.
|
||||
* - idle=true|false
|
||||
- Dump the current execution stats whenever the guest vCPU idles
|
||||
|
||||
@@ -381,6 +388,15 @@ run::
|
||||
160 1 0
|
||||
135 1 0
|
||||
|
||||
Test inline operations
|
||||
......................
|
||||
|
||||
``tests/plugins/inline.c``
|
||||
|
||||
This plugin is used for testing all inline operations, conditional callbacks and
|
||||
scoreboard. It prints a per-cpu summary of all events.
|
||||
|
||||
|
||||
Hot Blocks
|
||||
..........
|
||||
|
||||
@@ -394,9 +410,6 @@ with linux-user execution as system emulation tends to generate
|
||||
re-translations as blocks from different programs get swapped in and
|
||||
out of system memory.
|
||||
|
||||
If your program is single-threaded you can use the ``inline`` option for
|
||||
slightly faster (but not thread safe) counters.
|
||||
|
||||
Example::
|
||||
|
||||
$ qemu-aarch64 \
|
||||
@@ -736,6 +749,28 @@ The plugin will log the reason of exit, for example::
|
||||
|
||||
0xd4 reached, exiting
|
||||
|
||||
Limit instructions per second
|
||||
.............................
|
||||
|
||||
This plugin can limit the number of Instructions Per Second that are executed::
|
||||
|
||||
# get number of instructions
|
||||
$ num_insn=$(./build/qemu-x86_64 -plugin ./build/tests/plugin/libinsn.so -d plugin /bin/true |& grep total | sed -e 's/.*: //')
|
||||
# limit speed to execute in 10 seconds
|
||||
$ time ./build/qemu-x86_64 -plugin ./build/contrib/plugins/libips.so,ips=$(($num_insn/10)) /bin/true
|
||||
real 10.000s
|
||||
|
||||
|
||||
.. list-table:: IPS arguments
|
||||
:widths: 20 80
|
||||
:header-rows: 1
|
||||
|
||||
* - Option
|
||||
- Description
|
||||
* - ips=N
|
||||
- Maximum number of instructions per cpu that can be executed in one second.
|
||||
The plugin will sleep when the given number of instructions is reached.
|
||||
|
||||
Other emulation features
|
||||
------------------------
|
||||
|
||||
|
||||
@@ -114,7 +114,7 @@ Make sure all these above kernel configurations are selected.
|
||||
|
||||
Accelerator dev node permissions
|
||||
--------------------------------
|
||||
Harware accelerators(eg: HiSilicon Kunpeng Zip accelerator) gets registered to
|
||||
Hardware accelerators (eg: HiSilicon Kunpeng Zip accelerator) gets registered to
|
||||
UADK and char devices are created in dev directory. In order to access resources
|
||||
on hardware accelerator devices, write permission should be provided to user.
|
||||
|
||||
@@ -134,7 +134,7 @@ How To Use UADK Compression In QEMU Migration
|
||||
Set ``migrate_set_parameter multifd-compression uadk``
|
||||
|
||||
Since UADK uses Shared Virtual Addressing(SVA) and device access virtual memory
|
||||
directly it is possible that SMMUv3 may enounter page faults while walking the
|
||||
directly it is possible that SMMUv3 may encounter page faults while walking the
|
||||
IO page tables. This may impact the performance. In order to mitigate this,
|
||||
please make sure to specify ``-mem-prealloc`` parameter to the destination VM
|
||||
boot parameters.
|
||||
|
||||
@@ -61,11 +61,14 @@ translation event the plugin has an option to enumerate the
|
||||
instructions in a block of instructions and optionally register
|
||||
callbacks to some or all instructions when they are executed.
|
||||
|
||||
There is also a facility to add an inline event where code to
|
||||
increment a counter can be directly inlined with the translation.
|
||||
Currently only a simple increment is supported. This is not atomic so
|
||||
can miss counts. If you want absolute precision you should use a
|
||||
callback which can then ensure atomicity itself.
|
||||
There is also a facility to add inline instructions doing various operations,
|
||||
like adding or storing an immediate value. It is also possible to execute a
|
||||
callback conditionally, with condition being evaluated inline. All those inline
|
||||
operations are associated to a ``scoreboard``, which is a thread-local storage
|
||||
automatically expanded when new cores/threads are created and that can be
|
||||
accessed/modified in a thread-safe way without any lock needed. Combining inline
|
||||
operations and conditional callbacks offer a more efficient way to instrument
|
||||
binaries, compared to classic callbacks.
|
||||
|
||||
Finally when QEMU exits all the registered *atexit* callbacks are
|
||||
invoked.
|
||||
|
||||
@@ -50,7 +50,7 @@ Options
|
||||
.. option:: -c, --config=PATH
|
||||
|
||||
Configuration file path (the default is |CONFDIR|\ ``/qemu-ga.conf``,
|
||||
unless overriden by the QGA_CONF environment variable)
|
||||
unless overridden by the QGA_CONF environment variable)
|
||||
|
||||
.. option:: -m, --method=METHOD
|
||||
|
||||
|
||||
@@ -17,8 +17,8 @@ driver to advertise and monitor the power consumption or accumulated energy
|
||||
consumption of different power domains, such as CPU packages, DRAM, and other
|
||||
components when available.
|
||||
|
||||
However those register are accesible under priviliged access (CAP_SYS_RAWIO).
|
||||
QEMU can use an external helper to access those priviliged register.
|
||||
However those registers are accessible under privileged access (CAP_SYS_RAWIO).
|
||||
QEMU can use an external helper to access those privileged registers.
|
||||
|
||||
:program:`qemu-vmsr-helper` is that external helper; it creates a listener
|
||||
socket which will accept incoming connections for communication with QEMU.
|
||||
|
||||
@@ -674,7 +674,7 @@ error:
|
||||
|
||||
/*
|
||||
* combine S1 and S2 TLB entries into a single entry.
|
||||
* As a result the S1 entry is overriden with combined data.
|
||||
* As a result the S1 entry is overridden with combined data.
|
||||
*/
|
||||
static void combine_tlb(SMMUTLBEntry *tlbe, SMMUTLBEntry *tlbe_s2,
|
||||
dma_addr_t iova, SMMUTransCfg *cfg)
|
||||
|
||||
+9
-8
@@ -40,6 +40,7 @@
|
||||
#include "migration/misc.h"
|
||||
#include "standard-headers/linux/ethtool.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
#include "sysemu/replay.h"
|
||||
#include "trace.h"
|
||||
#include "monitor/qdev.h"
|
||||
#include "monitor/monitor.h"
|
||||
@@ -417,7 +418,7 @@ static void virtio_net_set_status(struct VirtIODevice *vdev, uint8_t status)
|
||||
timer_mod(q->tx_timer,
|
||||
qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + n->tx_timeout);
|
||||
} else {
|
||||
qemu_bh_schedule(q->tx_bh);
|
||||
replay_bh_schedule_event(q->tx_bh);
|
||||
}
|
||||
} else {
|
||||
if (q->tx_timer) {
|
||||
@@ -2123,7 +2124,7 @@ static void virtio_net_rsc_purge(void *opq)
|
||||
chain->stat.timer++;
|
||||
if (!QTAILQ_EMPTY(&chain->buffers)) {
|
||||
timer_mod(chain->drain_timer,
|
||||
qemu_clock_get_ns(QEMU_CLOCK_HOST) + chain->n->rsc_timeout);
|
||||
qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + chain->n->rsc_timeout);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2359,7 +2360,7 @@ static size_t virtio_net_rsc_do_coalesce(VirtioNetRscChain *chain,
|
||||
chain->stat.empty_cache++;
|
||||
virtio_net_rsc_cache_buf(chain, nc, buf, size);
|
||||
timer_mod(chain->drain_timer,
|
||||
qemu_clock_get_ns(QEMU_CLOCK_HOST) + chain->n->rsc_timeout);
|
||||
qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + chain->n->rsc_timeout);
|
||||
return size;
|
||||
}
|
||||
|
||||
@@ -2597,7 +2598,7 @@ static VirtioNetRscChain *virtio_net_rsc_lookup_chain(VirtIONet *n,
|
||||
chain->max_payload = VIRTIO_NET_MAX_IP6_PAYLOAD;
|
||||
chain->gso_type = VIRTIO_NET_HDR_GSO_TCPV6;
|
||||
}
|
||||
chain->drain_timer = timer_new_ns(QEMU_CLOCK_HOST,
|
||||
chain->drain_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
|
||||
virtio_net_rsc_purge, chain);
|
||||
memset(&chain->stat, 0, sizeof(chain->stat));
|
||||
|
||||
@@ -2672,7 +2673,7 @@ static void virtio_net_tx_complete(NetClientState *nc, ssize_t len)
|
||||
*/
|
||||
virtio_queue_set_notification(q->tx_vq, 0);
|
||||
if (q->tx_bh) {
|
||||
qemu_bh_schedule(q->tx_bh);
|
||||
replay_bh_schedule_event(q->tx_bh);
|
||||
} else {
|
||||
timer_mod(q->tx_timer,
|
||||
qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + n->tx_timeout);
|
||||
@@ -2838,7 +2839,7 @@ static void virtio_net_handle_tx_bh(VirtIODevice *vdev, VirtQueue *vq)
|
||||
return;
|
||||
}
|
||||
virtio_queue_set_notification(vq, 0);
|
||||
qemu_bh_schedule(q->tx_bh);
|
||||
replay_bh_schedule_event(q->tx_bh);
|
||||
}
|
||||
|
||||
static void virtio_net_tx_timer(void *opaque)
|
||||
@@ -2921,7 +2922,7 @@ static void virtio_net_tx_bh(void *opaque)
|
||||
/* If we flush a full burst of packets, assume there are
|
||||
* more coming and immediately reschedule */
|
||||
if (ret >= n->tx_burst) {
|
||||
qemu_bh_schedule(q->tx_bh);
|
||||
replay_bh_schedule_event(q->tx_bh);
|
||||
q->tx_waiting = 1;
|
||||
return;
|
||||
}
|
||||
@@ -2935,7 +2936,7 @@ static void virtio_net_tx_bh(void *opaque)
|
||||
return;
|
||||
} else if (ret > 0) {
|
||||
virtio_queue_set_notification(q->tx_vq, 0);
|
||||
qemu_bh_schedule(q->tx_bh);
|
||||
replay_bh_schedule_event(q->tx_bh);
|
||||
q->tx_waiting = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1852,7 +1852,7 @@ void memory_region_iommu_replay(IOMMUMemoryRegion *iommu_mr, IOMMUNotifier *n);
|
||||
* memory_region_unregister_iommu_notifier: unregister a notifier for
|
||||
* changes to IOMMU translation entries.
|
||||
*
|
||||
* @mr: the memory region which was observed and for which notity_stopped()
|
||||
* @mr: the memory region which was observed and for which notify_stopped()
|
||||
* needs to be called
|
||||
* @n: the notifier to be removed.
|
||||
*/
|
||||
|
||||
@@ -73,11 +73,6 @@ int replay_get_instructions(void);
|
||||
/*! Updates instructions counter in replay mode. */
|
||||
void replay_account_executed_instructions(void);
|
||||
|
||||
/**
|
||||
* replay_can_wait: check if we should pause for wait-io
|
||||
*/
|
||||
bool replay_can_wait(void);
|
||||
|
||||
/* Processing clocks and other time sources */
|
||||
|
||||
/*! Save the specified clock */
|
||||
|
||||
@@ -9,6 +9,7 @@ void runstate_set(RunState new_state);
|
||||
RunState runstate_get(void);
|
||||
bool runstate_is_running(void);
|
||||
bool runstate_needs_reset(void);
|
||||
void runstate_replay_enable(void);
|
||||
|
||||
typedef void VMChangeStateHandler(void *opaque, bool running, RunState state);
|
||||
|
||||
|
||||
@@ -3288,6 +3288,7 @@ bool load_snapshot(const char *name, const char *vmstate,
|
||||
/* Don't even try to load empty VM states */
|
||||
ret = bdrv_snapshot_find(bs_vm_state, &sn, name);
|
||||
if (ret < 0) {
|
||||
error_setg(errp, "Snapshot can not be found");
|
||||
return false;
|
||||
} else if (sn.vm_state_size == 0) {
|
||||
error_setg(errp, "This is a disk-only snapshot. Revert to it "
|
||||
|
||||
+32
-13
@@ -214,30 +214,49 @@ CPUPluginState *qemu_plugin_create_vcpu_state(void)
|
||||
|
||||
static void plugin_grow_scoreboards__locked(CPUState *cpu)
|
||||
{
|
||||
if (cpu->cpu_index < plugin.scoreboard_alloc_size) {
|
||||
size_t scoreboard_size = plugin.scoreboard_alloc_size;
|
||||
bool need_realloc = false;
|
||||
|
||||
if (cpu->cpu_index < scoreboard_size) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool need_realloc = FALSE;
|
||||
while (cpu->cpu_index >= plugin.scoreboard_alloc_size) {
|
||||
plugin.scoreboard_alloc_size *= 2;
|
||||
need_realloc = TRUE;
|
||||
while (cpu->cpu_index >= scoreboard_size) {
|
||||
scoreboard_size *= 2;
|
||||
need_realloc = true;
|
||||
}
|
||||
|
||||
|
||||
if (!need_realloc || QLIST_EMPTY(&plugin.scoreboards)) {
|
||||
/* nothing to do, we just updated sizes for future scoreboards */
|
||||
if (!need_realloc) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (QLIST_EMPTY(&plugin.scoreboards)) {
|
||||
/* just update size for future scoreboards */
|
||||
plugin.scoreboard_alloc_size = scoreboard_size;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* A scoreboard creation/deletion might be in progress. If a new vcpu is
|
||||
* initialized at the same time, we are safe, as the new
|
||||
* plugin.scoreboard_alloc_size was not yet written.
|
||||
*/
|
||||
qemu_rec_mutex_unlock(&plugin.lock);
|
||||
|
||||
/* cpus must be stopped, as tb might still use an existing scoreboard. */
|
||||
start_exclusive();
|
||||
struct qemu_plugin_scoreboard *score;
|
||||
QLIST_FOREACH(score, &plugin.scoreboards, entry) {
|
||||
g_array_set_size(score->data, plugin.scoreboard_alloc_size);
|
||||
/* re-acquire lock */
|
||||
qemu_rec_mutex_lock(&plugin.lock);
|
||||
/* in case another vcpu is created between unlock and exclusive section. */
|
||||
if (scoreboard_size > plugin.scoreboard_alloc_size) {
|
||||
struct qemu_plugin_scoreboard *score;
|
||||
QLIST_FOREACH(score, &plugin.scoreboards, entry) {
|
||||
g_array_set_size(score->data, scoreboard_size);
|
||||
}
|
||||
plugin.scoreboard_alloc_size = scoreboard_size;
|
||||
/* force all tb to be flushed, as scoreboard pointers were changed. */
|
||||
tb_flush(cpu);
|
||||
}
|
||||
/* force all tb to be flushed, as scoreboard pointers were changed. */
|
||||
tb_flush(cpu);
|
||||
end_exclusive();
|
||||
}
|
||||
|
||||
|
||||
+26
-24
@@ -1,3 +1,7 @@
|
||||
if not get_option('plugins')
|
||||
subdir_done()
|
||||
endif
|
||||
|
||||
# Modules need more symbols than just those in plugins/qemu-plugins.symbols
|
||||
if not enable_modules
|
||||
if host_os == 'darwin'
|
||||
@@ -12,29 +16,27 @@ if not enable_modules
|
||||
endif
|
||||
endif
|
||||
|
||||
if get_option('plugins')
|
||||
if host_os == 'windows'
|
||||
dlltool = find_program('dlltool', required: true)
|
||||
if host_os == 'windows'
|
||||
dlltool = find_program('dlltool', required: true)
|
||||
|
||||
# Generate a .lib file for plugins to link against.
|
||||
# First, create a .def file listing all the symbols a plugin should expect to have
|
||||
# available in qemu
|
||||
win32_plugin_def = configure_file(
|
||||
input: files('qemu-plugins.symbols'),
|
||||
output: 'qemu_plugin_api.def',
|
||||
capture: true,
|
||||
command: ['sed', '-e', '0,/^/s//EXPORTS/; s/[{};]//g', '@INPUT@'])
|
||||
# then use dlltool to assemble a delaylib.
|
||||
win32_qemu_plugin_api_lib = configure_file(
|
||||
input: win32_plugin_def,
|
||||
output: 'libqemu_plugin_api.a',
|
||||
command: [dlltool, '--input-def', '@INPUT@',
|
||||
'--output-delaylib', '@OUTPUT@', '--dllname', 'qemu.exe']
|
||||
)
|
||||
endif
|
||||
specific_ss.add(files(
|
||||
'loader.c',
|
||||
'core.c',
|
||||
'api.c',
|
||||
))
|
||||
# Generate a .lib file for plugins to link against.
|
||||
# First, create a .def file listing all the symbols a plugin should expect to have
|
||||
# available in qemu
|
||||
win32_plugin_def = configure_file(
|
||||
input: files('qemu-plugins.symbols'),
|
||||
output: 'qemu_plugin_api.def',
|
||||
capture: true,
|
||||
command: ['sed', '-e', '0,/^/s//EXPORTS/; s/[{};]//g', '@INPUT@'])
|
||||
# then use dlltool to assemble a delaylib.
|
||||
win32_qemu_plugin_api_lib = configure_file(
|
||||
input: win32_plugin_def,
|
||||
output: 'libqemu_plugin_api.a',
|
||||
command: [dlltool, '--input-def', '@INPUT@',
|
||||
'--output-delaylib', '@OUTPUT@', '--dllname', 'qemu.exe']
|
||||
)
|
||||
endif
|
||||
specific_ss.add(files(
|
||||
'loader.c',
|
||||
'core.c',
|
||||
'api.c',
|
||||
))
|
||||
|
||||
+2
-2
@@ -42,7 +42,7 @@
|
||||
##
|
||||
# @RockerPortDuplex:
|
||||
#
|
||||
# An eumeration of port duplex states.
|
||||
# An enumeration of port duplex states.
|
||||
#
|
||||
# @half: half duplex
|
||||
#
|
||||
@@ -55,7 +55,7 @@
|
||||
##
|
||||
# @RockerPortAutoneg:
|
||||
#
|
||||
# An eumeration of port autoneg states.
|
||||
# An enumeration of port autoneg states.
|
||||
#
|
||||
# @off: autoneg is off
|
||||
#
|
||||
|
||||
+1
-1
@@ -257,7 +257,7 @@ QEMU_COPYRIGHT "\n"
|
||||
"\n"
|
||||
" -c, --config=PATH configuration file path (default is\n"
|
||||
" %s/qemu-ga.conf\n"
|
||||
" unless overriden by the QGA_CONF environment variable)\n"
|
||||
" unless overridden by the QGA_CONF environment variable)\n"
|
||||
" -m, --method transport method: one of unix-listen, virtio-serial,\n"
|
||||
" isa-serial, or vsock-listen (virtio-serial is the default)\n"
|
||||
" -p, --path device/socket path (the default for virtio-serial is:\n"
|
||||
|
||||
+2
-21
@@ -385,6 +385,8 @@ static void replay_enable(const char *fname, int mode)
|
||||
replay_fetch_data_kind();
|
||||
}
|
||||
|
||||
runstate_replay_enable();
|
||||
|
||||
replay_init_events();
|
||||
}
|
||||
|
||||
@@ -449,27 +451,6 @@ void replay_start(void)
|
||||
replay_enable_events();
|
||||
}
|
||||
|
||||
/*
|
||||
* For none/record the answer is yes.
|
||||
*/
|
||||
bool replay_can_wait(void)
|
||||
{
|
||||
if (replay_mode == REPLAY_MODE_PLAY) {
|
||||
/*
|
||||
* For playback we shouldn't ever be at a point we wait. If
|
||||
* the instruction count has reached zero and we have an
|
||||
* unconsumed event we should go around again and consume it.
|
||||
*/
|
||||
if (replay_state.instruction_count == 0 && replay_state.has_unread_data) {
|
||||
return false;
|
||||
} else {
|
||||
replay_sync_error("Playback shouldn't have to iowait");
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void replay_finish(void)
|
||||
{
|
||||
if (replay_mode == REPLAY_MODE_NONE) {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user