1 #include <l4/sys/compiler.h>
3 #include "../configuration"
5 #define MSG() DEBUGf(Romain::Log::Swifi)
8 Romain::SWIFIObserver *
9 Romain::SWIFIObserver::Create()
10 { return new SWIFIPriv(); }
13 void Romain::SWIFIPriv::status() const { }
16 Romain::SWIFIPriv::startup_notify(Romain::App_instance *i,
18 Romain::Thread_group *tg,
22 * We only inject faults in replica 0
28 _breakpoint->activate(i, a);
29 MSG() << "set SWIFI bp";
34 Romain::Observer::ObserverReturnVal
35 Romain::SWIFIPriv::notify(Romain::App_instance *i,
36 Romain::App_thread *t,
37 Romain::Thread_group *tg,
40 Romain::Observer::ObserverReturnVal ret = Romain::Observer::Invalid;
42 * Faults are injected into replica 0 only. All other replicas
43 * simply get told to wait until the fault injector is done.
47 return Romain::Observer::Finished_wait;
50 if (_breakpoint && _breakpoint->was_hit(t)) {
51 INFO() << "\033[36m======== SWIFI: start (part 1) ========\033[0m";
52 _breakpoint->deactivate(i,a);
55 * Faults are injected into replica 0 only. All other replicas
56 * simply get told to wait until the fault injector is done.
59 return Romain::Observer::Finished_wait;
62 t->print_vcpu_state();
65 case GPR: _flipper = new GPRFlipEmulator(t->vcpu(), a, i);
66 MSG() << "GPRFlipped";
67 // GPR flipping does not use second phase
68 ret = Romain::Observer::Finished_wakeup;
70 case INSTR: _flipper = new InstrFlipEmulator(t->vcpu(), a, i);
71 ret = Romain::Observer::Finished_step;
73 case ALU: _flipper = new ALUFlipEmulator(t->vcpu(), a, i);
74 ret = Romain::Observer::Finished_step;
76 case RAT: _flipper = new RATFlipEmulator(t->vcpu(), a, i);
77 ret = Romain::Observer::Finished_step;
79 case MEM: _flipper = new MemFlipEmulator(t->vcpu(), a, i);
80 ret = Romain::Observer::Finished_step;
83 ERROR() << "Unhandled injection type: " << _flags;
84 return Romain::Observer::Ignored;
87 INFO() << "\033[36m======== SWIFI: end (part 1) ========\033[0m";
91 } else if ((t->vcpu()->r()->trapno == 1) ||
92 ((t->vcpu()->r()->trapno == 3) && (a->in_trampoline(t->vcpu()->r()->ip))))
94 MSG() << "\033[36m======== SWIFI: start (part 2) ========\033[0m";
101 MSG() << "\033[36m======== SWIFI: end (part 2) ========\033[0m";
102 return Romain::Observer::Finished_wakeup;
103 case GPR: // not for us in this case
105 if (_flipper) delete _flipper;
110 MSG() << "\033[36m======== SWIFI: end (part 2) ========\033[0m";
111 return Romain::Observer::Ignored;
115 void Romain::SWIFIPriv::flipper_trap1(Romain::App_thread *t)
117 MSG() << std::hex << t->vcpu()->r()->ip << " " << _flipper->prev_eip()
118 << " + " << _flipper->ilen();
122 t->vcpu()->r()->ip = _flipper->next_eip();
123 t->vcpu()->r()->flags &= ~TrapFlag;
124 t->print_vcpu_state();
130 void Romain::SWIFIPriv::flipper_trap3(Romain::App_thread *t, bool step)
132 if (_flipper->flip()) {
133 t->vcpu()->r()->flags |= TrapFlag;
135 t->print_vcpu_state();
139 Romain::SWIFIPriv::SWIFIPriv()
140 : _breakpoint(0), _flags(None), _flipper(0)
143 gettimeofday(&tv, 0);
146 l4_addr_t target = ConfigIntValue("swifi:target");
147 char const* inject = ConfigStringValue("swifi:inject");
148 if (target && inject) {
149 MSG() << "target: " << std::hex << target;
150 MSG() << " inj: " << inject;
152 _breakpoint = new Breakpoint(target);
153 if (strcmp(inject, "instr") == 0) {
155 } else if (strcmp(inject, "gpr") == 0) {
157 } else if (strcmp(inject, "alu") == 0) {
159 } else if (strcmp(inject, "rat") == 0) {
161 } else if (strcmp(inject, "mem") == 0) {