]>
Commit | Line | Data |
---|---|---|
027e3332 AB |
1 | .. |
2 | Copyright (C) 2017, Emilio G. Cota <cota@braap.org> | |
3 | Copyright (c) 2019, Linaro Limited | |
4 | Written by Emilio Cota and Alex Bennée | |
5 | ||
6 | ================ | |
7 | QEMU TCG Plugins | |
8 | ================ | |
9 | ||
10 | QEMU TCG plugins provide a way for users to run experiments taking | |
11 | advantage of the total system control emulation can have over a guest. | |
12 | It provides a mechanism for plugins to subscribe to events during | |
13 | translation and execution and optionally callback into the plugin | |
14 | during these events. TCG plugins are unable to change the system state | |
15 | only monitor it passively. However they can do this down to an | |
16 | individual instruction granularity including potentially subscribing | |
17 | to all load and store operations. | |
18 | ||
19 | API Stability | |
20 | ============= | |
21 | ||
22 | This is a new feature for QEMU and it does allow people to develop | |
23 | out-of-tree plugins that can be dynamically linked into a running QEMU | |
24 | process. However the project reserves the right to change or break the | |
25 | API should it need to do so. The best way to avoid this is to submit | |
26 | your plugin upstream so they can be updated if/when the API changes. | |
27 | ||
5c6ecbdc AB |
28 | API versioning |
29 | -------------- | |
30 | ||
31 | All plugins need to declare a symbol which exports the plugin API | |
32 | version they were built against. This can be done simply by:: | |
33 | ||
34 | QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION; | |
35 | ||
36 | The core code will refuse to load a plugin that doesn't export a | |
37 | `qemu_plugin_version` symbol or if plugin version is outside of QEMU's | |
38 | supported range of API versions. | |
39 | ||
40 | Additionally the `qemu_info_t` structure which is passed to the | |
41 | `qemu_plugin_install` method of a plugin will detail the minimum and | |
42 | current API versions supported by QEMU. The API version will be | |
43 | incremented if new APIs are added. The minimum API version will be | |
44 | incremented if existing APIs are changed or removed. | |
027e3332 AB |
45 | |
46 | Exposure of QEMU internals | |
47 | -------------------------- | |
48 | ||
49 | The plugin architecture actively avoids leaking implementation details | |
50 | about how QEMU's translation works to the plugins. While there are | |
51 | conceptions such as translation time and translation blocks the | |
52 | details are opaque to plugins. The plugin is able to query select | |
53 | details of instructions and system configuration only through the | |
9675a9c6 AB |
54 | exported *qemu_plugin* functions. |
55 | ||
56 | Query Handle Lifetime | |
57 | --------------------- | |
58 | ||
59 | Each callback provides an opaque anonymous information handle which | |
60 | can usually be further queried to find out information about a | |
61 | translation, instruction or operation. The handles themselves are only | |
62 | valid during the lifetime of the callback so it is important that any | |
63 | information that is needed is extracted during the callback and saved | |
64 | by the plugin. | |
027e3332 AB |
65 | |
66 | Usage | |
67 | ===== | |
68 | ||
5c6ecbdc | 69 | The QEMU binary needs to be compiled for plugin support:: |
027e3332 | 70 | |
5c6ecbdc | 71 | configure --enable-plugins |
027e3332 AB |
72 | |
73 | Once built a program can be run with multiple plugins loaded each with | |
5c6ecbdc | 74 | their own arguments:: |
027e3332 | 75 | |
5c6ecbdc | 76 | $QEMU $OTHER_QEMU_ARGS \ |
027e3332 AB |
77 | -plugin tests/plugin/libhowvec.so,arg=inline,arg=hint \ |
78 | -plugin tests/plugin/libhotblocks.so | |
79 | ||
80 | Arguments are plugin specific and can be used to modify their | |
81 | behaviour. In this case the howvec plugin is being asked to use inline | |
82 | ops to count and break down the hint instructions by type. | |
83 | ||
84 | Plugin Life cycle | |
85 | ================= | |
86 | ||
87 | First the plugin is loaded and the public qemu_plugin_install function | |
88 | is called. The plugin will then register callbacks for various plugin | |
89 | events. Generally plugins will register a handler for the *atexit* | |
90 | if they want to dump a summary of collected information once the | |
91 | program/system has finished running. | |
92 | ||
93 | When a registered event occurs the plugin callback is invoked. The | |
94 | callbacks may provide additional information. In the case of a | |
95 | translation event the plugin has an option to enumerate the | |
96 | instructions in a block of instructions and optionally register | |
97 | callbacks to some or all instructions when they are executed. | |
98 | ||
99 | There is also a facility to add an inline event where code to | |
100 | increment a counter can be directly inlined with the translation. | |
101 | Currently only a simple increment is supported. This is not atomic so | |
102 | can miss counts. If you want absolute precision you should use a | |
103 | callback which can then ensure atomicity itself. | |
104 | ||
105 | Finally when QEMU exits all the registered *atexit* callbacks are | |
106 | invoked. | |
107 | ||
108 | Internals | |
109 | ========= | |
110 | ||
111 | Locking | |
112 | ------- | |
113 | ||
114 | We have to ensure we cannot deadlock, particularly under MTTCG. For | |
115 | this we acquire a lock when called from plugin code. We also keep the | |
116 | list of callbacks under RCU so that we do not have to hold the lock | |
117 | when calling the callbacks. This is also for performance, since some | |
118 | callbacks (e.g. memory access callbacks) might be called very | |
119 | frequently. | |
120 | ||
121 | * A consequence of this is that we keep our own list of CPUs, so that | |
122 | we do not have to worry about locking order wrt cpu_list_lock. | |
123 | * Use a recursive lock, since we can get registration calls from | |
124 | callbacks. | |
125 | ||
126 | As a result registering/unregistering callbacks is "slow", since it | |
127 | takes a lock. But this is very infrequent; we want performance when | |
128 | calling (or not calling) callbacks, not when registering them. Using | |
129 | RCU is great for this. | |
130 | ||
131 | We support the uninstallation of a plugin at any time (e.g. from | |
132 | plugin callbacks). This allows plugins to remove themselves if they no | |
133 | longer want to instrument the code. This operation is asynchronous | |
134 | which means callbacks may still occur after the uninstall operation is | |
135 | requested. The plugin isn't completely uninstalled until the safe work | |
136 | has executed while all vCPUs are quiescent. |