diff options
Diffstat (limited to 'include/linux/syscalls.h')
| -rw-r--r-- | include/linux/syscalls.h | 131 |
1 files changed, 129 insertions, 2 deletions
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 80de7003d8c2..a8e37821cc60 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h | |||
| @@ -64,6 +64,7 @@ struct perf_counter_attr; | |||
| 64 | #include <linux/sem.h> | 64 | #include <linux/sem.h> |
| 65 | #include <asm/siginfo.h> | 65 | #include <asm/siginfo.h> |
| 66 | #include <asm/signal.h> | 66 | #include <asm/signal.h> |
| 67 | #include <linux/unistd.h> | ||
| 67 | #include <linux/quota.h> | 68 | #include <linux/quota.h> |
| 68 | #include <linux/key.h> | 69 | #include <linux/key.h> |
| 69 | #include <trace/syscall.h> | 70 | #include <trace/syscall.h> |
| @@ -97,6 +98,53 @@ struct perf_counter_attr; | |||
| 97 | #define __SC_TEST5(t5, a5, ...) __SC_TEST(t5); __SC_TEST4(__VA_ARGS__) | 98 | #define __SC_TEST5(t5, a5, ...) __SC_TEST(t5); __SC_TEST4(__VA_ARGS__) |
| 98 | #define __SC_TEST6(t6, a6, ...) __SC_TEST(t6); __SC_TEST5(__VA_ARGS__) | 99 | #define __SC_TEST6(t6, a6, ...) __SC_TEST(t6); __SC_TEST5(__VA_ARGS__) |
| 99 | 100 | ||
| 101 | #ifdef CONFIG_EVENT_PROFILE | ||
| 102 | #define TRACE_SYS_ENTER_PROFILE(sname) \ | ||
| 103 | static int prof_sysenter_enable_##sname(struct ftrace_event_call *event_call) \ | ||
| 104 | { \ | ||
| 105 | int ret = 0; \ | ||
| 106 | if (!atomic_inc_return(&event_enter_##sname.profile_count)) \ | ||
| 107 | ret = reg_prof_syscall_enter("sys"#sname); \ | ||
| 108 | return ret; \ | ||
| 109 | } \ | ||
| 110 | \ | ||
| 111 | static void prof_sysenter_disable_##sname(struct ftrace_event_call *event_call)\ | ||
| 112 | { \ | ||
| 113 | if (atomic_add_negative(-1, &event_enter_##sname.profile_count)) \ | ||
| 114 | unreg_prof_syscall_enter("sys"#sname); \ | ||
| 115 | } | ||
| 116 | |||
| 117 | #define TRACE_SYS_EXIT_PROFILE(sname) \ | ||
| 118 | static int prof_sysexit_enable_##sname(struct ftrace_event_call *event_call) \ | ||
| 119 | { \ | ||
| 120 | int ret = 0; \ | ||
| 121 | if (!atomic_inc_return(&event_exit_##sname.profile_count)) \ | ||
| 122 | ret = reg_prof_syscall_exit("sys"#sname); \ | ||
| 123 | return ret; \ | ||
| 124 | } \ | ||
| 125 | \ | ||
| 126 | static void prof_sysexit_disable_##sname(struct ftrace_event_call *event_call) \ | ||
| 127 | { \ | ||
| 128 | if (atomic_add_negative(-1, &event_exit_##sname.profile_count)) \ | ||
| 129 | unreg_prof_syscall_exit("sys"#sname); \ | ||
| 130 | } | ||
| 131 | |||
| 132 | #define TRACE_SYS_ENTER_PROFILE_INIT(sname) \ | ||
| 133 | .profile_count = ATOMIC_INIT(-1), \ | ||
| 134 | .profile_enable = prof_sysenter_enable_##sname, \ | ||
| 135 | .profile_disable = prof_sysenter_disable_##sname, | ||
| 136 | |||
| 137 | #define TRACE_SYS_EXIT_PROFILE_INIT(sname) \ | ||
| 138 | .profile_count = ATOMIC_INIT(-1), \ | ||
| 139 | .profile_enable = prof_sysexit_enable_##sname, \ | ||
| 140 | .profile_disable = prof_sysexit_disable_##sname, | ||
| 141 | #else | ||
| 142 | #define TRACE_SYS_ENTER_PROFILE(sname) | ||
| 143 | #define TRACE_SYS_ENTER_PROFILE_INIT(sname) | ||
| 144 | #define TRACE_SYS_EXIT_PROFILE(sname) | ||
| 145 | #define TRACE_SYS_EXIT_PROFILE_INIT(sname) | ||
| 146 | #endif | ||
| 147 | |||
| 100 | #ifdef CONFIG_FTRACE_SYSCALLS | 148 | #ifdef CONFIG_FTRACE_SYSCALLS |
| 101 | #define __SC_STR_ADECL1(t, a) #a | 149 | #define __SC_STR_ADECL1(t, a) #a |
| 102 | #define __SC_STR_ADECL2(t, a, ...) #a, __SC_STR_ADECL1(__VA_ARGS__) | 150 | #define __SC_STR_ADECL2(t, a, ...) #a, __SC_STR_ADECL1(__VA_ARGS__) |
| @@ -112,7 +160,81 @@ struct perf_counter_attr; | |||
| 112 | #define __SC_STR_TDECL5(t, a, ...) #t, __SC_STR_TDECL4(__VA_ARGS__) | 160 | #define __SC_STR_TDECL5(t, a, ...) #t, __SC_STR_TDECL4(__VA_ARGS__) |
| 113 | #define __SC_STR_TDECL6(t, a, ...) #t, __SC_STR_TDECL5(__VA_ARGS__) | 161 | #define __SC_STR_TDECL6(t, a, ...) #t, __SC_STR_TDECL5(__VA_ARGS__) |
| 114 | 162 | ||
| 163 | #define SYSCALL_TRACE_ENTER_EVENT(sname) \ | ||
| 164 | static struct ftrace_event_call event_enter_##sname; \ | ||
| 165 | struct trace_event enter_syscall_print_##sname = { \ | ||
| 166 | .trace = print_syscall_enter, \ | ||
| 167 | }; \ | ||
| 168 | static int init_enter_##sname(void) \ | ||
| 169 | { \ | ||
| 170 | int num, id; \ | ||
| 171 | num = syscall_name_to_nr("sys"#sname); \ | ||
| 172 | if (num < 0) \ | ||
| 173 | return -ENOSYS; \ | ||
| 174 | id = register_ftrace_event(&enter_syscall_print_##sname);\ | ||
| 175 | if (!id) \ | ||
| 176 | return -ENODEV; \ | ||
| 177 | event_enter_##sname.id = id; \ | ||
| 178 | set_syscall_enter_id(num, id); \ | ||
| 179 | INIT_LIST_HEAD(&event_enter_##sname.fields); \ | ||
| 180 | return 0; \ | ||
| 181 | } \ | ||
| 182 | TRACE_SYS_ENTER_PROFILE(sname); \ | ||
| 183 | static struct ftrace_event_call __used \ | ||
| 184 | __attribute__((__aligned__(4))) \ | ||
| 185 | __attribute__((section("_ftrace_events"))) \ | ||
| 186 | event_enter_##sname = { \ | ||
| 187 | .name = "sys_enter"#sname, \ | ||
| 188 | .system = "syscalls", \ | ||
| 189 | .event = &event_syscall_enter, \ | ||
| 190 | .raw_init = init_enter_##sname, \ | ||
| 191 | .show_format = syscall_enter_format, \ | ||
| 192 | .define_fields = syscall_enter_define_fields, \ | ||
| 193 | .regfunc = reg_event_syscall_enter, \ | ||
| 194 | .unregfunc = unreg_event_syscall_enter, \ | ||
| 195 | .data = "sys"#sname, \ | ||
| 196 | TRACE_SYS_ENTER_PROFILE_INIT(sname) \ | ||
| 197 | } | ||
| 198 | |||
| 199 | #define SYSCALL_TRACE_EXIT_EVENT(sname) \ | ||
| 200 | static struct ftrace_event_call event_exit_##sname; \ | ||
| 201 | struct trace_event exit_syscall_print_##sname = { \ | ||
| 202 | .trace = print_syscall_exit, \ | ||
| 203 | }; \ | ||
| 204 | static int init_exit_##sname(void) \ | ||
| 205 | { \ | ||
| 206 | int num, id; \ | ||
| 207 | num = syscall_name_to_nr("sys"#sname); \ | ||
| 208 | if (num < 0) \ | ||
| 209 | return -ENOSYS; \ | ||
| 210 | id = register_ftrace_event(&exit_syscall_print_##sname);\ | ||
| 211 | if (!id) \ | ||
| 212 | return -ENODEV; \ | ||
| 213 | event_exit_##sname.id = id; \ | ||
| 214 | set_syscall_exit_id(num, id); \ | ||
| 215 | INIT_LIST_HEAD(&event_exit_##sname.fields); \ | ||
| 216 | return 0; \ | ||
| 217 | } \ | ||
| 218 | TRACE_SYS_EXIT_PROFILE(sname); \ | ||
| 219 | static struct ftrace_event_call __used \ | ||
| 220 | __attribute__((__aligned__(4))) \ | ||
| 221 | __attribute__((section("_ftrace_events"))) \ | ||
| 222 | event_exit_##sname = { \ | ||
| 223 | .name = "sys_exit"#sname, \ | ||
| 224 | .system = "syscalls", \ | ||
| 225 | .event = &event_syscall_exit, \ | ||
| 226 | .raw_init = init_exit_##sname, \ | ||
| 227 | .show_format = syscall_exit_format, \ | ||
| 228 | .define_fields = syscall_exit_define_fields, \ | ||
| 229 | .regfunc = reg_event_syscall_exit, \ | ||
| 230 | .unregfunc = unreg_event_syscall_exit, \ | ||
| 231 | .data = "sys"#sname, \ | ||
| 232 | TRACE_SYS_EXIT_PROFILE_INIT(sname) \ | ||
| 233 | } | ||
| 234 | |||
| 115 | #define SYSCALL_METADATA(sname, nb) \ | 235 | #define SYSCALL_METADATA(sname, nb) \ |
| 236 | SYSCALL_TRACE_ENTER_EVENT(sname); \ | ||
| 237 | SYSCALL_TRACE_EXIT_EVENT(sname); \ | ||
| 116 | static const struct syscall_metadata __used \ | 238 | static const struct syscall_metadata __used \ |
| 117 | __attribute__((__aligned__(4))) \ | 239 | __attribute__((__aligned__(4))) \ |
| 118 | __attribute__((section("__syscalls_metadata"))) \ | 240 | __attribute__((section("__syscalls_metadata"))) \ |
| @@ -121,18 +243,23 @@ struct perf_counter_attr; | |||
| 121 | .nb_args = nb, \ | 243 | .nb_args = nb, \ |
| 122 | .types = types_##sname, \ | 244 | .types = types_##sname, \ |
| 123 | .args = args_##sname, \ | 245 | .args = args_##sname, \ |
| 124 | } | 246 | .enter_event = &event_enter_##sname, \ |
| 247 | .exit_event = &event_exit_##sname, \ | ||
| 248 | }; | ||
| 125 | 249 | ||
| 126 | #define SYSCALL_DEFINE0(sname) \ | 250 | #define SYSCALL_DEFINE0(sname) \ |
| 251 | SYSCALL_TRACE_ENTER_EVENT(_##sname); \ | ||
| 252 | SYSCALL_TRACE_EXIT_EVENT(_##sname); \ | ||
| 127 | static const struct syscall_metadata __used \ | 253 | static const struct syscall_metadata __used \ |
| 128 | __attribute__((__aligned__(4))) \ | 254 | __attribute__((__aligned__(4))) \ |
| 129 | __attribute__((section("__syscalls_metadata"))) \ | 255 | __attribute__((section("__syscalls_metadata"))) \ |
| 130 | __syscall_meta_##sname = { \ | 256 | __syscall_meta_##sname = { \ |
| 131 | .name = "sys_"#sname, \ | 257 | .name = "sys_"#sname, \ |
| 132 | .nb_args = 0, \ | 258 | .nb_args = 0, \ |
| 259 | .enter_event = &event_enter__##sname, \ | ||
| 260 | .exit_event = &event_exit__##sname, \ | ||
| 133 | }; \ | 261 | }; \ |
| 134 | asmlinkage long sys_##sname(void) | 262 | asmlinkage long sys_##sname(void) |
| 135 | |||
| 136 | #else | 263 | #else |
| 137 | #define SYSCALL_DEFINE0(name) asmlinkage long sys_##name(void) | 264 | #define SYSCALL_DEFINE0(name) asmlinkage long sys_##name(void) |
| 138 | #endif | 265 | #endif |
