xref: /openbmc/qemu/docs/devel/tcg-plugins.rst (revision c17a386b6afe608086aa4d260e29662865680b7f)
18ea6abf0SAlex Bennée..
28ea6abf0SAlex Bennée   Copyright (C) 2017, Emilio G. Cota <cota@braap.org>
38ea6abf0SAlex Bennée   Copyright (c) 2019, Linaro Limited
48ea6abf0SAlex Bennée   Written by Emilio Cota and Alex Bennée
58ea6abf0SAlex Bennée
68ea6abf0SAlex Bennée================
78ea6abf0SAlex BennéeQEMU TCG Plugins
88ea6abf0SAlex Bennée================
98ea6abf0SAlex Bennée
108ea6abf0SAlex BennéeQEMU TCG plugins provide a way for users to run experiments taking
118ea6abf0SAlex Bennéeadvantage of the total system control emulation can have over a guest.
128ea6abf0SAlex BennéeIt provides a mechanism for plugins to subscribe to events during
138ea6abf0SAlex Bennéetranslation and execution and optionally callback into the plugin
148ea6abf0SAlex Bennéeduring these events. TCG plugins are unable to change the system state
158ea6abf0SAlex Bennéeonly monitor it passively. However they can do this down to an
168ea6abf0SAlex Bennéeindividual instruction granularity including potentially subscribing
178ea6abf0SAlex Bennéeto all load and store operations.
188ea6abf0SAlex Bennée
198ea6abf0SAlex BennéeAPI Stability
208ea6abf0SAlex Bennée=============
218ea6abf0SAlex Bennée
228ea6abf0SAlex BennéeThis is a new feature for QEMU and it does allow people to develop
238ea6abf0SAlex Bennéeout-of-tree plugins that can be dynamically linked into a running QEMU
248ea6abf0SAlex Bennéeprocess. However the project reserves the right to change or break the
258ea6abf0SAlex BennéeAPI should it need to do so. The best way to avoid this is to submit
268ea6abf0SAlex Bennéeyour plugin upstream so they can be updated if/when the API changes.
278ea6abf0SAlex Bennée
285c6ecbdcSAlex BennéeAPI versioning
295c6ecbdcSAlex Bennée--------------
305c6ecbdcSAlex Bennée
315c6ecbdcSAlex BennéeAll plugins need to declare a symbol which exports the plugin API
325c6ecbdcSAlex Bennéeversion they were built against. This can be done simply by::
335c6ecbdcSAlex Bennée
345c6ecbdcSAlex Bennée  QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION;
355c6ecbdcSAlex Bennée
365c6ecbdcSAlex BennéeThe core code will refuse to load a plugin that doesn't export a
375c6ecbdcSAlex Bennée`qemu_plugin_version` symbol or if plugin version is outside of QEMU's
385c6ecbdcSAlex Bennéesupported range of API versions.
395c6ecbdcSAlex Bennée
405c6ecbdcSAlex BennéeAdditionally the `qemu_info_t` structure which is passed to the
415c6ecbdcSAlex Bennée`qemu_plugin_install` method of a plugin will detail the minimum and
425c6ecbdcSAlex Bennéecurrent API versions supported by QEMU. The API version will be
435c6ecbdcSAlex Bennéeincremented if new APIs are added. The minimum API version will be
445c6ecbdcSAlex Bennéeincremented if existing APIs are changed or removed.
458ea6abf0SAlex Bennée
468ea6abf0SAlex BennéeExposure of QEMU internals
478ea6abf0SAlex Bennée--------------------------
488ea6abf0SAlex Bennée
498ea6abf0SAlex BennéeThe plugin architecture actively avoids leaking implementation details
508ea6abf0SAlex Bennéeabout how QEMU's translation works to the plugins. While there are
518ea6abf0SAlex Bennéeconceptions such as translation time and translation blocks the
528ea6abf0SAlex Bennéedetails are opaque to plugins. The plugin is able to query select
538ea6abf0SAlex Bennéedetails of instructions and system configuration only through the
549675a9c6SAlex Bennéeexported *qemu_plugin* functions.
559675a9c6SAlex Bennée
569675a9c6SAlex BennéeQuery Handle Lifetime
579675a9c6SAlex Bennée---------------------
589675a9c6SAlex Bennée
599675a9c6SAlex BennéeEach callback provides an opaque anonymous information handle which
609675a9c6SAlex Bennéecan usually be further queried to find out information about a
619675a9c6SAlex Bennéetranslation, instruction or operation. The handles themselves are only
629675a9c6SAlex Bennéevalid during the lifetime of the callback so it is important that any
639675a9c6SAlex Bennéeinformation that is needed is extracted during the callback and saved
649675a9c6SAlex Bennéeby the plugin.
658ea6abf0SAlex Bennée
668ea6abf0SAlex BennéeUsage
678ea6abf0SAlex Bennée=====
688ea6abf0SAlex Bennée
695c6ecbdcSAlex BennéeThe QEMU binary needs to be compiled for plugin support::
708ea6abf0SAlex Bennée
718ea6abf0SAlex Bennée  configure --enable-plugins
728ea6abf0SAlex Bennée
738ea6abf0SAlex BennéeOnce built a program can be run with multiple plugins loaded each with
745c6ecbdcSAlex Bennéetheir own arguments::
758ea6abf0SAlex Bennée
768ea6abf0SAlex Bennée  $QEMU $OTHER_QEMU_ARGS \
778ea6abf0SAlex Bennée      -plugin tests/plugin/libhowvec.so,arg=inline,arg=hint \
788ea6abf0SAlex Bennée      -plugin tests/plugin/libhotblocks.so
798ea6abf0SAlex Bennée
808ea6abf0SAlex BennéeArguments are plugin specific and can be used to modify their
818ea6abf0SAlex Bennéebehaviour. In this case the howvec plugin is being asked to use inline
828ea6abf0SAlex Bennéeops to count and break down the hint instructions by type.
838ea6abf0SAlex Bennée
848ea6abf0SAlex BennéePlugin Life cycle
858ea6abf0SAlex Bennée=================
868ea6abf0SAlex Bennée
878ea6abf0SAlex BennéeFirst the plugin is loaded and the public qemu_plugin_install function
888ea6abf0SAlex Bennéeis called. The plugin will then register callbacks for various plugin
898ea6abf0SAlex Bennéeevents. Generally plugins will register a handler for the *atexit*
908ea6abf0SAlex Bennéeif they want to dump a summary of collected information once the
918ea6abf0SAlex Bennéeprogram/system has finished running.
928ea6abf0SAlex Bennée
938ea6abf0SAlex BennéeWhen a registered event occurs the plugin callback is invoked. The
948ea6abf0SAlex Bennéecallbacks may provide additional information. In the case of a
958ea6abf0SAlex Bennéetranslation event the plugin has an option to enumerate the
968ea6abf0SAlex Bennéeinstructions in a block of instructions and optionally register
978ea6abf0SAlex Bennéecallbacks to some or all instructions when they are executed.
988ea6abf0SAlex Bennée
998ea6abf0SAlex BennéeThere is also a facility to add an inline event where code to
1008ea6abf0SAlex Bennéeincrement a counter can be directly inlined with the translation.
1018ea6abf0SAlex BennéeCurrently only a simple increment is supported. This is not atomic so
1028ea6abf0SAlex Bennéecan miss counts. If you want absolute precision you should use a
1038ea6abf0SAlex Bennéecallback which can then ensure atomicity itself.
1048ea6abf0SAlex Bennée
1058ea6abf0SAlex BennéeFinally when QEMU exits all the registered *atexit* callbacks are
1068ea6abf0SAlex Bennéeinvoked.
1078ea6abf0SAlex Bennée
1088ea6abf0SAlex BennéeInternals
1098ea6abf0SAlex Bennée=========
1108ea6abf0SAlex Bennée
1118ea6abf0SAlex BennéeLocking
1128ea6abf0SAlex Bennée-------
1138ea6abf0SAlex Bennée
1148ea6abf0SAlex BennéeWe have to ensure we cannot deadlock, particularly under MTTCG. For
1158ea6abf0SAlex Bennéethis we acquire a lock when called from plugin code. We also keep the
1168ea6abf0SAlex Bennéelist of callbacks under RCU so that we do not have to hold the lock
1178ea6abf0SAlex Bennéewhen calling the callbacks. This is also for performance, since some
1188ea6abf0SAlex Bennéecallbacks (e.g. memory access callbacks) might be called very
1198ea6abf0SAlex Bennéefrequently.
1208ea6abf0SAlex Bennée
1218ea6abf0SAlex Bennée  * A consequence of this is that we keep our own list of CPUs, so that
1228ea6abf0SAlex Bennée    we do not have to worry about locking order wrt cpu_list_lock.
1238ea6abf0SAlex Bennée  * Use a recursive lock, since we can get registration calls from
1248ea6abf0SAlex Bennée    callbacks.
1258ea6abf0SAlex Bennée
1268ea6abf0SAlex BennéeAs a result registering/unregistering callbacks is "slow", since it
1278ea6abf0SAlex Bennéetakes a lock. But this is very infrequent; we want performance when
1288ea6abf0SAlex Bennéecalling (or not calling) callbacks, not when registering them. Using
1298ea6abf0SAlex BennéeRCU is great for this.
1308ea6abf0SAlex Bennée
1318ea6abf0SAlex BennéeWe support the uninstallation of a plugin at any time (e.g. from
1328ea6abf0SAlex Bennéeplugin callbacks). This allows plugins to remove themselves if they no
1338ea6abf0SAlex Bennéelonger want to instrument the code. This operation is asynchronous
1348ea6abf0SAlex Bennéewhich means callbacks may still occur after the uninstall operation is
1358ea6abf0SAlex Bennéerequested. The plugin isn't completely uninstalled until the safe work
1368ea6abf0SAlex Bennéehas executed while all vCPUs are quiescent.
137*c17a386bSAlex Bennée
138*c17a386bSAlex BennéeExample Plugins
139*c17a386bSAlex Bennée===============
140*c17a386bSAlex Bennée
141*c17a386bSAlex BennéeThere are a number of plugins included with QEMU and you are
142*c17a386bSAlex Bennéeencouraged to contribute your own plugins plugins upstream. There is a
143*c17a386bSAlex Bennée`contrib/plugins` directory where they can go.
144*c17a386bSAlex Bennée
145*c17a386bSAlex Bennée- tests/plugins
146*c17a386bSAlex Bennée
147*c17a386bSAlex BennéeThese are some basic plugins that are used to test and exercise the
148*c17a386bSAlex BennéeAPI during the `make check-tcg` target.
149*c17a386bSAlex Bennée
150*c17a386bSAlex Bennée- contrib/plugins/hotblocks.c
151*c17a386bSAlex Bennée
152*c17a386bSAlex BennéeThe hotblocks plugin allows you to examine the where hot paths of
153*c17a386bSAlex Bennéeexecution are in your program. Once the program has finished you will
154*c17a386bSAlex Bennéeget a sorted list of blocks reporting the starting PC, translation
155*c17a386bSAlex Bennéecount, number of instructions and execution count. This will work best
156*c17a386bSAlex Bennéewith linux-user execution as system emulation tends to generate
157*c17a386bSAlex Bennéere-translations as blocks from different programs get swapped in and
158*c17a386bSAlex Bennéeout of system memory.
159*c17a386bSAlex Bennée
160*c17a386bSAlex BennéeIf your program is single-threaded you can use the `inline` option for
161*c17a386bSAlex Bennéeslightly faster (but not thread safe) counters.
162*c17a386bSAlex Bennée
163*c17a386bSAlex BennéeExample::
164*c17a386bSAlex Bennée
165*c17a386bSAlex Bennée  ./aarch64-linux-user/qemu-aarch64 \
166*c17a386bSAlex Bennée    -plugin contrib/plugins/libhotblocks.so -d plugin \
167*c17a386bSAlex Bennée    ./tests/tcg/aarch64-linux-user/sha1
168*c17a386bSAlex Bennée  SHA1=15dd99a1991e0b3826fede3deffc1feba42278e6
169*c17a386bSAlex Bennée  collected 903 entries in the hash table
170*c17a386bSAlex Bennée  pc, tcount, icount, ecount
171*c17a386bSAlex Bennée  0x0000000041ed10, 1, 5, 66087
172*c17a386bSAlex Bennée  0x000000004002b0, 1, 4, 66087
173*c17a386bSAlex Bennée  ...
174*c17a386bSAlex Bennée
175*c17a386bSAlex Bennée- contrib/plugins/hotpages.c
176*c17a386bSAlex Bennée
177*c17a386bSAlex BennéeSimilar to hotblocks but this time tracks memory accesses::
178*c17a386bSAlex Bennée
179*c17a386bSAlex Bennée  ./aarch64-linux-user/qemu-aarch64 \
180*c17a386bSAlex Bennée    -plugin contrib/plugins/libhotpages.so -d plugin \
181*c17a386bSAlex Bennée    ./tests/tcg/aarch64-linux-user/sha1
182*c17a386bSAlex Bennée  SHA1=15dd99a1991e0b3826fede3deffc1feba42278e6
183*c17a386bSAlex Bennée  Addr, RCPUs, Reads, WCPUs, Writes
184*c17a386bSAlex Bennée  0x000055007fe000, 0x0001, 31747952, 0x0001, 8835161
185*c17a386bSAlex Bennée  0x000055007ff000, 0x0001, 29001054, 0x0001, 8780625
186*c17a386bSAlex Bennée  0x00005500800000, 0x0001, 687465, 0x0001, 335857
187*c17a386bSAlex Bennée  0x0000000048b000, 0x0001, 130594, 0x0001, 355
188*c17a386bSAlex Bennée  0x0000000048a000, 0x0001, 1826, 0x0001, 11
189*c17a386bSAlex Bennée
190*c17a386bSAlex Bennée- contrib/plugins/howvec.c
191*c17a386bSAlex Bennée
192*c17a386bSAlex BennéeThis is an instruction classifier so can be used to count different
193*c17a386bSAlex Bennéetypes of instructions. It has a number of options to refine which get
194*c17a386bSAlex Bennéecounted. You can give an argument for a class of instructions to break
195*c17a386bSAlex Bennéeit down fully, so for example to see all the system registers
196*c17a386bSAlex Bennéeaccesses::
197*c17a386bSAlex Bennée
198*c17a386bSAlex Bennée  ./aarch64-softmmu/qemu-system-aarch64 $(QEMU_ARGS) \
199*c17a386bSAlex Bennée    -append "root=/dev/sda2 systemd.unit=benchmark.service" \
200*c17a386bSAlex Bennée    -smp 4 -plugin ./contrib/plugins/libhowvec.so,arg=sreg -d plugin
201*c17a386bSAlex Bennée
202*c17a386bSAlex Bennéewhich will lead to a sorted list after the class breakdown::
203*c17a386bSAlex Bennée
204*c17a386bSAlex Bennée  Instruction Classes:
205*c17a386bSAlex Bennée  Class:   UDEF                   not counted
206*c17a386bSAlex Bennée  Class:   SVE                    (68 hits)
207*c17a386bSAlex Bennée  Class:   PCrel addr             (47789483 hits)
208*c17a386bSAlex Bennée  Class:   Add/Sub (imm)          (192817388 hits)
209*c17a386bSAlex Bennée  Class:   Logical (imm)          (93852565 hits)
210*c17a386bSAlex Bennée  Class:   Move Wide (imm)        (76398116 hits)
211*c17a386bSAlex Bennée  Class:   Bitfield               (44706084 hits)
212*c17a386bSAlex Bennée  Class:   Extract                (5499257 hits)
213*c17a386bSAlex Bennée  Class:   Cond Branch (imm)      (147202932 hits)
214*c17a386bSAlex Bennée  Class:   Exception Gen          (193581 hits)
215*c17a386bSAlex Bennée  Class:     NOP                  not counted
216*c17a386bSAlex Bennée  Class:   Hints                  (6652291 hits)
217*c17a386bSAlex Bennée  Class:   Barriers               (8001661 hits)
218*c17a386bSAlex Bennée  Class:   PSTATE                 (1801695 hits)
219*c17a386bSAlex Bennée  Class:   System Insn            (6385349 hits)
220*c17a386bSAlex Bennée  Class:   System Reg             counted individually
221*c17a386bSAlex Bennée  Class:   Branch (reg)           (69497127 hits)
222*c17a386bSAlex Bennée  Class:   Branch (imm)           (84393665 hits)
223*c17a386bSAlex Bennée  Class:   Cmp & Branch           (110929659 hits)
224*c17a386bSAlex Bennée  Class:   Tst & Branch           (44681442 hits)
225*c17a386bSAlex Bennée  Class:   AdvSimd ldstmult       (736 hits)
226*c17a386bSAlex Bennée  Class:   ldst excl              (9098783 hits)
227*c17a386bSAlex Bennée  Class:   Load Reg (lit)         (87189424 hits)
228*c17a386bSAlex Bennée  Class:   ldst noalloc pair      (3264433 hits)
229*c17a386bSAlex Bennée  Class:   ldst pair              (412526434 hits)
230*c17a386bSAlex Bennée  Class:   ldst reg (imm)         (314734576 hits)
231*c17a386bSAlex Bennée  Class: Loads & Stores           (2117774 hits)
232*c17a386bSAlex Bennée  Class: Data Proc Reg            (223519077 hits)
233*c17a386bSAlex Bennée  Class: Scalar FP                (31657954 hits)
234*c17a386bSAlex Bennée  Individual Instructions:
235*c17a386bSAlex Bennée  Instr: mrs x0, sp_el0           (2682661 hits)  (op=0xd5384100/  System Reg)
236*c17a386bSAlex Bennée  Instr: mrs x1, tpidr_el2        (1789339 hits)  (op=0xd53cd041/  System Reg)
237*c17a386bSAlex Bennée  Instr: mrs x2, tpidr_el2        (1513494 hits)  (op=0xd53cd042/  System Reg)
238*c17a386bSAlex Bennée  Instr: mrs x0, tpidr_el2        (1490823 hits)  (op=0xd53cd040/  System Reg)
239*c17a386bSAlex Bennée  Instr: mrs x1, sp_el0           (933793 hits)   (op=0xd5384101/  System Reg)
240*c17a386bSAlex Bennée  Instr: mrs x2, sp_el0           (699516 hits)   (op=0xd5384102/  System Reg)
241*c17a386bSAlex Bennée  Instr: mrs x4, tpidr_el2        (528437 hits)   (op=0xd53cd044/  System Reg)
242*c17a386bSAlex Bennée  Instr: mrs x30, ttbr1_el1       (480776 hits)   (op=0xd538203e/  System Reg)
243*c17a386bSAlex Bennée  Instr: msr ttbr1_el1, x30       (480713 hits)   (op=0xd518203e/  System Reg)
244*c17a386bSAlex Bennée  Instr: msr vbar_el1, x30        (480671 hits)   (op=0xd518c01e/  System Reg)
245*c17a386bSAlex Bennée  ...
246*c17a386bSAlex Bennée
247*c17a386bSAlex BennéeTo find the argument shorthand for the class you need to examine the
248*c17a386bSAlex Bennéesource code of the plugin at the moment, specifically the `*opt`
249*c17a386bSAlex Bennéeargument in the InsnClassExecCount tables.
250*c17a386bSAlex Bennée
251*c17a386bSAlex Bennée- contrib/plugins/lockstep.c
252*c17a386bSAlex Bennée
253*c17a386bSAlex BennéeThis is a debugging tool for developers who want to find out when and
254*c17a386bSAlex Bennéewhere execution diverges after a subtle change to TCG code generation.
255*c17a386bSAlex BennéeIt is not an exact science and results are likely to be mixed once
256*c17a386bSAlex Bennéeasynchronous events are introduced. While the use of -icount can
257*c17a386bSAlex Bennéeintroduce determinism to the execution flow it doesn't always follow
258*c17a386bSAlex Bennéethe translation sequence will be exactly the same. Typically this is
259*c17a386bSAlex Bennéecaused by a timer firing to service the GUI causing a block to end
260*c17a386bSAlex Bennéeearly. However in some cases it has proved to be useful in pointing
261*c17a386bSAlex Bennéepeople at roughly where execution diverges. The only argument you need
262*c17a386bSAlex Bennéefor the plugin is a path for the socket the two instances will
263*c17a386bSAlex Bennéecommunicate over::
264*c17a386bSAlex Bennée
265*c17a386bSAlex Bennée
266*c17a386bSAlex Bennée  ./sparc-softmmu/qemu-system-sparc -monitor none -parallel none \
267*c17a386bSAlex Bennée    -net none -M SS-20 -m 256 -kernel day11/zImage.elf \
268*c17a386bSAlex Bennée    -plugin ./contrib/plugins/liblockstep.so,arg=lockstep-sparc.sock \
269*c17a386bSAlex Bennée  -d plugin,nochain
270*c17a386bSAlex Bennée
271*c17a386bSAlex Bennéewhich will eventually report::
272*c17a386bSAlex Bennée
273*c17a386bSAlex Bennée  qemu-system-sparc: warning: nic lance.0 has no peer
274*c17a386bSAlex Bennée  @ 0x000000ffd06678 vs 0x000000ffd001e0 (2/1 since last)
275*c17a386bSAlex Bennée  @ 0x000000ffd07d9c vs 0x000000ffd06678 (3/1 since last)
276*c17a386bSAlex Bennée  Δ insn_count @ 0x000000ffd07d9c (809900609) vs 0x000000ffd06678 (809900612)
277*c17a386bSAlex Bennée    previously @ 0x000000ffd06678/10 (809900609 insns)
278*c17a386bSAlex Bennée    previously @ 0x000000ffd001e0/4 (809900599 insns)
279*c17a386bSAlex Bennée    previously @ 0x000000ffd080ac/2 (809900595 insns)
280*c17a386bSAlex Bennée    previously @ 0x000000ffd08098/5 (809900593 insns)
281*c17a386bSAlex Bennée    previously @ 0x000000ffd080c0/1 (809900588 insns)
282*c17a386bSAlex Bennée
283