aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/ft_event.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/ft_event.c')
-rw-r--r--arch/x86/kernel/ft_event.c104
1 files changed, 104 insertions, 0 deletions
diff --git a/arch/x86/kernel/ft_event.c b/arch/x86/kernel/ft_event.c
new file mode 100644
index 0000000000..b1d80c52d7
--- /dev/null
+++ b/arch/x86/kernel/ft_event.c
@@ -0,0 +1,104 @@
1#include <linux/types.h>
2
3#include <litmus/feather_trace.h>
4
5/* the feather trace management functions assume
6 * exclusive access to the event table
7 */
8
9
10#define BYTE_JUMP 0xeb
11#define BYTE_JUMP_LEN 0x02
12
13/* for each event, there is an entry in the event table */
14struct trace_event {
15 long id;
16 long count;
17 long start_addr;
18 long end_addr;
19};
20
21extern struct trace_event __start___event_table[];
22extern struct trace_event __stop___event_table[];
23
24int ft_enable_event(unsigned long id)
25{
26 struct trace_event* te = __start___event_table;
27 int count = 0;
28 char* delta;
29 unsigned char* instr;
30
31 while (te < __stop___event_table) {
32 if (te->id == id && ++te->count == 1) {
33 instr = (unsigned char*) te->start_addr;
34 /* make sure we don't clobber something wrong */
35 if (*instr == BYTE_JUMP) {
36 delta = (((unsigned char*) te->start_addr) + 1);
37 *delta = 0;
38 }
39 }
40 if (te->id == id)
41 count++;
42 te++;
43 }
44 return count;
45}
46
47int ft_disable_event(unsigned long id)
48{
49 struct trace_event* te = __start___event_table;
50 int count = 0;
51 char* delta;
52 unsigned char* instr;
53
54 while (te < __stop___event_table) {
55 if (te->id == id && --te->count == 0) {
56 instr = (unsigned char*) te->start_addr;
57 if (*instr == BYTE_JUMP) {
58 delta = (((unsigned char*) te->start_addr) + 1);
59 *delta = te->end_addr - te->start_addr -
60 BYTE_JUMP_LEN;
61 }
62 }
63 if (te->id == id)
64 count++;
65 te++;
66 }
67 return count;
68}
69
70int ft_disable_all_events(void)
71{
72 struct trace_event* te = __start___event_table;
73 int count = 0;
74 char* delta;
75 unsigned char* instr;
76
77 while (te < __stop___event_table) {
78 if (te->count) {
79 instr = (unsigned char*) te->start_addr;
80 if (*instr == BYTE_JUMP) {
81 delta = (((unsigned char*) te->start_addr)
82 + 1);
83 *delta = te->end_addr - te->start_addr -
84 BYTE_JUMP_LEN;
85 te->count = 0;
86 count++;
87 }
88 }
89 te++;
90 }
91 return count;
92}
93
94int ft_is_event_enabled(unsigned long id)
95{
96 struct trace_event* te = __start___event_table;
97
98 while (te < __stop___event_table) {
99 if (te->id == id)
100 return te->count;
101 te++;
102 }
103 return 0;
104}