mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-04 00:03:54 -06:00
TCG Plugins initial implementation
- use --enable-plugins @ configure - low impact introspection (-plugin empty.so to measure overhead) - plugins cannot alter guest state - example plugins included in source tree (tests/plugins) - -d plugin to enable plugin output in logs - check-tcg runs extra tests when plugins enabled - documentation in docs/devel/plugins.rst -----BEGIN PGP SIGNATURE----- iQEzBAABCgAdFiEEZoWumedRZ7yvyN81+9DbCVqeKkQFAl23BZMACgkQ+9DbCVqe KkRPegf/QHygZ4ER2jOaWEookxiOEcik+dzQKVGNqLNXeMLvo5fGjGVpFoFxSgfv ZvCAL4xbW44zsYlVfh59tfn4Tu9qK7s7/qM3WXpHsmuvEuhoWef0Lt2jSe+D46Rs KeG/aX+rHLUR8rr9eCgE+1/MQmxPUj3VUonkUpNkk2ebBbSNoLSOudB4DD9Vcyl7 Pya1kPvA6W9bwI20ZSWihE7flg13o62Pp+LgAFLrsfxXOxOMkPrU8Pp+B0Dvr+hL 5Oh0clZLhiRi75x+KVGZ90TVsoftdjYoOWGMOudS/+NNmqKT1NTLm0K1WJYyRMQ1 V0ne4/OcGNq7x8gcOx/xs09ADu5/VA== =UXR/ -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/stsquad/tags/pull-tcg-plugins-281019-4' into staging TCG Plugins initial implementation - use --enable-plugins @ configure - low impact introspection (-plugin empty.so to measure overhead) - plugins cannot alter guest state - example plugins included in source tree (tests/plugins) - -d plugin to enable plugin output in logs - check-tcg runs extra tests when plugins enabled - documentation in docs/devel/plugins.rst # gpg: Signature made Mon 28 Oct 2019 15:13:23 GMT # gpg: using RSA key 6685AE99E75167BCAFC8DF35FBD0DB095A9E2A44 # gpg: Good signature from "Alex Bennée (Master Work Key) <alex.bennee@linaro.org>" [full] # Primary key fingerprint: 6685 AE99 E751 67BC AFC8 DF35 FBD0 DB09 5A9E 2A44 * remotes/stsquad/tags/pull-tcg-plugins-281019-4: (57 commits) travis.yml: enable linux-gcc-debug-tcg cache MAINTAINERS: add me for the TCG plugins code scripts/checkpatch.pl: don't complain about (foo, /* empty */) .travis.yml: add --enable-plugins tests include/exec: wrap cpu_ldst.h in CONFIG_TCG accel/stubs: reduce headers from tcg-stub tests/plugin: add hotpages to analyse memory access patterns tests/plugin: add instruction execution breakdown tests/plugin: add a hotblocks plugin tests/tcg: enable plugin testing tests/tcg: drop test-i386-fprem from TESTS when not SLOW tests/tcg: move "virtual" tests to EXTRA_TESTS tests/tcg: set QEMU_OPTS for all cris runs tests/tcg/Makefile.target: fix path to config-host.mak tests/plugin: add sample plugins linux-user: support -plugin option vl: support -plugin option plugin: add qemu_plugin_outs helper plugin: add qemu_plugin_insn_disas helper plugin: expand the plugin_init function to include an info block ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
68d8ef4ec5
92 changed files with 5172 additions and 169 deletions
|
@ -22,3 +22,4 @@ Contents:
|
|||
decodetree
|
||||
secure-coding-practices
|
||||
tcg
|
||||
plugins
|
||||
|
|
112
docs/devel/plugins.rst
Normal file
112
docs/devel/plugins.rst
Normal file
|
@ -0,0 +1,112 @@
|
|||
..
|
||||
Copyright (C) 2017, Emilio G. Cota <cota@braap.org>
|
||||
Copyright (c) 2019, Linaro Limited
|
||||
Written by Emilio Cota and Alex Bennée
|
||||
|
||||
================
|
||||
QEMU TCG Plugins
|
||||
================
|
||||
|
||||
QEMU TCG plugins provide a way for users to run experiments taking
|
||||
advantage of the total system control emulation can have over a guest.
|
||||
It provides a mechanism for plugins to subscribe to events during
|
||||
translation and execution and optionally callback into the plugin
|
||||
during these events. TCG plugins are unable to change the system state
|
||||
only monitor it passively. However they can do this down to an
|
||||
individual instruction granularity including potentially subscribing
|
||||
to all load and store operations.
|
||||
|
||||
API Stability
|
||||
=============
|
||||
|
||||
This is a new feature for QEMU and it does allow people to develop
|
||||
out-of-tree plugins that can be dynamically linked into a running QEMU
|
||||
process. However the project reserves the right to change or break the
|
||||
API should it need to do so. The best way to avoid this is to submit
|
||||
your plugin upstream so they can be updated if/when the API changes.
|
||||
|
||||
|
||||
Exposure of QEMU internals
|
||||
--------------------------
|
||||
|
||||
The plugin architecture actively avoids leaking implementation details
|
||||
about how QEMU's translation works to the plugins. While there are
|
||||
conceptions such as translation time and translation blocks the
|
||||
details are opaque to plugins. The plugin is able to query select
|
||||
details of instructions and system configuration only through the
|
||||
exported *qemu_plugin* functions. The types used to describe
|
||||
instructions and events are opaque to the plugins themselves.
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
The QEMU binary needs to be compiled for plugin support:
|
||||
|
||||
::
|
||||
configure --enable-plugins
|
||||
|
||||
Once built a program can be run with multiple plugins loaded each with
|
||||
their own arguments:
|
||||
|
||||
::
|
||||
$QEMU $OTHER_QEMU_ARGS \
|
||||
-plugin tests/plugin/libhowvec.so,arg=inline,arg=hint \
|
||||
-plugin tests/plugin/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
|
||||
ops to count and break down the hint instructions by type.
|
||||
|
||||
Plugin Life cycle
|
||||
=================
|
||||
|
||||
First the plugin is loaded and the public qemu_plugin_install function
|
||||
is called. The plugin will then register callbacks for various plugin
|
||||
events. Generally plugins will register a handler for the *atexit*
|
||||
if they want to dump a summary of collected information once the
|
||||
program/system has finished running.
|
||||
|
||||
When a registered event occurs the plugin callback is invoked. The
|
||||
callbacks may provide additional information. In the case of a
|
||||
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.
|
||||
|
||||
Finally when QEMU exits all the registered *atexit* callbacks are
|
||||
invoked.
|
||||
|
||||
Internals
|
||||
=========
|
||||
|
||||
Locking
|
||||
-------
|
||||
|
||||
We have to ensure we cannot deadlock, particularly under MTTCG. For
|
||||
this we acquire a lock when called from plugin code. We also keep the
|
||||
list of callbacks under RCU so that we do not have to hold the lock
|
||||
when calling the callbacks. This is also for performance, since some
|
||||
callbacks (e.g. memory access callbacks) might be called very
|
||||
frequently.
|
||||
|
||||
* A consequence of this is that we keep our own list of CPUs, so that
|
||||
we do not have to worry about locking order wrt cpu_list_lock.
|
||||
* Use a recursive lock, since we can get registration calls from
|
||||
callbacks.
|
||||
|
||||
As a result registering/unregistering callbacks is "slow", since it
|
||||
takes a lock. But this is very infrequent; we want performance when
|
||||
calling (or not calling) callbacks, not when registering them. Using
|
||||
RCU is great for this.
|
||||
|
||||
We support the uninstallation of a plugin at any time (e.g. from
|
||||
plugin callbacks). This allows plugins to remove themselves if they no
|
||||
longer want to instrument the code. This operation is asynchronous
|
||||
which means callbacks may still occur after the uninstall operation is
|
||||
requested. The plugin isn't completely uninstalled until the safe work
|
||||
has executed while all vCPUs are quiescent.
|
Loading…
Add table
Add a link
Reference in a new issue