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