| 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 | .. _TCG Plugins: |
| 7 | |
| 8 | QEMU TCG Plugins |
| 9 | ================ |
| 10 | |
| 11 | |
| 12 | Writing plugins |
| 13 | --------------- |
| 14 | |
| 15 | API versioning |
| 16 | ~~~~~~~~~~~~~~ |
| 17 | |
| 18 | This is a new feature for QEMU and it does allow people to develop |
| 19 | out-of-tree plugins that can be dynamically linked into a running QEMU |
| 20 | process. However the project reserves the right to change or break the |
| 21 | API should it need to do so. The best way to avoid this is to submit |
| 22 | your plugin upstream so they can be updated if/when the API changes. |
| 23 | |
| 24 | All plugins need to declare a symbol which exports the plugin API |
| 25 | version they were built against. This can be done simply by:: |
| 26 | |
| 27 | QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION; |
| 28 | |
| 29 | The core code will refuse to load a plugin that doesn't export a |
| 30 | ``qemu_plugin_version`` symbol or if plugin version is outside of QEMU's |
| 31 | supported range of API versions. |
| 32 | |
| 33 | Additionally the ``qemu_info_t`` structure which is passed to the |
| 34 | ``qemu_plugin_install`` method of a plugin will detail the minimum and |
| 35 | current API versions supported by QEMU. The API version will be |
| 36 | incremented if new APIs are added. The minimum API version will be |
| 37 | incremented if existing APIs are changed or removed. |
| 38 | |
| 39 | Lifetime of the query handle |
| 40 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 41 | |
| 42 | Each callback provides an opaque anonymous information handle which |
| 43 | can usually be further queried to find out information about a |
| 44 | translation, instruction or operation. The handles themselves are only |
| 45 | valid during the lifetime of the callback so it is important that any |
| 46 | information that is needed is extracted during the callback and saved |
| 47 | by the plugin. |
| 48 | |
| 49 | Plugin life cycle |
| 50 | ~~~~~~~~~~~~~~~~~ |
| 51 | |
| 52 | First the plugin is loaded and the public qemu_plugin_install function |
| 53 | is called. The plugin will then register callbacks for various plugin |
| 54 | events. Generally plugins will register a handler for the *atexit* |
| 55 | if they want to dump a summary of collected information once the |
| 56 | program/system has finished running. |
| 57 | |
| 58 | When a registered event occurs the plugin callback is invoked. The |
| 59 | callbacks may provide additional information. In the case of a |
| 60 | translation event the plugin has an option to enumerate the |
| 61 | instructions in a block of instructions and optionally register |
| 62 | callbacks to some or all instructions when they are executed. |
| 63 | |
| 64 | There is also a facility to add inline instructions doing various operations, |
| 65 | like adding or storing an immediate value. It is also possible to execute a |
| 66 | callback conditionally, with condition being evaluated inline. All those inline |
| 67 | operations are associated to a ``scoreboard``, which is a thread-local storage |
| 68 | automatically expanded when new cores/threads are created and that can be |
| 69 | accessed/modified in a thread-safe way without any lock needed. Combining inline |
| 70 | operations and conditional callbacks offer a more efficient way to instrument |
| 71 | binaries, compared to classic callbacks. |
| 72 | |
| 73 | Finally when QEMU exits all the registered *atexit* callbacks are |
| 74 | invoked. |
| 75 | |
| 76 | Exposure of QEMU internals |
| 77 | ~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 78 | |
| 79 | The plugin architecture actively avoids leaking implementation details |
| 80 | about how QEMU's translation works to the plugins. While there are |
| 81 | conceptions such as translation time and translation blocks the |
| 82 | details are opaque to plugins. The plugin is able to query select |
| 83 | details of instructions and system configuration only through the |
| 84 | exported *qemu_plugin* functions. |
| 85 | |
| 86 | However the following assumptions can be made: |
| 87 | |
| 88 | Translation Blocks |
| 89 | ++++++++++++++++++ |
| 90 | |
| 91 | All code will go through a translation phase although not all |
| 92 | translations will be necessarily be executed. You need to instrument |
| 93 | actual executions to track what is happening. |
| 94 | |
| 95 | It is quite normal to see the same address translated multiple times. |
| 96 | If you want to track the code in system emulation you should examine |
| 97 | the underlying physical address (``qemu_plugin_insn_haddr``) to take |
| 98 | into account the effects of virtual memory although if the system does |
| 99 | paging this will change too. |
| 100 | |
| 101 | Not all instructions in a block will always execute so if its |
| 102 | important to track individual instruction execution you need to |
| 103 | instrument them directly. However asynchronous interrupts will not |
| 104 | change control flow mid-block. |
| 105 | |
| 106 | Instructions |
| 107 | ++++++++++++ |
| 108 | |
| 109 | Instruction instrumentation runs before the instruction executes. You |
| 110 | can be can be sure the instruction will be dispatched, but you can't |
| 111 | be sure it will complete. Generally this will be because of a |
| 112 | synchronous exception (e.g. SIGILL) triggered by the instruction |
| 113 | attempting to execute. If you want to be sure you will need to |
| 114 | instrument the next instruction as well. See the ``execlog.c`` plugin |
| 115 | for examples of how to track this and finalise details after execution. |
| 116 | |
| 117 | Memory Accesses |
| 118 | +++++++++++++++ |
| 119 | |
| 120 | Memory callbacks are called after a successful load or store. |
| 121 | Unsuccessful operations (i.e. faults) will not be visible to memory |
| 122 | instrumentation although the execution side effects can be observed |
| 123 | (e.g. entering a exception handler). |
| 124 | |
| 125 | System Idle and Resume States |
| 126 | +++++++++++++++++++++++++++++ |
| 127 | |
| 128 | The ``qemu_plugin_register_vcpu_idle_cb`` and |
| 129 | ``qemu_plugin_register_vcpu_resume_cb`` functions can be used to track |
| 130 | when CPUs go into and return from sleep states when waiting for |
| 131 | external I/O. Be aware though that these may occur less frequently |
| 132 | than in real HW due to the inefficiencies of emulation giving less |
| 133 | chance for the CPU to idle. |
| 134 | |
| 135 | Internals |
| 136 | --------- |
| 137 | |
| 138 | Locking |
| 139 | ~~~~~~~ |
| 140 | |
| 141 | We have to ensure we cannot deadlock, particularly under MTTCG. For |
| 142 | this we acquire a lock when called from plugin code. We also keep the |
| 143 | list of callbacks under RCU so that we do not have to hold the lock |
| 144 | when calling the callbacks. This is also for performance, since some |
| 145 | callbacks (e.g. memory access callbacks) might be called very |
| 146 | frequently. |
| 147 | |
| 148 | * A consequence of this is that we keep our own list of CPUs, so that |
| 149 | we do not have to worry about locking order wrt cpu_list_lock. |
| 150 | * Use a recursive lock, since we can get registration calls from |
| 151 | callbacks. |
| 152 | |
| 153 | As a result registering/unregistering callbacks is "slow", since it |
| 154 | takes a lock. But this is very infrequent; we want performance when |
| 155 | calling (or not calling) callbacks, not when registering them. Using |
| 156 | RCU is great for this. |
| 157 | |
| 158 | We support the uninstallation of a plugin at any time (e.g. from |
| 159 | plugin callbacks). This allows plugins to remove themselves if they no |
| 160 | longer want to instrument the code. This operation is asynchronous |
| 161 | which means callbacks may still occur after the uninstall operation is |
| 162 | requested. The plugin isn't completely uninstalled until the safe work |
| 163 | has executed while all vCPUs are quiescent. |
| 164 | |
| 165 | Plugin API |
| 166 | ========== |
| 167 | |
| 168 | The following API is generated from the inline documentation in |
| 169 | ``include/plugins/qemu-plugin.h``. Please ensure any updates to the API |
| 170 | include the full kernel-doc annotations. |
| 171 | |
| 172 | .. kernel-doc:: include/plugins/qemu-plugin.h |