]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/plr/server/src/fault_observers
update
[l4.git] / l4 / pkg / plr / server / src / fault_observers
1 // vim: ft=cpp
2 #pragma once
3
4 /*
5  * fault_observer --
6  *
7  *    Definition of the generic fault handling class as well as
8  *    specific sub-classes.
9  *
10  * (c) 2011-2013 Björn Döbel <doebel@os.inf.tu-dresden.de>,
11  *     economic rights: Technische Universität Dresden (Germany)
12  * This file is part of TUD:OS and distributed under the terms of the
13  * GNU General Public License 2.
14  * Please see the COPYING-GPL-2 file for details.
15  */
16
17 #include "app"
18 #include "log"
19 #include "exceptions"
20 //#include "emulation"
21 #include <l4/sys/kdebug.h>
22
23 namespace Romain
24 {
25         class App_model;
26         class App_instance;
27         class App_thread;
28         struct Thread_group;
29
30 /* Make this a macro because every sub-class will have to define
31  * these two virtual functions.
32  */
33 #define DECLARE_OBSERVER(_name_) \
34                 public: \
35                         virtual void startup_notify(Romain::App_instance *i, \
36                                                     Romain::App_thread *t, \
37                                                     Romain::Thread_group *tg, \
38                                                     Romain::App_model *a); \
39                         virtual ObserverReturnVal notify(Romain::App_instance *i, \
40                                                          Romain::App_thread *t, \
41                                                          Romain::Thread_group *tg, \
42                                                          Romain::App_model *a); \
43                         virtual char const * name() const { return _name_; } \
44                         virtual void status() const;
45
46
47 #define DEFINE_EMPTY_STARTUP(name) \
48         void Romain::name::startup_notify(Romain::App_instance*, Romain::App_thread*, \
49                                           Romain::Thread_group*, Romain::App_model*) { }
50
51         /*
52          * Generic observer class.
53          */
54         class Observer
55         {
56                 public:
57
58                         /*
59                          * Return values for the observers' notify() functions.
60                          */
61                         enum ObserverReturnVal {
62                                 Invalid,
63                                 /*
64                                  * A fault handler has "Finished" handling the fault,
65                                  * if it modified the VCPU/UTCB state in a way that
66                                  * allows returning to the replica and other handlers
67                                  * may not touch this state anymore.
68                                  */
69                                 Finished,
70
71                                 /* The story of Finished_{wait,step,wakeup}
72                                  * ==============================================
73                                  * 
74                                  * The fault injection handler needs a mechanism that allows
75                                  * it to inject a fault into one replica while all other replicas
76                                  * don't do anything and simply wait until the injection (including
77                                  * potential further faults) has been completed.
78                                  */
79
80                                 /*
81                                  * tl;dr: Tell redundancy handler that execution has been
82                                  *        completed and that the replica should wait for an
83                                  *        explicit wakeup before resuming.
84                                  */
85                                 Finished_wait,
86                                 /*
87                                  * tl;dr: Execution completed. You are now the only replica
88                                  *        to continue.
89                                  */
90                                 Finished_step,
91                                 /*
92                                  * tl;dr: Tell redundancy handler that execution has been
93                                  *        completed and it should now also wake up all other
94                                  *        replicas that have been stopped by 'Finished_wait'
95                                  *        calls.
96                                  */
97                                 Finished_wakeup,
98
99                                 /*
100                                  * Handling produced the same result as 'Finished'.
101                                  *
102                                  * In contrast to the 'Finished' result, this result
103                                  * may be applied to replicas by simply copying UTCB
104                                  * and VCPU state to all of them.
105                                  */
106                                 Replicatable,
107                                 /*
108                                  * The fault was handled. However, VCPU/UTCB were not
109                                  * modified and other observers can be invoked before
110                                  * resuming the replica.
111                                  */
112                                 Continue,
113                                 /*
114                                  * This handler could not handle the fault and
115                                  * ignored it.
116                                  */
117                                 Ignored,
118                         };
119
120                         /*
121                          * This function is called once the observed instance has
122                          * completed startup.
123                          */
124                         virtual void startup_notify(Romain::App_instance *i = 0,
125                                                     Romain::App_thread *t = 0,
126                                                     Romain::Thread_group *tg = 0,
127                                                     Romain::App_model *a = 0) = 0;
128
129                         /*
130                          * This function is called whenever an observed instance
131                          * causes a fault.
132                          */
133                         virtual ObserverReturnVal notify(Romain::App_instance *i = 0,
134                                                          Romain::App_thread *t = 0,
135                                                          Romain::Thread_group *tg = 0,
136                                                          Romain::App_model *a = 0) = 0;
137
138                         /*
139                          * Check if we came to this point through a
140                          * debug interrupt.
141                          */
142                         static bool entry_reason_is_int3(L4vcpu::Vcpu* vcpu,
143                                                          Romain::App_instance *i,
144                                                          Romain::App_model *am);
145
146
147                         virtual char const * name() const = 0;
148                         virtual void status() const = 0;
149
150                         /*
151                          * Determine if this fault was caused by an INT1 trap.
152                          */
153                         static bool entry_reason_is_int1(L4vcpu::Vcpu *vcpu)
154                         { return vcpu->r()->trapno == 1; }
155         };
156
157
158         class ObserverFactory
159         {
160                 public:
161                         static Observer* CreateObserver(char const*);
162         };
163 }