cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

qgraph.h (14758B)


      1/*
      2 * libqos driver framework
      3 *
      4 * Copyright (c) 2018 Emanuele Giuseppe Esposito <e.emanuelegiuseppe@gmail.com>
      5 *
      6 * This library is free software; you can redistribute it and/or
      7 * modify it under the terms of the GNU Lesser General Public
      8 * License version 2.1 as published by the Free Software Foundation.
      9 *
     10 * This library is distributed in the hope that it will be useful,
     11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     13 * Lesser General Public License for more details.
     14 *
     15 * You should have received a copy of the GNU Lesser General Public
     16 * License along with this library; if not, see <http://www.gnu.org/licenses/>
     17 */
     18
     19#ifndef QGRAPH_H
     20#define QGRAPH_H
     21
     22#include <gmodule.h>
     23#include "qemu/module.h"
     24#include "malloc.h"
     25
     26/* maximum path length */
     27#define QOS_PATH_MAX_ELEMENT_SIZE 50
     28
     29typedef struct QOSGraphObject QOSGraphObject;
     30typedef struct QOSGraphNode QOSGraphNode;
     31typedef struct QOSGraphEdge QOSGraphEdge;
     32typedef struct QOSGraphEdgeOptions QOSGraphEdgeOptions;
     33typedef struct QOSGraphTestOptions QOSGraphTestOptions;
     34
     35/* Constructor for drivers, machines and test */
     36typedef void *(*QOSCreateDriverFunc) (void *parent, QGuestAllocator *alloc,
     37                                      void *addr);
     38typedef void *(*QOSCreateMachineFunc) (QTestState *qts);
     39typedef void (*QOSTestFunc) (void *parent, void *arg, QGuestAllocator *alloc);
     40
     41/* QOSGraphObject functions */
     42typedef void *(*QOSGetDriver) (void *object, const char *interface);
     43typedef QOSGraphObject *(*QOSGetDevice) (void *object, const char *name);
     44typedef void (*QOSDestructorFunc) (QOSGraphObject *object);
     45typedef void (*QOSStartFunct) (QOSGraphObject *object);
     46
     47/* Test options functions */
     48typedef void *(*QOSBeforeTest) (GString *cmd_line, void *arg);
     49
     50/**
     51 * struct QOSGraphEdgeOptions:
     52 * Edge options to be passed to the contains/consumes \*_args function.
     53 * @arg: optional arg that will be used by dest edge
     54 * @size_arg: @arg size that will be used by dest edge
     55 * @extra_device_opts: optional additional command line for dest
     56 *                     edge, used to add additional attributes
     57 *                     *after* the node command line, the
     58 *                     framework automatically prepends ","
     59 *                     to this argument.
     60 * @before_cmd_line: optional additional command line for dest
     61 *                   edge, used to add additional attributes
     62 *                   *before* the node command line, usually
     63 *                   other non-node represented commands,
     64 *                   like "-fdsev synt"
     65 * @after_cmd_line: optional extra command line to be added
     66 *                  after the device command. This option
     67 *                  is used to add other devices
     68 *                  command line that depend on current node.
     69 *                  Automatically prepends " " to this argument
     70 * @edge_name: optional edge to differentiate multiple
     71 *             devices with same node name
     72 */
     73struct QOSGraphEdgeOptions {
     74    void *arg;
     75    uint32_t size_arg;
     76    const char *extra_device_opts;
     77    const char *before_cmd_line;
     78    const char *after_cmd_line;
     79    const char *edge_name;
     80};
     81
     82/**
     83 * struct QOSGraphTestOptions:
     84 * Test options to be passed to the test functions.
     85 * @edge: edge arguments that will be used by test.
     86 *        Note that test *does not* use edge_name,
     87 *        and uses instead arg and size_arg as
     88 *        data arg for its test function.
     89 * @arg:  if @before is non-NULL, pass @arg there.
     90 *        Otherwise pass it to the test function.
     91 * @before: executed before the test. Used to add
     92 *          additional parameters to the command line
     93 *          and modify the argument to the test function.
     94 * @subprocess: run the test in a subprocess.
     95 */
     96struct QOSGraphTestOptions {
     97    QOSGraphEdgeOptions edge;
     98    void *arg;
     99    QOSBeforeTest before;
    100    bool subprocess;
    101};
    102
    103/**
    104 * struct QOSGraphObject:
    105 * Each driver, test or machine of this framework will have a
    106 * QOSGraphObject as first field.
    107 *
    108 * This set of functions offered by QOSGraphObject are executed
    109 * in different stages of the framework:
    110 * @get_driver: see @get_device
    111 * @get_device: Once a machine-to-test path has been
    112 *              found, the framework traverses it again and allocates all the
    113 *              nodes, using the provided constructor. To satisfy their
    114 *              relations, i.e. for produces or contains, where a struct
    115 *              constructor needs an external parameter represented by the
    116 *              previous node, the framework will call
    117 *              @get_device (for contains) or @get_driver (for produces),
    118 *              depending on the edge type, passing them the name of the next
    119 *              node to be taken and getting from them the corresponding
    120 *              pointer to the actual structure of the next node to
    121 *              be used in the path.
    122 * @start_hw: This function is executed after all the path objects
    123 *            have been allocated, but before the test is run. It starts the
    124 *            hw, setting the initial configurations (\*_device_enable) and
    125 *            making it ready for the test.
    126 * @destructor: Opposite to the node constructor, destroys the object.
    127 *              This function is called after the test has been executed, and
    128 *              performs a complete cleanup of each node allocated field.
    129 *              In case no constructor is provided, no destructor will be
    130 *              called.
    131 * @free: free the memory associated to the QOSGraphObject and its contained
    132 *        children
    133 */
    134struct QOSGraphObject {
    135    QOSGetDriver get_driver;
    136    QOSGetDevice get_device;
    137    QOSStartFunct start_hw;
    138    QOSDestructorFunc destructor;
    139    GDestroyNotify free;
    140};
    141
    142/**
    143 * qos_graph_init(): initialize the framework, creates two hash
    144 * tables: one for the nodes and another for the edges.
    145 */
    146void qos_graph_init(void);
    147
    148/**
    149 * qos_graph_destroy(): deallocates all the hash tables,
    150 * freeing all nodes and edges.
    151 */
    152void qos_graph_destroy(void);
    153
    154/**
    155 * qos_node_destroy(): removes and frees a node from the
    156 * nodes hash table.
    157 * @key: Name of the node
    158 */
    159void qos_node_destroy(void *key);
    160
    161/**
    162 * qos_edge_destroy(): removes and frees an edge from the
    163 * edges hash table.
    164 * @key: Name of the node
    165 */
    166void qos_edge_destroy(void *key);
    167
    168/**
    169 * qos_add_test(): adds a test node @name to the nodes hash table.
    170 * @name: Name of the test
    171 * @interface: Name of the interface node it consumes
    172 * @test_func: Actual test to perform
    173 * @opts: Facultative options (see %QOSGraphTestOptions)
    174 *
    175 * The test will consume a @interface node, and once the
    176 * graph walking algorithm has found it, the @test_func will be
    177 * executed. It also has the possibility to
    178 * add an optional @opts (see %QOSGraphTestOptions).
    179 *
    180 * For tests, opts->edge.arg and size_arg represent the arg to pass
    181 * to @test_func
    182 */
    183void qos_add_test(const char *name, const char *interface,
    184                  QOSTestFunc test_func,
    185                  QOSGraphTestOptions *opts);
    186
    187/**
    188 * qos_node_create_machine(): creates the machine @name and
    189 * adds it to the node hash table.
    190 * @name: Name of the machine
    191 * @function: Machine constructor
    192 *
    193 * This node will be of type QNODE_MACHINE and have @function
    194 * as constructor
    195 */
    196void qos_node_create_machine(const char *name, QOSCreateMachineFunc function);
    197
    198/**
    199 * qos_node_create_machine_args(): same as qos_node_create_machine,
    200 * but with the possibility to add an optional ", @opts" after -M machine
    201 * command line.
    202 * @name: Name of the machine
    203 * @function: Machine constructor
    204 * @opts: Optional additional command line
    205 */
    206void qos_node_create_machine_args(const char *name,
    207                                  QOSCreateMachineFunc function,
    208                                  const char *opts);
    209
    210/**
    211 * qos_node_create_driver(): creates the driver @name and
    212 * adds it to the node hash table.
    213 * @name: Name of the driver
    214 * @function: Driver constructor
    215 *
    216 * This node will be of type QNODE_DRIVER and have @function
    217 * as constructor
    218 */
    219void qos_node_create_driver(const char *name, QOSCreateDriverFunc function);
    220
    221/**
    222 * qos_node_create_driver_named(): behaves as qos_node_create_driver() with the
    223 * extension of allowing to specify a different node name vs. associated QEMU
    224 * device name.
    225 * @name: Custom, unique name of the node to be created
    226 * @qemu_name: Actual (official) QEMU driver name the node shall be
    227 * associated with
    228 * @function: Driver constructor
    229 *
    230 * Use this function instead of qos_node_create_driver() if you need to create
    231 * several instances of the same QEMU device. You are free to choose a custom
    232 * node name, however the chosen node name must always be unique.
    233 */
    234void qos_node_create_driver_named(const char *name, const char *qemu_name,
    235                                  QOSCreateDriverFunc function);
    236
    237/**
    238 * qos_node_contains(): creates one or more edges of type QEDGE_CONTAINS
    239 * and adds them to the edge list mapped to @container in the
    240 * edge hash table.
    241 * @container: Source node that "contains"
    242 * @contained: Destination node that "is contained"
    243 * @opts: Facultative options (see %QOSGraphEdgeOptions)
    244 *
    245 * The edges will have @container as source and @contained as destination.
    246 *
    247 * If @opts is NULL, a single edge will be added with no options.
    248 * If @opts is non-NULL, the arguments after @contained represent a
    249 * NULL-terminated list of %QOSGraphEdgeOptions structs, and an
    250 * edge will be added for each of them.
    251 *
    252 * This function can be useful when there are multiple devices
    253 * with the same node name contained in a machine/other node
    254 *
    255 * For example, if ``arm/raspi2b`` contains 2 ``generic-sdhci``
    256 * devices, the right commands will be:
    257 *
    258 * .. code::
    259 *
    260 *    qos_node_create_machine("arm/raspi2b");
    261 *    qos_node_create_driver("generic-sdhci", constructor);
    262 *    // assume rest of the fields are set NULL
    263 *    QOSGraphEdgeOptions op1 = { .edge_name = "emmc" };
    264 *    QOSGraphEdgeOptions op2 = { .edge_name = "sdcard" };
    265 *    qos_node_contains("arm/raspi2b", "generic-sdhci", &op1, &op2, NULL);
    266 *
    267 * Of course this also requires that the @container's get_device function
    268 * should implement a case for "emmc" and "sdcard".
    269 *
    270 * For contains, op1.arg and op1.size_arg represent the arg to pass
    271 * to @contained constructor to properly initialize it.
    272 */
    273void qos_node_contains(const char *container, const char *contained,
    274                       QOSGraphEdgeOptions *opts, ...);
    275
    276/**
    277 * qos_node_produces(): creates an edge of type QEDGE_PRODUCES and
    278 * adds it to the edge list mapped to @producer in the
    279 * edge hash table.
    280 * @producer: Source node that "produces"
    281 * @interface: Interface node that "is produced"
    282 *
    283 * This edge will have @producer as source and @interface as destination.
    284 */
    285void qos_node_produces(const char *producer, const char *interface);
    286
    287/**
    288 * qos_node_consumes():  creates an edge of type QEDGE_CONSUMED_BY and
    289 * adds it to the edge list mapped to @interface in the
    290 * edge hash table.
    291 * @consumer: Node that "consumes"
    292 * @interface: Interface node that "is consumed by"
    293 * @opts: Facultative options (see %QOSGraphEdgeOptions)
    294 *
    295 * This edge will have @interface as source and @consumer as destination.
    296 * It also has the possibility to add an optional @opts
    297 * (see %QOSGraphEdgeOptions)
    298 */
    299void qos_node_consumes(const char *consumer, const char *interface,
    300                       QOSGraphEdgeOptions *opts);
    301
    302/**
    303 * qos_invalidate_command_line(): invalidates current command line, so that
    304 * qgraph framework cannot try to cache the current command line and
    305 * forces QEMU to restart.
    306 */
    307void qos_invalidate_command_line(void);
    308
    309/**
    310 * qos_get_current_command_line(): return the command line required by the
    311 * machine and driver objects.  This is the same string that was passed to
    312 * the test's "before" callback, if any.
    313 */
    314const char *qos_get_current_command_line(void);
    315
    316/**
    317 * qos_allocate_objects():
    318 * @qts: The #QTestState that will be referred to by the machine object.
    319 * @p_alloc: Where to store the allocator for the machine object, or %NULL.
    320 *
    321 * Allocate driver objects for the current test
    322 * path, but relative to the QTestState @qts.
    323 *
    324 * Returns a test object just like the one that was passed to
    325 * the test function, but relative to @qts.
    326 */
    327void *qos_allocate_objects(QTestState *qts, QGuestAllocator **p_alloc);
    328
    329/**
    330 * qos_object_destroy(): calls the destructor for @obj
    331 * @obj: A #QOSGraphObject to destroy
    332 */
    333void qos_object_destroy(QOSGraphObject *obj);
    334
    335/**
    336 * qos_object_queue_destroy(): queue the destructor for @obj so that it is
    337 * called at the end of the test
    338 * @obj: A #QOSGraphObject to destroy
    339 */
    340void qos_object_queue_destroy(QOSGraphObject *obj);
    341
    342/**
    343 * qos_object_start_hw(): calls the start_hw function for @obj
    344 * @obj: A #QOSGraphObject containing the start_hw function
    345 */
    346void qos_object_start_hw(QOSGraphObject *obj);
    347
    348/**
    349 * qos_machine_new(): instantiate a new machine node
    350 * @node: Machine node to be instantiated
    351 * @qts: A #QTestState that will be referred to by the machine object.
    352 *
    353 * Returns a machine object.
    354 */
    355QOSGraphObject *qos_machine_new(QOSGraphNode *node, QTestState *qts);
    356
    357/**
    358 * qos_machine_new(): instantiate a new driver node
    359 * @node: A driver node to be instantiated
    360 * @parent: A #QOSGraphObject to be consumed by the new driver node
    361 * @alloc: An allocator to be used by the new driver node.
    362 * @arg: The argument for the consumed-by edge to @node.
    363 *
    364 * Calls the constructor for the driver object.
    365 */
    366QOSGraphObject *qos_driver_new(QOSGraphNode *node, QOSGraphObject *parent,
    367                               QGuestAllocator *alloc, void *arg);
    368
    369/**
    370 * qos_dump_graph(): prints all currently existing nodes and
    371 * edges to stdout. Just for debugging purposes.
    372 *
    373 * All qtests add themselves to the overall qos graph by calling qgraph
    374 * functions that add device nodes and edges between the individual graph
    375 * nodes for tests. As the actual graph is assmbled at runtime by the qos
    376 * subsystem, it is sometimes not obvious how the overall graph looks like.
    377 * E.g. when writing new tests it may happen that those new tests are simply
    378 * ignored by the qtest framework.
    379 *
    380 * This function allows to identify problems in the created qgraph. Keep in
    381 * mind: only tests with a path down from the actual test case node (leaf) up
    382 * to the graph's root node are actually executed by the qtest framework. And
    383 * the qtest framework uses QMP to automatically check which QEMU drivers are
    384 * actually currently available, and accordingly qos marks certain pathes as
    385 * 'unavailable' in such cases (e.g. when QEMU was compiled without support for
    386 * a certain feature).
    387 */
    388void qos_dump_graph(void);
    389
    390#endif