qemu/docs/fault_injection.txt
<<
>>
Prefs
   1                           Fault Injection Framework
   2                           =========================
   3
   4Introduction
   5------------
   6
   7The fault injection framework allows users to write python scripts to inject
   8faults through the QMP (QEMU Machine Protocol) during execution.
   9
  10Basically it's composed of a Python API which makes some QMP commands easy to
  11send to the machine:
  12  * read/write a memory location from a CPU view.
  13  * set a GPIO line.
  14  * get/set a QOM property.
  15
  16In addition it allows the Python script to be notified back by QEMU so it can
  17do any of the previous commands at a given time.
  18
  19Today the available function in the API are the following:
  20  * notify(time_ns, cb)
  21  * inject_write(address, value, size, cpu)
  22  * read(address, size, cpu)
  23  * get_qom_property(path, property)
  24  * set_qom_property(path, property, value)
  25  * set_gpio(path, gpio, num, value)
  26
  27Empty Example
  28-------------
  29
  30This is an empty example to begin:
  31
  32import fault_injection
  33import sys
  34
  35framework = None
  36
  37def main():
  38    # The injection framework will parse the command line automatically
  39    # (eg: the qmp socket/port.. etc)
  40    sys.stdout.write('Fault Injection Example\n')
  41    global framework
  42    framework = fault_injection.FaultInjectionFramework(sys.argv[1])
  43
  44    framework.run()
  45    sys.exit(1)
  46
  47if __name__ == '__main__':
  48    main()
  49
  50To run the example just save the example in `script/qmp/example_scenario`
  51Run qemu with the additional arguments: `-S -qmp unix:/path/to/qmp-sock,server`
  52in order to wait for a qmp connection and stop the QEMU machine.
  53Run the example with: `./example_scenario /path/to/qmp-sock`
  54
  55It will start the simulation inside QEMU and do nothing else.
  56
  57Adding a callback at a given time
  58---------------------------------
  59
  60As described above a callback can be added in the python scenario.
  61For example we can create the following callback which write 0xDEADBEEF @0 with
  62a size of 4 from cpu 0 and then reads it back:
  63
  64def write_mem_callback():
  65    print 'write_mem_callback()'
  66    framework.write(0x0, 0xDEADBEEF, 4, 0)
  67    val = framework.read(0x0, 4, 0)
  68    print 'value read: 0x%8.8X' %val
  69
  70Then we can notify it in the main function before framework.run():
  71`framework.notify(1000000000, write_mem_callback)`
  72
  73The script works as expected:
  74
  75write_mem_callback()
  76value read: 0xDEADBEEF
  77
  78Using the python interpreter
  79----------------------------
  80
  81The Python interpreter can be used to send the command above:
  82For example to set the vinithi bit to 1 for the /rpu_cpu@0 the following
  83commands can be done in the script/qmp directory:
  84
  85$ python
  86>>> import fault_injection
  87>>> inj=fault_injection.FaultInjectionFramework("../../qmp-sock", 0)
  88Connected to QEMU 2.2.50
  89
  90>>> inj.help()
  91
  92Fault Injection Framework Commands
  93==================================
  94
  95cont()
  96 * Resume the simulation when the Virtual Machine is stopped.
  97
  98run()
  99 * Start the simulation when the notify are set.
 100
 101notify(time_ns, cb)
 102 * Notify the callback cb in guest time time_ns.
 103
 104write(address, value, size, cpu)
 105 * Write @value of size @size at @address from @cpu.
 106 * @cpu can be either a qom path or the cpu id.
 107
 108read(address, size, cpu)
 109 * Read a value of size @size at @address from @cpu.
 110 * @cpu can be either a qom path or the cpu id.
 111 * Returns the value.
 112
 113get_qom_property(path, property)
 114 * Get a qom property.
 115 * Returns the qom property named @property in @path.
 116
 117set_qom_property(path, property, value)
 118 * Set the property named @property in @path with @value.
 119
 120set_gpio(path, gpio, num, value)
 121 * Set the gpio named @gpio number @num in @path with the @val.
 122 * @val is a boolean.
 123
 124>>> inj.set_gpio('/rpu_cpu@0', 'vinithi', 0, 1)
 125
 126Notes
 127-----
 128
 129The user can turn debug information on by passing a level to the framework
 130constructor eg:
 131"framework = fault_injection.FaultInjectionFramework(1)" will print timed traces
 132such as write or read.
 133"framework = fault_injection.FaultInjectionFramework(2)" will print the QMP
 134commands as well.
 135
 136