qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

tcg-plugins.rst (21380B)


      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 QEMU TCG Plugins
      7 ================
      8 
      9 QEMU TCG plugins provide a way for users to run experiments taking
     10 advantage of the total system control emulation can have over a guest.
     11 It provides a mechanism for plugins to subscribe to events during
     12 translation and execution and optionally callback into the plugin
     13 during these events. TCG plugins are unable to change the system state
     14 only monitor it passively. However they can do this down to an
     15 individual instruction granularity including potentially subscribing
     16 to all load and store operations.
     17 
     18 Usage
     19 -----
     20 
     21 Any QEMU binary with TCG support has plugins enabled by default.
     22 Earlier releases needed to be explicitly enabled with::
     23 
     24   configure --enable-plugins
     25 
     26 Once built a program can be run with multiple plugins loaded each with
     27 their own arguments::
     28 
     29   $QEMU $OTHER_QEMU_ARGS \
     30       -plugin contrib/plugin/libhowvec.so,inline=on,count=hint \
     31       -plugin contrib/plugin/libhotblocks.so
     32 
     33 Arguments are plugin specific and can be used to modify their
     34 behaviour. In this case the howvec plugin is being asked to use inline
     35 ops to count and break down the hint instructions by type.
     36 
     37 Linux user-mode emulation also evaluates the environment variable
     38 ``QEMU_PLUGIN``::
     39 
     40   QEMU_PLUGIN="file=contrib/plugins/libhowvec.so,inline=on,count=hint" $QEMU
     41 
     42 Writing plugins
     43 ---------------
     44 
     45 API versioning
     46 ~~~~~~~~~~~~~~
     47 
     48 This is a new feature for QEMU and it does allow people to develop
     49 out-of-tree plugins that can be dynamically linked into a running QEMU
     50 process. However the project reserves the right to change or break the
     51 API should it need to do so. The best way to avoid this is to submit
     52 your plugin upstream so they can be updated if/when the API changes.
     53 
     54 All plugins need to declare a symbol which exports the plugin API
     55 version they were built against. This can be done simply by::
     56 
     57   QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION;
     58 
     59 The core code will refuse to load a plugin that doesn't export a
     60 ``qemu_plugin_version`` symbol or if plugin version is outside of QEMU's
     61 supported range of API versions.
     62 
     63 Additionally the ``qemu_info_t`` structure which is passed to the
     64 ``qemu_plugin_install`` method of a plugin will detail the minimum and
     65 current API versions supported by QEMU. The API version will be
     66 incremented if new APIs are added. The minimum API version will be
     67 incremented if existing APIs are changed or removed.
     68 
     69 Lifetime of the query handle
     70 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     71 
     72 Each callback provides an opaque anonymous information handle which
     73 can usually be further queried to find out information about a
     74 translation, instruction or operation. The handles themselves are only
     75 valid during the lifetime of the callback so it is important that any
     76 information that is needed is extracted during the callback and saved
     77 by the plugin.
     78 
     79 Plugin life cycle
     80 ~~~~~~~~~~~~~~~~~
     81 
     82 First the plugin is loaded and the public qemu_plugin_install function
     83 is called. The plugin will then register callbacks for various plugin
     84 events. Generally plugins will register a handler for the *atexit*
     85 if they want to dump a summary of collected information once the
     86 program/system has finished running.
     87 
     88 When a registered event occurs the plugin callback is invoked. The
     89 callbacks may provide additional information. In the case of a
     90 translation event the plugin has an option to enumerate the
     91 instructions in a block of instructions and optionally register
     92 callbacks to some or all instructions when they are executed.
     93 
     94 There is also a facility to add an inline event where code to
     95 increment a counter can be directly inlined with the translation.
     96 Currently only a simple increment is supported. This is not atomic so
     97 can miss counts. If you want absolute precision you should use a
     98 callback which can then ensure atomicity itself.
     99 
    100 Finally when QEMU exits all the registered *atexit* callbacks are
    101 invoked.
    102 
    103 Exposure of QEMU internals
    104 ~~~~~~~~~~~~~~~~~~~~~~~~~~
    105 
    106 The plugin architecture actively avoids leaking implementation details
    107 about how QEMU's translation works to the plugins. While there are
    108 conceptions such as translation time and translation blocks the
    109 details are opaque to plugins. The plugin is able to query select
    110 details of instructions and system configuration only through the
    111 exported *qemu_plugin* functions.
    112 
    113 Internals
    114 ---------
    115 
    116 Locking
    117 ~~~~~~~
    118 
    119 We have to ensure we cannot deadlock, particularly under MTTCG. For
    120 this we acquire a lock when called from plugin code. We also keep the
    121 list of callbacks under RCU so that we do not have to hold the lock
    122 when calling the callbacks. This is also for performance, since some
    123 callbacks (e.g. memory access callbacks) might be called very
    124 frequently.
    125 
    126   * A consequence of this is that we keep our own list of CPUs, so that
    127     we do not have to worry about locking order wrt cpu_list_lock.
    128   * Use a recursive lock, since we can get registration calls from
    129     callbacks.
    130 
    131 As a result registering/unregistering callbacks is "slow", since it
    132 takes a lock. But this is very infrequent; we want performance when
    133 calling (or not calling) callbacks, not when registering them. Using
    134 RCU is great for this.
    135 
    136 We support the uninstallation of a plugin at any time (e.g. from
    137 plugin callbacks). This allows plugins to remove themselves if they no
    138 longer want to instrument the code. This operation is asynchronous
    139 which means callbacks may still occur after the uninstall operation is
    140 requested. The plugin isn't completely uninstalled until the safe work
    141 has executed while all vCPUs are quiescent.
    142 
    143 Example Plugins
    144 ---------------
    145 
    146 There are a number of plugins included with QEMU and you are
    147 encouraged to contribute your own plugins plugins upstream. There is a
    148 ``contrib/plugins`` directory where they can go. There are also some
    149 basic plugins that are used to test and exercise the API during the
    150 ``make check-tcg`` target in ``tests\plugins``.
    151 
    152 - tests/plugins/empty.c
    153 
    154 Purely a test plugin for measuring the overhead of the plugins system
    155 itself. Does no instrumentation.
    156 
    157 - tests/plugins/bb.c
    158 
    159 A very basic plugin which will measure execution in course terms as
    160 each basic block is executed. By default the results are shown once
    161 execution finishes::
    162 
    163   $ qemu-aarch64 -plugin tests/plugin/libbb.so \
    164       -d plugin ./tests/tcg/aarch64-linux-user/sha1
    165   SHA1=15dd99a1991e0b3826fede3deffc1feba42278e6
    166   bb's: 2277338, insns: 158483046
    167 
    168 Behaviour can be tweaked with the following arguments:
    169 
    170  * inline=true|false
    171 
    172  Use faster inline addition of a single counter. Not per-cpu and not
    173  thread safe.
    174 
    175  * idle=true|false
    176 
    177  Dump the current execution stats whenever the guest vCPU idles
    178 
    179 - tests/plugins/insn.c
    180 
    181 This is a basic instruction level instrumentation which can count the
    182 number of instructions executed on each core/thread::
    183 
    184   $ qemu-aarch64 -plugin tests/plugin/libinsn.so \
    185       -d plugin ./tests/tcg/aarch64-linux-user/threadcount
    186   Created 10 threads
    187   Done
    188   cpu 0 insns: 46765
    189   cpu 1 insns: 3694
    190   cpu 2 insns: 3694
    191   cpu 3 insns: 2994
    192   cpu 4 insns: 1497
    193   cpu 5 insns: 1497
    194   cpu 6 insns: 1497
    195   cpu 7 insns: 1497
    196   total insns: 63135
    197 
    198 Behaviour can be tweaked with the following arguments:
    199 
    200  * inline=true|false
    201 
    202  Use faster inline addition of a single counter. Not per-cpu and not
    203  thread safe.
    204 
    205  * sizes=true|false
    206 
    207  Give a summary of the instruction sizes for the execution
    208 
    209  * match=<string>
    210 
    211  Only instrument instructions matching the string prefix. Will show
    212  some basic stats including how many instructions have executed since
    213  the last execution. For example::
    214 
    215    $ qemu-aarch64 -plugin tests/plugin/libinsn.so,match=bl \
    216        -d plugin ./tests/tcg/aarch64-linux-user/sha512-vector
    217    ...
    218    0x40069c, 'bl #0x4002b0', 10 hits, 1093 match hits, Δ+1257 since last match, 98 avg insns/match
    219    0x4006ac, 'bl #0x403690', 10 hits, 1094 match hits, Δ+47 since last match, 98 avg insns/match 
    220    0x4037fc, 'bl #0x4002b0', 18 hits, 1095 match hits, Δ+22 since last match, 98 avg insns/match 
    221    0x400720, 'bl #0x403690', 10 hits, 1096 match hits, Δ+58 since last match, 98 avg insns/match 
    222    0x4037fc, 'bl #0x4002b0', 19 hits, 1097 match hits, Δ+22 since last match, 98 avg insns/match 
    223    0x400730, 'bl #0x403690', 10 hits, 1098 match hits, Δ+33 since last match, 98 avg insns/match 
    224    0x4037ac, 'bl #0x4002b0', 12 hits, 1099 match hits, Δ+20 since last match, 98 avg insns/match 
    225    ...
    226 
    227 For more detailed execution tracing see the ``execlog`` plugin for
    228 other options.
    229 
    230 - tests/plugins/mem.c
    231 
    232 Basic instruction level memory instrumentation::
    233 
    234   $ qemu-aarch64 -plugin tests/plugin/libmem.so,inline=true \
    235       -d plugin ./tests/tcg/aarch64-linux-user/sha1
    236   SHA1=15dd99a1991e0b3826fede3deffc1feba42278e6
    237   inline mem accesses: 79525013
    238 
    239 Behaviour can be tweaked with the following arguments:
    240 
    241  * inline=true|false
    242 
    243  Use faster inline addition of a single counter. Not per-cpu and not
    244  thread safe.
    245 
    246  * callback=true|false
    247 
    248  Use callbacks on each memory instrumentation.
    249 
    250  * hwaddr=true|false
    251 
    252  Count IO accesses (only for system emulation)
    253 
    254 - tests/plugins/syscall.c
    255 
    256 A basic syscall tracing plugin. This only works for user-mode. By
    257 default it will give a summary of syscall stats at the end of the
    258 run::
    259 
    260   $ qemu-aarch64 -plugin tests/plugin/libsyscall \
    261       -d plugin ./tests/tcg/aarch64-linux-user/threadcount
    262   Created 10 threads
    263   Done
    264   syscall no.  calls  errors
    265   226          12     0
    266   99           11     11
    267   115          11     0
    268   222          11     0
    269   93           10     0
    270   220          10     0
    271   233          10     0
    272   215          8      0
    273   214          4      0
    274   134          2      0
    275   64           2      0
    276   96           1      0
    277   94           1      0
    278   80           1      0
    279   261          1      0
    280   78           1      0
    281   160          1      0
    282   135          1      0
    283 
    284 - contrib/plugins/hotblocks.c
    285 
    286 The hotblocks plugin allows you to examine the where hot paths of
    287 execution are in your program. Once the program has finished you will
    288 get a sorted list of blocks reporting the starting PC, translation
    289 count, number of instructions and execution count. This will work best
    290 with linux-user execution as system emulation tends to generate
    291 re-translations as blocks from different programs get swapped in and
    292 out of system memory.
    293 
    294 If your program is single-threaded you can use the ``inline`` option for
    295 slightly faster (but not thread safe) counters.
    296 
    297 Example::
    298 
    299   $ qemu-aarch64 \
    300     -plugin contrib/plugins/libhotblocks.so -d plugin \
    301     ./tests/tcg/aarch64-linux-user/sha1
    302   SHA1=15dd99a1991e0b3826fede3deffc1feba42278e6
    303   collected 903 entries in the hash table
    304   pc, tcount, icount, ecount
    305   0x0000000041ed10, 1, 5, 66087
    306   0x000000004002b0, 1, 4, 66087
    307   ...
    308 
    309 - contrib/plugins/hotpages.c
    310 
    311 Similar to hotblocks but this time tracks memory accesses::
    312 
    313   $ qemu-aarch64 \
    314     -plugin contrib/plugins/libhotpages.so -d plugin \
    315     ./tests/tcg/aarch64-linux-user/sha1
    316   SHA1=15dd99a1991e0b3826fede3deffc1feba42278e6
    317   Addr, RCPUs, Reads, WCPUs, Writes
    318   0x000055007fe000, 0x0001, 31747952, 0x0001, 8835161
    319   0x000055007ff000, 0x0001, 29001054, 0x0001, 8780625
    320   0x00005500800000, 0x0001, 687465, 0x0001, 335857
    321   0x0000000048b000, 0x0001, 130594, 0x0001, 355
    322   0x0000000048a000, 0x0001, 1826, 0x0001, 11
    323 
    324 The hotpages plugin can be configured using the following arguments:
    325 
    326   * sortby=reads|writes|address
    327 
    328   Log the data sorted by either the number of reads, the number of writes, or
    329   memory address. (Default: entries are sorted by the sum of reads and writes)
    330 
    331   * io=on
    332 
    333   Track IO addresses. Only relevant to full system emulation. (Default: off)
    334 
    335   * pagesize=N
    336 
    337   The page size used. (Default: N = 4096)
    338 
    339 - contrib/plugins/howvec.c
    340 
    341 This is an instruction classifier so can be used to count different
    342 types of instructions. It has a number of options to refine which get
    343 counted. You can give a value to the ``count`` argument for a class of
    344 instructions to break it down fully, so for example to see all the system
    345 registers accesses::
    346 
    347   $ qemu-system-aarch64 $(QEMU_ARGS) \
    348     -append "root=/dev/sda2 systemd.unit=benchmark.service" \
    349     -smp 4 -plugin ./contrib/plugins/libhowvec.so,count=sreg -d plugin
    350 
    351 which will lead to a sorted list after the class breakdown::
    352 
    353   Instruction Classes:
    354   Class:   UDEF                   not counted
    355   Class:   SVE                    (68 hits)
    356   Class:   PCrel addr             (47789483 hits)
    357   Class:   Add/Sub (imm)          (192817388 hits)
    358   Class:   Logical (imm)          (93852565 hits)
    359   Class:   Move Wide (imm)        (76398116 hits)
    360   Class:   Bitfield               (44706084 hits)
    361   Class:   Extract                (5499257 hits)
    362   Class:   Cond Branch (imm)      (147202932 hits)
    363   Class:   Exception Gen          (193581 hits)
    364   Class:     NOP                  not counted
    365   Class:   Hints                  (6652291 hits)
    366   Class:   Barriers               (8001661 hits)
    367   Class:   PSTATE                 (1801695 hits)
    368   Class:   System Insn            (6385349 hits)
    369   Class:   System Reg             counted individually
    370   Class:   Branch (reg)           (69497127 hits)
    371   Class:   Branch (imm)           (84393665 hits)
    372   Class:   Cmp & Branch           (110929659 hits)
    373   Class:   Tst & Branch           (44681442 hits)
    374   Class:   AdvSimd ldstmult       (736 hits)
    375   Class:   ldst excl              (9098783 hits)
    376   Class:   Load Reg (lit)         (87189424 hits)
    377   Class:   ldst noalloc pair      (3264433 hits)
    378   Class:   ldst pair              (412526434 hits)
    379   Class:   ldst reg (imm)         (314734576 hits)
    380   Class: Loads & Stores           (2117774 hits)
    381   Class: Data Proc Reg            (223519077 hits)
    382   Class: Scalar FP                (31657954 hits)
    383   Individual Instructions:
    384   Instr: mrs x0, sp_el0           (2682661 hits)  (op=0xd5384100/  System Reg)
    385   Instr: mrs x1, tpidr_el2        (1789339 hits)  (op=0xd53cd041/  System Reg)
    386   Instr: mrs x2, tpidr_el2        (1513494 hits)  (op=0xd53cd042/  System Reg)
    387   Instr: mrs x0, tpidr_el2        (1490823 hits)  (op=0xd53cd040/  System Reg)
    388   Instr: mrs x1, sp_el0           (933793 hits)   (op=0xd5384101/  System Reg)
    389   Instr: mrs x2, sp_el0           (699516 hits)   (op=0xd5384102/  System Reg)
    390   Instr: mrs x4, tpidr_el2        (528437 hits)   (op=0xd53cd044/  System Reg)
    391   Instr: mrs x30, ttbr1_el1       (480776 hits)   (op=0xd538203e/  System Reg)
    392   Instr: msr ttbr1_el1, x30       (480713 hits)   (op=0xd518203e/  System Reg)
    393   Instr: msr vbar_el1, x30        (480671 hits)   (op=0xd518c01e/  System Reg)
    394   ...
    395 
    396 To find the argument shorthand for the class you need to examine the
    397 source code of the plugin at the moment, specifically the ``*opt``
    398 argument in the InsnClassExecCount tables.
    399 
    400 - contrib/plugins/lockstep.c
    401 
    402 This is a debugging tool for developers who want to find out when and
    403 where execution diverges after a subtle change to TCG code generation.
    404 It is not an exact science and results are likely to be mixed once
    405 asynchronous events are introduced. While the use of -icount can
    406 introduce determinism to the execution flow it doesn't always follow
    407 the translation sequence will be exactly the same. Typically this is
    408 caused by a timer firing to service the GUI causing a block to end
    409 early. However in some cases it has proved to be useful in pointing
    410 people at roughly where execution diverges. The only argument you need
    411 for the plugin is a path for the socket the two instances will
    412 communicate over::
    413 
    414 
    415   $ qemu-system-sparc -monitor none -parallel none \
    416     -net none -M SS-20 -m 256 -kernel day11/zImage.elf \
    417     -plugin ./contrib/plugins/liblockstep.so,sockpath=lockstep-sparc.sock \
    418     -d plugin,nochain
    419 
    420 which will eventually report::
    421 
    422   qemu-system-sparc: warning: nic lance.0 has no peer
    423   @ 0x000000ffd06678 vs 0x000000ffd001e0 (2/1 since last)
    424   @ 0x000000ffd07d9c vs 0x000000ffd06678 (3/1 since last)
    425   Δ insn_count @ 0x000000ffd07d9c (809900609) vs 0x000000ffd06678 (809900612)
    426     previously @ 0x000000ffd06678/10 (809900609 insns)
    427     previously @ 0x000000ffd001e0/4 (809900599 insns)
    428     previously @ 0x000000ffd080ac/2 (809900595 insns)
    429     previously @ 0x000000ffd08098/5 (809900593 insns)
    430     previously @ 0x000000ffd080c0/1 (809900588 insns)
    431 
    432 - contrib/plugins/hwprofile.c
    433 
    434 The hwprofile tool can only be used with system emulation and allows
    435 the user to see what hardware is accessed how often. It has a number of options:
    436 
    437  * track=read or track=write
    438 
    439  By default the plugin tracks both reads and writes. You can use one
    440  of these options to limit the tracking to just one class of accesses.
    441 
    442  * source
    443 
    444  Will include a detailed break down of what the guest PC that made the
    445  access was. Not compatible with the pattern option. Example output::
    446 
    447    cirrus-low-memory @ 0xfffffd00000a0000
    448     pc:fffffc0000005cdc, 1, 256
    449     pc:fffffc0000005ce8, 1, 256
    450     pc:fffffc0000005cec, 1, 256
    451 
    452  * pattern
    453 
    454  Instead break down the accesses based on the offset into the HW
    455  region. This can be useful for seeing the most used registers of a
    456  device. Example output::
    457 
    458     pci0-conf @ 0xfffffd01fe000000
    459       off:00000004, 1, 1
    460       off:00000010, 1, 3
    461       off:00000014, 1, 3
    462       off:00000018, 1, 2
    463       off:0000001c, 1, 2
    464       off:00000020, 1, 2
    465       ...
    466 
    467 - contrib/plugins/execlog.c
    468 
    469 The execlog tool traces executed instructions with memory access. It can be used
    470 for debugging and security analysis purposes.
    471 Please be aware that this will generate a lot of output.
    472 
    473 The plugin needs default argument::
    474 
    475   $ qemu-system-arm $(QEMU_ARGS) \
    476     -plugin ./contrib/plugins/libexeclog.so -d plugin
    477 
    478 which will output an execution trace following this structure::
    479 
    480   # vCPU, vAddr, opcode, disassembly[, load/store, memory addr, device]...
    481   0, 0xa12, 0xf8012400, "movs r4, #0"
    482   0, 0xa14, 0xf87f42b4, "cmp r4, r6"
    483   0, 0xa16, 0xd206, "bhs #0xa26"
    484   0, 0xa18, 0xfff94803, "ldr r0, [pc, #0xc]", load, 0x00010a28, RAM
    485   0, 0xa1a, 0xf989f000, "bl #0xd30"
    486   0, 0xd30, 0xfff9b510, "push {r4, lr}", store, 0x20003ee0, RAM, store, 0x20003ee4, RAM
    487   0, 0xd32, 0xf9893014, "adds r0, #0x14"
    488   0, 0xd34, 0xf9c8f000, "bl #0x10c8"
    489   0, 0x10c8, 0xfff96c43, "ldr r3, [r0, #0x44]", load, 0x200000e4, RAM
    490 
    491 the output can be filtered to only track certain instructions or
    492 addresses using the ``ifilter`` or ``afilter`` options. You can stack the
    493 arguments if required::
    494 
    495   $ qemu-system-arm $(QEMU_ARGS) \
    496     -plugin ./contrib/plugins/libexeclog.so,ifilter=st1w,afilter=0x40001808 -d plugin
    497 
    498 - contrib/plugins/cache.c
    499 
    500 Cache modelling plugin that measures the performance of a given L1 cache
    501 configuration, and optionally a unified L2 per-core cache when a given working
    502 set is run::
    503 
    504   $ qemu-x86_64 -plugin ./contrib/plugins/libcache.so \
    505       -d plugin -D cache.log ./tests/tcg/x86_64-linux-user/float_convs
    506 
    507 will report the following::
    508 
    509     core #, data accesses, data misses, dmiss rate, insn accesses, insn misses, imiss rate
    510     0       996695         508             0.0510%  2642799        18617           0.7044%
    511 
    512     address, data misses, instruction
    513     0x424f1e (_int_malloc), 109, movq %rax, 8(%rcx)
    514     0x41f395 (_IO_default_xsputn), 49, movb %dl, (%rdi, %rax)
    515     0x42584d (ptmalloc_init.part.0), 33, movaps %xmm0, (%rax)
    516     0x454d48 (__tunables_init), 20, cmpb $0, (%r8)
    517     ...
    518 
    519     address, fetch misses, instruction
    520     0x4160a0 (__vfprintf_internal), 744, movl $1, %ebx
    521     0x41f0a0 (_IO_setb), 744, endbr64
    522     0x415882 (__vfprintf_internal), 744, movq %r12, %rdi
    523     0x4268a0 (__malloc), 696, andq $0xfffffffffffffff0, %rax
    524     ...
    525 
    526 The plugin has a number of arguments, all of them are optional:
    527 
    528   * limit=N
    529 
    530   Print top N icache and dcache thrashing instructions along with their
    531   address, number of misses, and its disassembly. (default: 32)
    532 
    533   * icachesize=N
    534   * iblksize=B
    535   * iassoc=A
    536 
    537   Instruction cache configuration arguments. They specify the cache size, block
    538   size, and associativity of the instruction cache, respectively.
    539   (default: N = 16384, B = 64, A = 8)
    540 
    541   * dcachesize=N
    542   * dblksize=B
    543   * dassoc=A
    544 
    545   Data cache configuration arguments. They specify the cache size, block size,
    546   and associativity of the data cache, respectively.
    547   (default: N = 16384, B = 64, A = 8)
    548 
    549   * evict=POLICY
    550 
    551   Sets the eviction policy to POLICY. Available policies are: :code:`lru`,
    552   :code:`fifo`, and :code:`rand`. The plugin will use the specified policy for
    553   both instruction and data caches. (default: POLICY = :code:`lru`)
    554 
    555   * cores=N
    556 
    557   Sets the number of cores for which we maintain separate icache and dcache.
    558   (default: for linux-user, N = 1, for full system emulation: N = cores
    559   available to guest)
    560 
    561   * l2=on
    562 
    563   Simulates a unified L2 cache (stores blocks for both instructions and data)
    564   using the default L2 configuration (cache size = 2MB, associativity = 16-way,
    565   block size = 64B).
    566 
    567   * l2cachesize=N
    568   * l2blksize=B
    569   * l2assoc=A
    570 
    571   L2 cache configuration arguments. They specify the cache size, block size, and
    572   associativity of the L2 cache, respectively. Setting any of the L2
    573   configuration arguments implies ``l2=on``.
    574   (default: N = 2097152 (2MB), B = 64, A = 16)
    575 
    576 API
    577 ---
    578 
    579 The following API is generated from the inline documentation in
    580 ``include/qemu/qemu-plugin.h``. Please ensure any updates to the API
    581 include the full kernel-doc annotations.
    582 
    583 .. kernel-doc:: include/qemu/qemu-plugin.h
    584