Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'trace-v5.3' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace

Pull tracing updates from Steven Rostedt:
"The main changes in this release include:

- Add user space specific memory reading for kprobes

- Allow kprobes to be executed earlier in boot

The rest are mostly just various clean ups and small fixes"

* tag 'trace-v5.3' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace: (33 commits)
tracing: Make trace_get_fields() global
tracing: Let filter_assign_type() detect FILTER_PTR_STRING
tracing: Pass type into tracing_generic_entry_update()
ftrace/selftest: Test if set_event/ftrace_pid exists before writing
ftrace/selftests: Return the skip code when tracing directory not configured in kernel
tracing/kprobe: Check registered state using kprobe
tracing/probe: Add trace_event_call accesses APIs
tracing/probe: Add probe event name and group name accesses APIs
tracing/probe: Add trace flag access APIs for trace_probe
tracing/probe: Add trace_event_file access APIs for trace_probe
tracing/probe: Add trace_event_call register API for trace_probe
tracing/probe: Add trace_probe init and free functions
tracing/uprobe: Set print format when parsing command
tracing/kprobe: Set print format right after parsed command
kprobes: Fix to init kprobes in subsys_initcall
tracepoint: Use struct_size() in kmalloc()
ring-buffer: Remove HAVE_64BIT_ALIGNED_ACCESS
ftrace: Enable trampoline when rec count returns back to one
tracing/kprobe: Do not run kprobe boot tests if kprobe_event is on cmdline
tracing: Make a separate config for trace event self tests
...

+864 -414
+13
Documentation/admin-guide/kernel-parameters.txt
··· 2011 2011 Built with CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF=y, 2012 2012 the default is off. 2013 2013 2014 + kprobe_event=[probe-list] 2015 + [FTRACE] Add kprobe events and enable at boot time. 2016 + The probe-list is a semicolon delimited list of probe 2017 + definitions. Each definition is same as kprobe_events 2018 + interface, but the parameters are comma delimited. 2019 + For example, to add a kprobe event on vfs_read with 2020 + arg1 and arg2, add to the command line; 2021 + 2022 + kprobe_event=p,vfs_read,$arg1,$arg2 2023 + 2024 + See also Documentation/trace/kprobetrace.rst "Kernel 2025 + Boot Parameter" section. 2026 + 2014 2027 kpti= [ARM64] Control page table isolation of user 2015 2028 and kernel address spaces. 2016 2029 Default: enabled on cores which need mitigation.
+39 -3
Documentation/trace/kprobetrace.rst
··· 51 51 $argN : Fetch the Nth function argument. (N >= 1) (\*1) 52 52 $retval : Fetch return value.(\*2) 53 53 $comm : Fetch current task comm. 54 - +|-offs(FETCHARG) : Fetch memory at FETCHARG +|- offs address.(\*3) 54 + +|-[u]OFFS(FETCHARG) : Fetch memory at FETCHARG +|- OFFS address.(\*3)(\*4) 55 55 NAME=FETCHARG : Set NAME as the argument name of FETCHARG. 56 56 FETCHARG:TYPE : Set TYPE as the type of FETCHARG. Currently, basic types 57 57 (u8/u16/u32/u64/s8/s16/s32/s64), hexadecimal types 58 - (x8/x16/x32/x64), "string" and bitfield are supported. 58 + (x8/x16/x32/x64), "string", "ustring" and bitfield 59 + are supported. 59 60 60 61 (\*1) only for the probe on function entry (offs == 0). 61 62 (\*2) only for return probe. 62 63 (\*3) this is useful for fetching a field of data structures. 64 + (\*4) "u" means user-space dereference. See :ref:`user_mem_access`. 63 65 64 66 Types 65 67 ----- ··· 79 77 wrong, but '+8($stack):x8[8]' is OK.) 80 78 String type is a special type, which fetches a "null-terminated" string from 81 79 kernel space. This means it will fail and store NULL if the string container 82 - has been paged out. 80 + has been paged out. "ustring" type is an alternative of string for user-space. 81 + See :ref:`user_mem_access` for more info.. 83 82 The string array type is a bit different from other types. For other base 84 83 types, <base-type>[1] is equal to <base-type> (e.g. +0(%di):x32[1] is same 85 84 as +0(%di):x32.) But string[1] is not equal to string. The string type itself ··· 95 92 which shows given pointer in "symbol+offset" style. 96 93 For $comm, the default type is "string"; any other type is invalid. 97 94 95 + .. _user_mem_access: 96 + User Memory Access 97 + ------------------ 98 + Kprobe events supports user-space memory access. For that purpose, you can use 99 + either user-space dereference syntax or 'ustring' type. 100 + 101 + The user-space dereference syntax allows you to access a field of a data 102 + structure in user-space. This is done by adding the "u" prefix to the 103 + dereference syntax. For example, +u4(%si) means it will read memory from the 104 + address in the register %si offset by 4, and the memory is expected to be in 105 + user-space. You can use this for strings too, e.g. +u0(%si):string will read 106 + a string from the address in the register %si that is expected to be in user- 107 + space. 'ustring' is a shortcut way of performing the same task. That is, 108 + +0(%si):ustring is equivalent to +u0(%si):string. 109 + 110 + Note that kprobe-event provides the user-memory access syntax but it doesn't 111 + use it transparently. This means if you use normal dereference or string type 112 + for user memory, it might fail, and may always fail on some archs. The user 113 + has to carefully check if the target data is in kernel or user space. 98 114 99 115 Per-Probe Event Filtering 100 116 ------------------------- ··· 145 123 /sys/kernel/debug/tracing/kprobe_profile. 146 124 The first column is event name, the second is the number of probe hits, 147 125 the third is the number of probe miss-hits. 126 + 127 + Kernel Boot Parameter 128 + --------------------- 129 + You can add and enable new kprobe events when booting up the kernel by 130 + "kprobe_event=" parameter. The parameter accepts a semicolon-delimited 131 + kprobe events, which format is similar to the kprobe_events. 132 + The difference is that the probe definition parameters are comma-delimited 133 + instead of space. For example, adding myprobe event on do_sys_open like below 134 + 135 + p:myprobe do_sys_open dfd=%ax filename=%dx flags=%cx mode=+4($stack) 136 + 137 + should be below for kernel boot parameter (just replace spaces with comma) 138 + 139 + p:myprobe,do_sys_open,dfd=%ax,filename=%dx,flags=%cx,mode=+4($stack) 148 140 149 141 150 142 Usage examples
+6 -4
Documentation/trace/uprobetracer.rst
··· 42 42 @+OFFSET : Fetch memory at OFFSET (OFFSET from same file as PATH) 43 43 $stackN : Fetch Nth entry of stack (N >= 0) 44 44 $stack : Fetch stack address. 45 - $retval : Fetch return value.(*) 45 + $retval : Fetch return value.(\*1) 46 46 $comm : Fetch current task comm. 47 - +|-offs(FETCHARG) : Fetch memory at FETCHARG +|- offs address.(**) 47 + +|-[u]OFFS(FETCHARG) : Fetch memory at FETCHARG +|- OFFS address.(\*2)(\*3) 48 48 NAME=FETCHARG : Set NAME as the argument name of FETCHARG. 49 49 FETCHARG:TYPE : Set TYPE as the type of FETCHARG. Currently, basic types 50 50 (u8/u16/u32/u64/s8/s16/s32/s64), hexadecimal types 51 51 (x8/x16/x32/x64), "string" and bitfield are supported. 52 52 53 - (*) only for return probe. 54 - (**) this is useful for fetching a field of data structures. 53 + (\*1) only for return probe. 54 + (\*2) this is useful for fetching a field of data structures. 55 + (\*3) Unlike kprobe event, "u" prefix will just be ignored, becuse uprobe 56 + events can access only user-space memory. 55 57 56 58 Types 57 59 -----
-16
arch/Kconfig
··· 128 128 managed by the kernel and kept transparent to the probed 129 129 application. ) 130 130 131 - config HAVE_64BIT_ALIGNED_ACCESS 132 - def_bool 64BIT && !HAVE_EFFICIENT_UNALIGNED_ACCESS 133 - help 134 - Some architectures require 64 bit accesses to be 64 bit 135 - aligned, which also requires structs containing 64 bit values 136 - to be 64 bit aligned too. This includes some 32 bit 137 - architectures which can do 64 bit accesses, as well as 64 bit 138 - architectures without unaligned access. 139 - 140 - This symbol should be selected by an architecture if 64 bit 141 - accesses are required to be 64 bit aligned in this way even 142 - though it is not a 64 bit architecture. 143 - 144 - See Documentation/unaligned-memory-access.txt for more 145 - information on the topic of unaligned memory accesses. 146 - 147 131 config HAVE_EFFICIENT_UNALIGNED_ACCESS 148 132 bool 149 133 help
+3 -1
arch/x86/include/asm/uaccess.h
··· 66 66 }) 67 67 68 68 #ifdef CONFIG_DEBUG_ATOMIC_SLEEP 69 - # define WARN_ON_IN_IRQ() WARN_ON_ONCE(!in_task()) 69 + static inline bool pagefault_disabled(void); 70 + # define WARN_ON_IN_IRQ() \ 71 + WARN_ON_ONCE(!in_task() && !pagefault_disabled()) 70 72 #else 71 73 # define WARN_ON_IN_IRQ() 72 74 #endif
+3 -3
arch/x86/kernel/ftrace.c
··· 373 373 return add_break(rec->ip, old); 374 374 } 375 375 376 - static int add_breakpoints(struct dyn_ftrace *rec, int enable) 376 + static int add_breakpoints(struct dyn_ftrace *rec, bool enable) 377 377 { 378 378 unsigned long ftrace_addr; 379 379 int ret; ··· 481 481 return add_update_code(ip, new); 482 482 } 483 483 484 - static int add_update(struct dyn_ftrace *rec, int enable) 484 + static int add_update(struct dyn_ftrace *rec, bool enable) 485 485 { 486 486 unsigned long ftrace_addr; 487 487 int ret; ··· 527 527 return ftrace_write(ip, new, 1); 528 528 } 529 529 530 - static int finish_update(struct dyn_ftrace *rec, int enable) 530 + static int finish_update(struct dyn_ftrace *rec, bool enable) 531 531 { 532 532 unsigned long ftrace_addr; 533 533 int ret;
+2 -2
include/linux/ftrace.h
··· 427 427 iter = ftrace_rec_iter_next(iter)) 428 428 429 429 430 - int ftrace_update_record(struct dyn_ftrace *rec, int enable); 431 - int ftrace_test_record(struct dyn_ftrace *rec, int enable); 430 + int ftrace_update_record(struct dyn_ftrace *rec, bool enable); 431 + int ftrace_test_record(struct dyn_ftrace *rec, bool enable); 432 432 void ftrace_run_stop_machine(int command); 433 433 unsigned long ftrace_location(unsigned long ip); 434 434 unsigned long ftrace_location_range(unsigned long start, unsigned long end);
+9
include/linux/trace_events.h
··· 142 142 enum print_line_t trace_handle_return(struct trace_seq *s); 143 143 144 144 void tracing_generic_entry_update(struct trace_entry *entry, 145 + unsigned short type, 145 146 unsigned long flags, 146 147 int pc); 147 148 struct trace_event_file; ··· 316 315 return call->tp ? call->tp->name : NULL; 317 316 else 318 317 return call->name; 318 + } 319 + 320 + static inline struct list_head * 321 + trace_get_fields(struct trace_event_call *event_call) 322 + { 323 + if (!event_call->class->get_fields) 324 + return &event_call->class->fields; 325 + return event_call->class->get_fields(event_call); 319 326 } 320 327 321 328 struct trace_array;
+19 -1
include/linux/uaccess.h
··· 203 203 /* 204 204 * Is the pagefault handler disabled? If so, user access methods will not sleep. 205 205 */ 206 - #define pagefault_disabled() (current->pagefault_disabled != 0) 206 + static inline bool pagefault_disabled(void) 207 + { 208 + return current->pagefault_disabled != 0; 209 + } 207 210 208 211 /* 209 212 * The pagefault handler is in general disabled by pagefault_disable() or ··· 243 240 extern long __probe_kernel_read(void *dst, const void *src, size_t size); 244 241 245 242 /* 243 + * probe_user_read(): safely attempt to read from a location in user space 244 + * @dst: pointer to the buffer that shall take the data 245 + * @src: address to read from 246 + * @size: size of the data chunk 247 + * 248 + * Safely read from address @src to the buffer at @dst. If a kernel fault 249 + * happens, handle that and return -EFAULT. 250 + */ 251 + extern long probe_user_read(void *dst, const void __user *src, size_t size); 252 + extern long __probe_user_read(void *dst, const void __user *src, size_t size); 253 + 254 + /* 246 255 * probe_kernel_write(): safely attempt to write to a location 247 256 * @dst: address to write to 248 257 * @src: pointer to the data that shall be written ··· 267 252 extern long notrace __probe_kernel_write(void *dst, const void *src, size_t size); 268 253 269 254 extern long strncpy_from_unsafe(char *dst, const void *unsafe_addr, long count); 255 + extern long strncpy_from_unsafe_user(char *dst, const void __user *unsafe_addr, 256 + long count); 257 + extern long strnlen_unsafe_user(const void __user *unsafe_addr, long count); 270 258 271 259 /** 272 260 * probe_kernel_address(): safely attempt to read from a location
+1 -2
kernel/kprobes.c
··· 2276 2276 init_test_probes(); 2277 2277 return err; 2278 2278 } 2279 + subsys_initcall(init_kprobes); 2279 2280 2280 2281 #ifdef CONFIG_DEBUG_FS 2281 2282 static void report_probe(struct seq_file *pi, struct kprobe *p, ··· 2589 2588 2590 2589 late_initcall(debugfs_kprobe_init); 2591 2590 #endif /* CONFIG_DEBUG_FS */ 2592 - 2593 - module_init(init_kprobes);
+11 -1
kernel/trace/Kconfig
··· 597 597 functioning properly. It will do tests on all the configured 598 598 tracers of ftrace. 599 599 600 + config EVENT_TRACE_STARTUP_TEST 601 + bool "Run selftest on trace events" 602 + depends on FTRACE_STARTUP_TEST 603 + default y 604 + help 605 + This option performs a test on all trace events in the system. 606 + It basically just enables each event and runs some code that 607 + will trigger events (not necessarily the event it enables) 608 + This may take some time run as there are a lot of events. 609 + 600 610 config EVENT_TRACE_TEST_SYSCALLS 601 611 bool "Run selftest on syscall events" 602 - depends on FTRACE_STARTUP_TEST 612 + depends on EVENT_TRACE_STARTUP_TEST 603 613 help 604 614 This option will also enable testing every syscall event. 605 615 It only enables the event and disables it and runs various loads
+25 -23
kernel/trace/ftrace.c
··· 1622 1622 return keep_regs; 1623 1623 } 1624 1624 1625 + static struct ftrace_ops * 1626 + ftrace_find_tramp_ops_any(struct dyn_ftrace *rec); 1627 + static struct ftrace_ops * 1628 + ftrace_find_tramp_ops_next(struct dyn_ftrace *rec, struct ftrace_ops *ops); 1629 + 1625 1630 static bool __ftrace_hash_rec_update(struct ftrace_ops *ops, 1626 1631 int filter_hash, 1627 1632 bool inc) ··· 1755 1750 } 1756 1751 1757 1752 /* 1758 - * If the rec had TRAMP enabled, then it needs to 1759 - * be cleared. As TRAMP can only be enabled iff 1760 - * there is only a single ops attached to it. 1761 - * In otherwords, always disable it on decrementing. 1762 - * In the future, we may set it if rec count is 1763 - * decremented to one, and the ops that is left 1764 - * has a trampoline. 1753 + * The TRAMP needs to be set only if rec count 1754 + * is decremented to one, and the ops that is 1755 + * left has a trampoline. As TRAMP can only be 1756 + * enabled if there is only a single ops attached 1757 + * to it. 1765 1758 */ 1766 - rec->flags &= ~FTRACE_FL_TRAMP; 1759 + if (ftrace_rec_count(rec) == 1 && 1760 + ftrace_find_tramp_ops_any(rec)) 1761 + rec->flags |= FTRACE_FL_TRAMP; 1762 + else 1763 + rec->flags &= ~FTRACE_FL_TRAMP; 1767 1764 1768 1765 /* 1769 1766 * flags will be cleared in ftrace_check_record() ··· 1775 1768 count++; 1776 1769 1777 1770 /* Must match FTRACE_UPDATE_CALLS in ftrace_modify_all_code() */ 1778 - update |= ftrace_test_record(rec, 1) != FTRACE_UPDATE_IGNORE; 1771 + update |= ftrace_test_record(rec, true) != FTRACE_UPDATE_IGNORE; 1779 1772 1780 1773 /* Shortcut, if we handled all records, we are done. */ 1781 1774 if (!all && count == hash->count) ··· 1958 1951 printk(KERN_CONT "%s%02x", i ? ":" : "", p[i]); 1959 1952 } 1960 1953 1961 - static struct ftrace_ops * 1962 - ftrace_find_tramp_ops_any(struct dyn_ftrace *rec); 1963 - static struct ftrace_ops * 1964 - ftrace_find_tramp_ops_next(struct dyn_ftrace *rec, struct ftrace_ops *ops); 1965 - 1966 1954 enum ftrace_bug_type ftrace_bug_type; 1967 1955 const void *ftrace_expected; 1968 1956 ··· 2049 2047 } 2050 2048 } 2051 2049 2052 - static int ftrace_check_record(struct dyn_ftrace *rec, int enable, int update) 2050 + static int ftrace_check_record(struct dyn_ftrace *rec, bool enable, bool update) 2053 2051 { 2054 2052 unsigned long flag = 0UL; 2055 2053 ··· 2148 2146 /** 2149 2147 * ftrace_update_record, set a record that now is tracing or not 2150 2148 * @rec: the record to update 2151 - * @enable: set to 1 if the record is tracing, zero to force disable 2149 + * @enable: set to true if the record is tracing, false to force disable 2152 2150 * 2153 2151 * The records that represent all functions that can be traced need 2154 2152 * to be updated when tracing has been enabled. 2155 2153 */ 2156 - int ftrace_update_record(struct dyn_ftrace *rec, int enable) 2154 + int ftrace_update_record(struct dyn_ftrace *rec, bool enable) 2157 2155 { 2158 - return ftrace_check_record(rec, enable, 1); 2156 + return ftrace_check_record(rec, enable, true); 2159 2157 } 2160 2158 2161 2159 /** 2162 2160 * ftrace_test_record, check if the record has been enabled or not 2163 2161 * @rec: the record to test 2164 - * @enable: set to 1 to check if enabled, 0 if it is disabled 2162 + * @enable: set to true to check if enabled, false if it is disabled 2165 2163 * 2166 2164 * The arch code may need to test if a record is already set to 2167 2165 * tracing to determine how to modify the function code that it 2168 2166 * represents. 2169 2167 */ 2170 - int ftrace_test_record(struct dyn_ftrace *rec, int enable) 2168 + int ftrace_test_record(struct dyn_ftrace *rec, bool enable) 2171 2169 { 2172 - return ftrace_check_record(rec, enable, 0); 2170 + return ftrace_check_record(rec, enable, false); 2173 2171 } 2174 2172 2175 2173 static struct ftrace_ops * ··· 2358 2356 } 2359 2357 2360 2358 static int 2361 - __ftrace_replace_code(struct dyn_ftrace *rec, int enable) 2359 + __ftrace_replace_code(struct dyn_ftrace *rec, bool enable) 2362 2360 { 2363 2361 unsigned long ftrace_old_addr; 2364 2362 unsigned long ftrace_addr; ··· 2397 2395 { 2398 2396 struct dyn_ftrace *rec; 2399 2397 struct ftrace_page *pg; 2400 - int enable = mod_flags & FTRACE_MODIFY_ENABLE_FL; 2398 + bool enable = mod_flags & FTRACE_MODIFY_ENABLE_FL; 2401 2399 int schedulable = mod_flags & FTRACE_MODIFY_MAY_SLEEP_FL; 2402 2400 int failed; 2403 2401
+4 -13
kernel/trace/ring_buffer.c
··· 128 128 #define RB_ALIGNMENT 4U 129 129 #define RB_MAX_SMALL_DATA (RB_ALIGNMENT * RINGBUF_TYPE_DATA_TYPE_LEN_MAX) 130 130 #define RB_EVNT_MIN_SIZE 8U /* two 32bit words */ 131 - 132 - #ifndef CONFIG_HAVE_64BIT_ALIGNED_ACCESS 133 - # define RB_FORCE_8BYTE_ALIGNMENT 0 134 - # define RB_ARCH_ALIGNMENT RB_ALIGNMENT 135 - #else 136 - # define RB_FORCE_8BYTE_ALIGNMENT 1 137 - # define RB_ARCH_ALIGNMENT 8U 138 - #endif 139 - 140 - #define RB_ALIGN_DATA __aligned(RB_ARCH_ALIGNMENT) 131 + #define RB_ALIGN_DATA __aligned(RB_ALIGNMENT) 141 132 142 133 /* define RINGBUF_TYPE_DATA for 'case RINGBUF_TYPE_DATA:' */ 143 134 #define RINGBUF_TYPE_DATA 0 ... RINGBUF_TYPE_DATA_TYPE_LEN_MAX ··· 2364 2373 2365 2374 event->time_delta = delta; 2366 2375 length -= RB_EVNT_HDR_SIZE; 2367 - if (length > RB_MAX_SMALL_DATA || RB_FORCE_8BYTE_ALIGNMENT) { 2376 + if (length > RB_MAX_SMALL_DATA) { 2368 2377 event->type_len = 0; 2369 2378 event->array[0] = length; 2370 2379 } else ··· 2379 2388 if (!length) 2380 2389 length++; 2381 2390 2382 - if (length > RB_MAX_SMALL_DATA || RB_FORCE_8BYTE_ALIGNMENT) 2391 + if (length > RB_MAX_SMALL_DATA) 2383 2392 length += sizeof(event.array[0]); 2384 2393 2385 2394 length += RB_EVNT_HDR_SIZE; 2386 - length = ALIGN(length, RB_ARCH_ALIGNMENT); 2395 + length = ALIGN(length, RB_ALIGNMENT); 2387 2396 2388 2397 /* 2389 2398 * In case the time delta is larger than the 27 bits for it
+9 -8
kernel/trace/trace.c
··· 366 366 } 367 367 368 368 /** 369 - * trace_pid_filter_add_remove_task - Add or remove a task from a pid_list 369 + * trace_filter_add_remove_task - Add or remove a task from a pid_list 370 370 * @pid_list: The list to modify 371 371 * @self: The current task for fork or NULL for exit 372 372 * @task: The task to add or remove ··· 743 743 { 744 744 struct trace_entry *ent = ring_buffer_event_data(event); 745 745 746 - tracing_generic_entry_update(ent, flags, pc); 747 - ent->type = type; 746 + tracing_generic_entry_update(ent, type, flags, pc); 748 747 } 749 748 750 749 static __always_inline struct ring_buffer_event * ··· 2311 2312 EXPORT_SYMBOL_GPL(trace_handle_return); 2312 2313 2313 2314 void 2314 - tracing_generic_entry_update(struct trace_entry *entry, unsigned long flags, 2315 - int pc) 2315 + tracing_generic_entry_update(struct trace_entry *entry, unsigned short type, 2316 + unsigned long flags, int pc) 2316 2317 { 2317 2318 struct task_struct *tsk = current; 2318 2319 2319 2320 entry->preempt_count = pc & 0xff; 2320 2321 entry->pid = (tsk) ? tsk->pid : 0; 2322 + entry->type = type; 2321 2323 entry->flags = 2322 2324 #ifdef CONFIG_TRACE_IRQFLAGS_SUPPORT 2323 2325 (irqs_disabled_flags(flags) ? TRACE_FLAG_IRQS_OFF : 0) | ··· 4842 4842 "\t args: <name>=fetcharg[:type]\n" 4843 4843 "\t fetcharg: %<register>, @<address>, @<symbol>[+|-<offset>],\n" 4844 4844 #ifdef CONFIG_HAVE_FUNCTION_ARG_ACCESS_API 4845 - "\t $stack<index>, $stack, $retval, $comm, $arg<N>\n" 4845 + "\t $stack<index>, $stack, $retval, $comm, $arg<N>,\n" 4846 4846 #else 4847 - "\t $stack<index>, $stack, $retval, $comm\n" 4847 + "\t $stack<index>, $stack, $retval, $comm,\n" 4848 4848 #endif 4849 + "\t +|-[u]<offset>(<fetcharg>)\n" 4849 4850 "\t type: s8/16/32/64, u8/16/32/64, x8/16/32/64, string, symbol,\n" 4850 - "\t b<bit-width>@<bit-offset>/<container-size>,\n" 4851 + "\t b<bit-width>@<bit-offset>/<container-size>, ustring,\n" 4851 4852 "\t <type>\\[<array-size>\\]\n" 4852 4853 #ifdef CONFIG_HIST_TRIGGERS 4853 4854 "\t field: <stype> <name>;\n"
+1 -2
kernel/trace/trace_event_perf.c
··· 416 416 unsigned long flags; 417 417 418 418 local_save_flags(flags); 419 - tracing_generic_entry_update(entry, flags, pc); 420 - entry->type = type; 419 + tracing_generic_entry_update(entry, type, flags, pc); 421 420 } 422 421 NOKPROBE_SYMBOL(perf_trace_buf_update); 423 422
+1 -9
kernel/trace/trace_events.c
··· 70 70 #define while_for_each_event_file() \ 71 71 } 72 72 73 - static struct list_head * 74 - trace_get_fields(struct trace_event_call *event_call) 75 - { 76 - if (!event_call->class->get_fields) 77 - return &event_call->class->fields; 78 - return event_call->class->get_fields(event_call); 79 - } 80 - 81 73 static struct ftrace_event_field * 82 74 __find_event_field(struct list_head *head, char *name) 83 75 { ··· 3182 3190 event_trace_enable(); 3183 3191 } 3184 3192 3185 - #ifdef CONFIG_FTRACE_STARTUP_TEST 3193 + #ifdef CONFIG_EVENT_TRACE_STARTUP_TEST 3186 3194 3187 3195 static DEFINE_SPINLOCK(test_spinlock); 3188 3196 static DEFINE_SPINLOCK(test_spinlock_irq);
+3
kernel/trace/trace_events_filter.c
··· 1084 1084 if (strchr(type, '[') && strstr(type, "char")) 1085 1085 return FILTER_STATIC_STRING; 1086 1086 1087 + if (strcmp(type, "char *") == 0 || strcmp(type, "const char *") == 0) 1088 + return FILTER_PTR_STRING; 1089 + 1087 1090 return FILTER_OTHER; 1088 1091 } 1089 1092
+202 -159
kernel/trace/trace_kprobe.c
··· 12 12 #include <linux/rculist.h> 13 13 #include <linux/error-injection.h> 14 14 15 + #include <asm/setup.h> /* for COMMAND_LINE_SIZE */ 16 + 15 17 #include "trace_dynevent.h" 16 18 #include "trace_kprobe_selftest.h" 17 19 #include "trace_probe.h" ··· 21 19 22 20 #define KPROBE_EVENT_SYSTEM "kprobes" 23 21 #define KRETPROBE_MAXACTIVE_MAX 4096 22 + #define MAX_KPROBE_CMDLINE_SIZE 1024 23 + 24 + /* Kprobe early definition from command line */ 25 + static char kprobe_boot_events_buf[COMMAND_LINE_SIZE] __initdata; 26 + static bool kprobe_boot_events_enabled __initdata; 27 + 28 + static int __init set_kprobe_boot_events(char *str) 29 + { 30 + strlcpy(kprobe_boot_events_buf, str, COMMAND_LINE_SIZE); 31 + return 0; 32 + } 33 + __setup("kprobe_event=", set_kprobe_boot_events); 24 34 25 35 static int trace_kprobe_create(int argc, const char **argv); 26 36 static int trace_kprobe_show(struct seq_file *m, struct dyn_event *ev); ··· 142 128 { 143 129 struct trace_kprobe *tk = to_trace_kprobe(ev); 144 130 145 - return strcmp(trace_event_name(&tk->tp.call), event) == 0 && 146 - (!system || strcmp(tk->tp.call.class->system, system) == 0); 131 + return strcmp(trace_probe_name(&tk->tp), event) == 0 && 132 + (!system || strcmp(trace_probe_group_name(&tk->tp), system) == 0); 147 133 } 148 134 149 135 static nokprobe_inline unsigned long trace_kprobe_nhit(struct trace_kprobe *tk) ··· 155 141 nhit += *per_cpu_ptr(tk->nhit, cpu); 156 142 157 143 return nhit; 144 + } 145 + 146 + static nokprobe_inline bool trace_kprobe_is_registered(struct trace_kprobe *tk) 147 + { 148 + return !(list_empty(&tk->rp.kp.list) && 149 + hlist_unhashed(&tk->rp.kp.hlist)); 158 150 } 159 151 160 152 /* Return 0 if it fails to find the symbol address */ ··· 203 183 static int kretprobe_dispatcher(struct kretprobe_instance *ri, 204 184 struct pt_regs *regs); 205 185 186 + static void free_trace_kprobe(struct trace_kprobe *tk) 187 + { 188 + if (tk) { 189 + trace_probe_cleanup(&tk->tp); 190 + kfree(tk->symbol); 191 + free_percpu(tk->nhit); 192 + kfree(tk); 193 + } 194 + } 195 + 206 196 /* 207 197 * Allocate new trace_probe and initialize it (including kprobes). 208 198 */ ··· 250 220 tk->rp.kp.pre_handler = kprobe_dispatcher; 251 221 252 222 tk->rp.maxactive = maxactive; 223 + INIT_HLIST_NODE(&tk->rp.kp.hlist); 224 + INIT_LIST_HEAD(&tk->rp.kp.list); 253 225 254 - if (!event || !group) { 255 - ret = -EINVAL; 256 - goto error; 257 - } 258 - 259 - tk->tp.call.class = &tk->tp.class; 260 - tk->tp.call.name = kstrdup(event, GFP_KERNEL); 261 - if (!tk->tp.call.name) 262 - goto error; 263 - 264 - tk->tp.class.system = kstrdup(group, GFP_KERNEL); 265 - if (!tk->tp.class.system) 226 + ret = trace_probe_init(&tk->tp, event, group); 227 + if (ret < 0) 266 228 goto error; 267 229 268 230 dyn_event_init(&tk->devent, &trace_kprobe_ops); 269 - INIT_LIST_HEAD(&tk->tp.files); 270 231 return tk; 271 232 error: 272 - kfree(tk->tp.call.name); 273 - kfree(tk->symbol); 274 - free_percpu(tk->nhit); 275 - kfree(tk); 233 + free_trace_kprobe(tk); 276 234 return ERR_PTR(ret); 277 - } 278 - 279 - static void free_trace_kprobe(struct trace_kprobe *tk) 280 - { 281 - int i; 282 - 283 - if (!tk) 284 - return; 285 - 286 - for (i = 0; i < tk->tp.nr_args; i++) 287 - traceprobe_free_probe_arg(&tk->tp.args[i]); 288 - 289 - kfree(tk->tp.call.class->system); 290 - kfree(tk->tp.call.name); 291 - kfree(tk->symbol); 292 - free_percpu(tk->nhit); 293 - kfree(tk); 294 235 } 295 236 296 237 static struct trace_kprobe *find_trace_kprobe(const char *event, ··· 271 270 struct trace_kprobe *tk; 272 271 273 272 for_each_trace_kprobe(tk, pos) 274 - if (strcmp(trace_event_name(&tk->tp.call), event) == 0 && 275 - strcmp(tk->tp.call.class->system, group) == 0) 273 + if (strcmp(trace_probe_name(&tk->tp), event) == 0 && 274 + strcmp(trace_probe_group_name(&tk->tp), group) == 0) 276 275 return tk; 277 276 return NULL; 278 277 } ··· 281 280 { 282 281 int ret = 0; 283 282 284 - if (trace_probe_is_registered(&tk->tp) && !trace_kprobe_has_gone(tk)) { 283 + if (trace_kprobe_is_registered(tk) && !trace_kprobe_has_gone(tk)) { 285 284 if (trace_kprobe_is_return(tk)) 286 285 ret = enable_kretprobe(&tk->rp); 287 286 else ··· 298 297 static int 299 298 enable_trace_kprobe(struct trace_kprobe *tk, struct trace_event_file *file) 300 299 { 301 - struct event_file_link *link; 300 + bool enabled = trace_probe_is_enabled(&tk->tp); 302 301 int ret = 0; 303 302 304 303 if (file) { 305 - link = kmalloc(sizeof(*link), GFP_KERNEL); 306 - if (!link) { 307 - ret = -ENOMEM; 308 - goto out; 309 - } 310 - 311 - link->file = file; 312 - list_add_tail_rcu(&link->list, &tk->tp.files); 313 - 314 - tk->tp.flags |= TP_FLAG_TRACE; 315 - ret = __enable_trace_kprobe(tk); 316 - if (ret) { 317 - list_del_rcu(&link->list); 318 - kfree(link); 319 - tk->tp.flags &= ~TP_FLAG_TRACE; 320 - } 321 - 322 - } else { 323 - tk->tp.flags |= TP_FLAG_PROFILE; 324 - ret = __enable_trace_kprobe(tk); 304 + ret = trace_probe_add_file(&tk->tp, file); 325 305 if (ret) 326 - tk->tp.flags &= ~TP_FLAG_PROFILE; 306 + return ret; 307 + } else 308 + trace_probe_set_flag(&tk->tp, TP_FLAG_PROFILE); 309 + 310 + if (enabled) 311 + return 0; 312 + 313 + ret = __enable_trace_kprobe(tk); 314 + if (ret) { 315 + if (file) 316 + trace_probe_remove_file(&tk->tp, file); 317 + else 318 + trace_probe_clear_flag(&tk->tp, TP_FLAG_PROFILE); 327 319 } 328 - out: 320 + 329 321 return ret; 330 322 } 331 323 ··· 329 335 static int 330 336 disable_trace_kprobe(struct trace_kprobe *tk, struct trace_event_file *file) 331 337 { 332 - struct event_file_link *link = NULL; 333 - int wait = 0; 338 + struct trace_probe *tp = &tk->tp; 334 339 int ret = 0; 335 340 336 341 if (file) { 337 - link = find_event_file_link(&tk->tp, file); 338 - if (!link) { 339 - ret = -EINVAL; 342 + if (!trace_probe_get_file_link(tp, file)) 343 + return -ENOENT; 344 + if (!trace_probe_has_single_file(tp)) 340 345 goto out; 341 - } 342 - 343 - list_del_rcu(&link->list); 344 - wait = 1; 345 - if (!list_empty(&tk->tp.files)) 346 - goto out; 347 - 348 - tk->tp.flags &= ~TP_FLAG_TRACE; 346 + trace_probe_clear_flag(tp, TP_FLAG_TRACE); 349 347 } else 350 - tk->tp.flags &= ~TP_FLAG_PROFILE; 348 + trace_probe_clear_flag(tp, TP_FLAG_PROFILE); 351 349 352 - if (!trace_probe_is_enabled(&tk->tp) && trace_probe_is_registered(&tk->tp)) { 350 + if (!trace_probe_is_enabled(tp) && trace_kprobe_is_registered(tk)) { 353 351 if (trace_kprobe_is_return(tk)) 354 352 disable_kretprobe(&tk->rp); 355 353 else 356 354 disable_kprobe(&tk->rp.kp); 357 - wait = 1; 358 355 } 359 356 360 - /* 361 - * if tk is not added to any list, it must be a local trace_kprobe 362 - * created with perf_event_open. We don't need to wait for these 363 - * trace_kprobes 364 - */ 365 - if (list_empty(&tk->devent.list)) 366 - wait = 0; 367 357 out: 368 - if (wait) { 358 + if (file) 369 359 /* 370 - * Synchronize with kprobe_trace_func/kretprobe_trace_func 371 - * to ensure disabled (all running handlers are finished). 372 - * This is not only for kfree(), but also the caller, 373 - * trace_remove_event_call() supposes it for releasing 374 - * event_call related objects, which will be accessed in 375 - * the kprobe_trace_func/kretprobe_trace_func. 360 + * Synchronization is done in below function. For perf event, 361 + * file == NULL and perf_trace_event_unreg() calls 362 + * tracepoint_synchronize_unregister() to ensure synchronize 363 + * event. We don't need to care about it. 376 364 */ 377 - synchronize_rcu(); 378 - kfree(link); /* Ignored if link == NULL */ 379 - } 365 + trace_probe_remove_file(tp, file); 380 366 381 367 return ret; 382 368 } ··· 389 415 { 390 416 int i, ret; 391 417 392 - if (trace_probe_is_registered(&tk->tp)) 418 + if (trace_kprobe_is_registered(tk)) 393 419 return -EINVAL; 394 420 395 421 if (within_notrace_func(tk)) { ··· 415 441 else 416 442 ret = register_kprobe(&tk->rp.kp); 417 443 418 - if (ret == 0) 419 - tk->tp.flags |= TP_FLAG_REGISTERED; 420 444 return ret; 421 445 } 422 446 423 447 /* Internal unregister function - just handle k*probes and flags */ 424 448 static void __unregister_trace_kprobe(struct trace_kprobe *tk) 425 449 { 426 - if (trace_probe_is_registered(&tk->tp)) { 450 + if (trace_kprobe_is_registered(tk)) { 427 451 if (trace_kprobe_is_return(tk)) 428 452 unregister_kretprobe(&tk->rp); 429 453 else 430 454 unregister_kprobe(&tk->rp.kp); 431 - tk->tp.flags &= ~TP_FLAG_REGISTERED; 432 - /* Cleanup kprobe for reuse */ 455 + /* Cleanup kprobe for reuse and mark it unregistered */ 456 + INIT_HLIST_NODE(&tk->rp.kp.hlist); 457 + INIT_LIST_HEAD(&tk->rp.kp.list); 433 458 if (tk->rp.kp.symbol_name) 434 459 tk->rp.kp.addr = NULL; 435 460 } ··· 460 487 mutex_lock(&event_mutex); 461 488 462 489 /* Delete old (same name) event if exist */ 463 - old_tk = find_trace_kprobe(trace_event_name(&tk->tp.call), 464 - tk->tp.call.class->system); 490 + old_tk = find_trace_kprobe(trace_probe_name(&tk->tp), 491 + trace_probe_group_name(&tk->tp)); 465 492 if (old_tk) { 466 493 ret = unregister_trace_kprobe(old_tk); 467 494 if (ret < 0) ··· 514 541 ret = __register_trace_kprobe(tk); 515 542 if (ret) 516 543 pr_warn("Failed to re-register probe %s on %s: %d\n", 517 - trace_event_name(&tk->tp.call), 544 + trace_probe_name(&tk->tp), 518 545 mod->name, ret); 519 546 } 520 547 } ··· 689 716 goto error; /* This can be -ENOMEM */ 690 717 } 691 718 719 + ret = traceprobe_set_print_fmt(&tk->tp, is_return); 720 + if (ret < 0) 721 + goto error; 722 + 692 723 ret = register_trace_kprobe(tk); 693 724 if (ret) { 694 725 trace_probe_log_set_index(1); ··· 744 767 int i; 745 768 746 769 seq_putc(m, trace_kprobe_is_return(tk) ? 'r' : 'p'); 747 - seq_printf(m, ":%s/%s", tk->tp.call.class->system, 748 - trace_event_name(&tk->tp.call)); 770 + seq_printf(m, ":%s/%s", trace_probe_group_name(&tk->tp), 771 + trace_probe_name(&tk->tp)); 749 772 750 773 if (!tk->symbol) 751 774 seq_printf(m, " 0x%p", tk->rp.kp.addr); ··· 819 842 820 843 tk = to_trace_kprobe(ev); 821 844 seq_printf(m, " %-44s %15lu %15lu\n", 822 - trace_event_name(&tk->tp.call), 845 + trace_probe_name(&tk->tp), 823 846 trace_kprobe_nhit(tk), 824 847 tk->rp.kp.nmissed); 825 848 ··· 863 886 return (ret < 0) ? ret : len; 864 887 } 865 888 889 + /* Return the length of string -- including null terminal byte */ 890 + static nokprobe_inline int 891 + fetch_store_strlen_user(unsigned long addr) 892 + { 893 + const void __user *uaddr = (__force const void __user *)addr; 894 + 895 + return strnlen_unsafe_user(uaddr, MAX_STRING_SIZE); 896 + } 897 + 866 898 /* 867 899 * Fetch a null-terminated string. Caller MUST set *(u32 *)buf with max 868 900 * length and relative data location. ··· 880 894 fetch_store_string(unsigned long addr, void *dest, void *base) 881 895 { 882 896 int maxlen = get_loc_len(*(u32 *)dest); 883 - u8 *dst = get_loc_data(dest, base); 897 + void *__dest; 884 898 long ret; 885 899 886 900 if (unlikely(!maxlen)) 887 901 return -ENOMEM; 902 + 903 + __dest = get_loc_data(dest, base); 904 + 888 905 /* 889 906 * Try to get string again, since the string can be changed while 890 907 * probing. 891 908 */ 892 - ret = strncpy_from_unsafe(dst, (void *)addr, maxlen); 893 - 909 + ret = strncpy_from_unsafe(__dest, (void *)addr, maxlen); 894 910 if (ret >= 0) 895 - *(u32 *)dest = make_data_loc(ret, (void *)dst - base); 911 + *(u32 *)dest = make_data_loc(ret, __dest - base); 912 + 913 + return ret; 914 + } 915 + 916 + /* 917 + * Fetch a null-terminated string from user. Caller MUST set *(u32 *)buf 918 + * with max length and relative data location. 919 + */ 920 + static nokprobe_inline int 921 + fetch_store_string_user(unsigned long addr, void *dest, void *base) 922 + { 923 + const void __user *uaddr = (__force const void __user *)addr; 924 + int maxlen = get_loc_len(*(u32 *)dest); 925 + void *__dest; 926 + long ret; 927 + 928 + if (unlikely(!maxlen)) 929 + return -ENOMEM; 930 + 931 + __dest = get_loc_data(dest, base); 932 + 933 + ret = strncpy_from_unsafe_user(__dest, uaddr, maxlen); 934 + if (ret >= 0) 935 + *(u32 *)dest = make_data_loc(ret, __dest - base); 936 + 896 937 return ret; 897 938 } 898 939 ··· 927 914 probe_mem_read(void *dest, void *src, size_t size) 928 915 { 929 916 return probe_kernel_read(dest, src, size); 917 + } 918 + 919 + static nokprobe_inline int 920 + probe_mem_read_user(void *dest, void *src, size_t size) 921 + { 922 + const void __user *uaddr = (__force const void __user *)src; 923 + 924 + return probe_user_read(dest, uaddr, size); 930 925 } 931 926 932 927 /* Note that we don't verify it, since the code does not come from user space */ ··· 992 971 struct ring_buffer *buffer; 993 972 int size, dsize, pc; 994 973 unsigned long irq_flags; 995 - struct trace_event_call *call = &tk->tp.call; 974 + struct trace_event_call *call = trace_probe_event_call(&tk->tp); 996 975 997 976 WARN_ON(call != trace_file->event_call); 998 977 ··· 1024 1003 { 1025 1004 struct event_file_link *link; 1026 1005 1027 - list_for_each_entry_rcu(link, &tk->tp.files, list) 1006 + trace_probe_for_each_link_rcu(link, &tk->tp) 1028 1007 __kprobe_trace_func(tk, regs, link->file); 1029 1008 } 1030 1009 NOKPROBE_SYMBOL(kprobe_trace_func); ··· 1040 1019 struct ring_buffer *buffer; 1041 1020 int size, pc, dsize; 1042 1021 unsigned long irq_flags; 1043 - struct trace_event_call *call = &tk->tp.call; 1022 + struct trace_event_call *call = trace_probe_event_call(&tk->tp); 1044 1023 1045 1024 WARN_ON(call != trace_file->event_call); 1046 1025 ··· 1074 1053 { 1075 1054 struct event_file_link *link; 1076 1055 1077 - list_for_each_entry_rcu(link, &tk->tp.files, list) 1056 + trace_probe_for_each_link_rcu(link, &tk->tp) 1078 1057 __kretprobe_trace_func(tk, ri, regs, link->file); 1079 1058 } 1080 1059 NOKPROBE_SYMBOL(kretprobe_trace_func); ··· 1091 1070 field = (struct kprobe_trace_entry_head *)iter->ent; 1092 1071 tp = container_of(event, struct trace_probe, call.event); 1093 1072 1094 - trace_seq_printf(s, "%s: (", trace_event_name(&tp->call)); 1073 + trace_seq_printf(s, "%s: (", trace_probe_name(tp)); 1095 1074 1096 1075 if (!seq_print_ip_sym(s, field->ip, flags | TRACE_ITER_SYM_OFFSET)) 1097 1076 goto out; ··· 1118 1097 field = (struct kretprobe_trace_entry_head *)iter->ent; 1119 1098 tp = container_of(event, struct trace_probe, call.event); 1120 1099 1121 - trace_seq_printf(s, "%s: (", trace_event_name(&tp->call)); 1100 + trace_seq_printf(s, "%s: (", trace_probe_name(tp)); 1122 1101 1123 1102 if (!seq_print_ip_sym(s, field->ret_ip, flags | TRACE_ITER_SYM_OFFSET)) 1124 1103 goto out; ··· 1170 1149 static int 1171 1150 kprobe_perf_func(struct trace_kprobe *tk, struct pt_regs *regs) 1172 1151 { 1173 - struct trace_event_call *call = &tk->tp.call; 1152 + struct trace_event_call *call = trace_probe_event_call(&tk->tp); 1174 1153 struct kprobe_trace_entry_head *entry; 1175 1154 struct hlist_head *head; 1176 1155 int size, __size, dsize; ··· 1220 1199 kretprobe_perf_func(struct trace_kprobe *tk, struct kretprobe_instance *ri, 1221 1200 struct pt_regs *regs) 1222 1201 { 1223 - struct trace_event_call *call = &tk->tp.call; 1202 + struct trace_event_call *call = trace_probe_event_call(&tk->tp); 1224 1203 struct kretprobe_trace_entry_head *entry; 1225 1204 struct hlist_head *head; 1226 1205 int size, __size, dsize; ··· 1320 1299 1321 1300 raw_cpu_inc(*tk->nhit); 1322 1301 1323 - if (tk->tp.flags & TP_FLAG_TRACE) 1302 + if (trace_probe_test_flag(&tk->tp, TP_FLAG_TRACE)) 1324 1303 kprobe_trace_func(tk, regs); 1325 1304 #ifdef CONFIG_PERF_EVENTS 1326 - if (tk->tp.flags & TP_FLAG_PROFILE) 1305 + if (trace_probe_test_flag(&tk->tp, TP_FLAG_PROFILE)) 1327 1306 ret = kprobe_perf_func(tk, regs); 1328 1307 #endif 1329 1308 return ret; ··· 1337 1316 1338 1317 raw_cpu_inc(*tk->nhit); 1339 1318 1340 - if (tk->tp.flags & TP_FLAG_TRACE) 1319 + if (trace_probe_test_flag(&tk->tp, TP_FLAG_TRACE)) 1341 1320 kretprobe_trace_func(tk, ri, regs); 1342 1321 #ifdef CONFIG_PERF_EVENTS 1343 - if (tk->tp.flags & TP_FLAG_PROFILE) 1322 + if (trace_probe_test_flag(&tk->tp, TP_FLAG_PROFILE)) 1344 1323 kretprobe_perf_func(tk, ri, regs); 1345 1324 #endif 1346 1325 return 0; /* We don't tweek kernel, so just return 0 */ ··· 1355 1334 .trace = print_kprobe_event 1356 1335 }; 1357 1336 1358 - static inline void init_trace_event_call(struct trace_kprobe *tk, 1359 - struct trace_event_call *call) 1337 + static inline void init_trace_event_call(struct trace_kprobe *tk) 1360 1338 { 1361 - INIT_LIST_HEAD(&call->class->fields); 1339 + struct trace_event_call *call = trace_probe_event_call(&tk->tp); 1340 + 1362 1341 if (trace_kprobe_is_return(tk)) { 1363 1342 call->event.funcs = &kretprobe_funcs; 1364 1343 call->class->define_fields = kretprobe_event_define_fields; ··· 1374 1353 1375 1354 static int register_kprobe_event(struct trace_kprobe *tk) 1376 1355 { 1377 - struct trace_event_call *call = &tk->tp.call; 1378 - int ret = 0; 1356 + init_trace_event_call(tk); 1379 1357 1380 - init_trace_event_call(tk, call); 1381 - 1382 - if (traceprobe_set_print_fmt(&tk->tp, trace_kprobe_is_return(tk)) < 0) 1383 - return -ENOMEM; 1384 - ret = register_trace_event(&call->event); 1385 - if (!ret) { 1386 - kfree(call->print_fmt); 1387 - return -ENODEV; 1388 - } 1389 - ret = trace_add_event_call(call); 1390 - if (ret) { 1391 - pr_info("Failed to register kprobe event: %s\n", 1392 - trace_event_name(call)); 1393 - kfree(call->print_fmt); 1394 - unregister_trace_event(&call->event); 1395 - } 1396 - return ret; 1358 + return trace_probe_register_event_call(&tk->tp); 1397 1359 } 1398 1360 1399 1361 static int unregister_kprobe_event(struct trace_kprobe *tk) 1400 1362 { 1401 - int ret; 1402 - 1403 - /* tp->event is unregistered in trace_remove_event_call() */ 1404 - ret = trace_remove_event_call(&tk->tp.call); 1405 - if (!ret) 1406 - kfree(tk->tp.call.print_fmt); 1407 - return ret; 1363 + return trace_probe_unregister_event_call(&tk->tp); 1408 1364 } 1409 1365 1410 1366 #ifdef CONFIG_PERF_EVENTS ··· 1411 1413 return ERR_CAST(tk); 1412 1414 } 1413 1415 1414 - init_trace_event_call(tk, &tk->tp.call); 1416 + init_trace_event_call(tk); 1415 1417 1416 1418 if (traceprobe_set_print_fmt(&tk->tp, trace_kprobe_is_return(tk)) < 0) { 1417 1419 ret = -ENOMEM; ··· 1419 1421 } 1420 1422 1421 1423 ret = __register_trace_kprobe(tk); 1422 - if (ret < 0) { 1423 - kfree(tk->tp.call.print_fmt); 1424 + if (ret < 0) 1424 1425 goto error; 1425 - } 1426 1426 1427 - return &tk->tp.call; 1427 + return trace_probe_event_call(&tk->tp); 1428 1428 error: 1429 1429 free_trace_kprobe(tk); 1430 1430 return ERR_PTR(ret); ··· 1441 1445 1442 1446 __unregister_trace_kprobe(tk); 1443 1447 1444 - kfree(tk->tp.call.print_fmt); 1445 1448 free_trace_kprobe(tk); 1446 1449 } 1447 1450 #endif /* CONFIG_PERF_EVENTS */ 1451 + 1452 + static __init void enable_boot_kprobe_events(void) 1453 + { 1454 + struct trace_array *tr = top_trace_array(); 1455 + struct trace_event_file *file; 1456 + struct trace_kprobe *tk; 1457 + struct dyn_event *pos; 1458 + 1459 + mutex_lock(&event_mutex); 1460 + for_each_trace_kprobe(tk, pos) { 1461 + list_for_each_entry(file, &tr->events, list) 1462 + if (file->event_call == trace_probe_event_call(&tk->tp)) 1463 + trace_event_enable_disable(file, 1, 0); 1464 + } 1465 + mutex_unlock(&event_mutex); 1466 + } 1467 + 1468 + static __init void setup_boot_kprobe_events(void) 1469 + { 1470 + char *p, *cmd = kprobe_boot_events_buf; 1471 + int ret; 1472 + 1473 + strreplace(kprobe_boot_events_buf, ',', ' '); 1474 + 1475 + while (cmd && *cmd != '\0') { 1476 + p = strchr(cmd, ';'); 1477 + if (p) 1478 + *p++ = '\0'; 1479 + 1480 + ret = trace_run_command(cmd, create_or_delete_trace_kprobe); 1481 + if (ret) 1482 + pr_warn("Failed to add event(%d): %s\n", ret, cmd); 1483 + else 1484 + kprobe_boot_events_enabled = true; 1485 + 1486 + cmd = p; 1487 + } 1488 + 1489 + enable_boot_kprobe_events(); 1490 + } 1448 1491 1449 1492 /* Make a tracefs interface for controlling probe points */ 1450 1493 static __init int init_kprobe_trace(void) ··· 1516 1481 1517 1482 if (!entry) 1518 1483 pr_warn("Could not create tracefs 'kprobe_profile' entry\n"); 1484 + 1485 + setup_boot_kprobe_events(); 1486 + 1519 1487 return 0; 1520 1488 } 1521 1489 fs_initcall(init_kprobe_trace); ··· 1531 1493 struct trace_event_file *file; 1532 1494 1533 1495 list_for_each_entry(file, &tr->events, list) 1534 - if (file->event_call == &tk->tp.call) 1496 + if (file->event_call == trace_probe_event_call(&tk->tp)) 1535 1497 return file; 1536 1498 1537 1499 return NULL; ··· 1550 1512 1551 1513 if (tracing_is_disabled()) 1552 1514 return -ENODEV; 1515 + 1516 + if (kprobe_boot_events_enabled) { 1517 + pr_info("Skipping kprobe tests due to kprobe_event on cmdline\n"); 1518 + return 0; 1519 + } 1553 1520 1554 1521 target = kprobe_trace_selftest_target; 1555 1522
+132 -10
kernel/trace/trace_probe.c
··· 78 78 /* Special types */ 79 79 __ASSIGN_FETCH_TYPE("string", string, string, sizeof(u32), 1, 80 80 "__data_loc char[]"), 81 + __ASSIGN_FETCH_TYPE("ustring", string, string, sizeof(u32), 1, 82 + "__data_loc char[]"), 81 83 /* Basic types */ 82 84 ASSIGN_FETCH_TYPE(u8, u8, 0), 83 85 ASSIGN_FETCH_TYPE(u16, u16, 0), ··· 324 322 { 325 323 struct fetch_insn *code = *pcode; 326 324 unsigned long param; 325 + int deref = FETCH_OP_DEREF; 327 326 long offset = 0; 328 327 char *tmp; 329 328 int ret = 0; ··· 397 394 break; 398 395 399 396 case '+': /* deref memory */ 400 - arg++; /* Skip '+', because kstrtol() rejects it. */ 401 - /* fall through */ 402 397 case '-': 398 + if (arg[1] == 'u') { 399 + deref = FETCH_OP_UDEREF; 400 + arg[1] = arg[0]; 401 + arg++; 402 + } 403 + if (arg[0] == '+') 404 + arg++; /* Skip '+', because kstrtol() rejects it. */ 403 405 tmp = strchr(arg, '('); 404 406 if (!tmp) { 405 407 trace_probe_log_err(offs, DEREF_NEED_BRACE); ··· 440 432 } 441 433 *pcode = code; 442 434 443 - code->op = FETCH_OP_DEREF; 435 + code->op = deref; 444 436 code->offset = offset; 445 437 } 446 438 break; ··· 577 569 goto fail; 578 570 579 571 /* Store operation */ 580 - if (!strcmp(parg->type->name, "string")) { 581 - if (code->op != FETCH_OP_DEREF && code->op != FETCH_OP_IMM && 582 - code->op != FETCH_OP_COMM) { 572 + if (!strcmp(parg->type->name, "string") || 573 + !strcmp(parg->type->name, "ustring")) { 574 + if (code->op != FETCH_OP_DEREF && code->op != FETCH_OP_UDEREF && 575 + code->op != FETCH_OP_IMM && code->op != FETCH_OP_COMM) { 583 576 trace_probe_log_err(offset + (t ? (t - arg) : 0), 584 577 BAD_STRING); 585 578 ret = -EINVAL; 586 579 goto fail; 587 580 } 588 - if (code->op != FETCH_OP_DEREF || parg->count) { 581 + if ((code->op == FETCH_OP_IMM || code->op == FETCH_OP_COMM) || 582 + parg->count) { 589 583 /* 590 584 * IMM and COMM is pointing actual address, those must 591 585 * be kept, and if parg->count != 0, this is an array ··· 600 590 goto fail; 601 591 } 602 592 } 603 - code->op = FETCH_OP_ST_STRING; /* In DEREF case, replace it */ 593 + /* If op == DEREF, replace it with STRING */ 594 + if (!strcmp(parg->type->name, "ustring") || 595 + code->op == FETCH_OP_UDEREF) 596 + code->op = FETCH_OP_ST_USTRING; 597 + else 598 + code->op = FETCH_OP_ST_STRING; 604 599 code->size = parg->type->size; 605 600 parg->dynamic = true; 606 601 } else if (code->op == FETCH_OP_DEREF) { 607 602 code->op = FETCH_OP_ST_MEM; 603 + code->size = parg->type->size; 604 + } else if (code->op == FETCH_OP_UDEREF) { 605 + code->op = FETCH_OP_ST_UMEM; 608 606 code->size = parg->type->size; 609 607 } else { 610 608 code++; ··· 636 618 /* Loop(Array) operation */ 637 619 if (parg->count) { 638 620 if (scode->op != FETCH_OP_ST_MEM && 639 - scode->op != FETCH_OP_ST_STRING) { 621 + scode->op != FETCH_OP_ST_STRING && 622 + scode->op != FETCH_OP_ST_USTRING) { 640 623 trace_probe_log_err(offset + (t ? (t - arg) : 0), 641 624 BAD_STRING); 642 625 ret = -EINVAL; ··· 844 825 845 826 int traceprobe_set_print_fmt(struct trace_probe *tp, bool is_return) 846 827 { 828 + struct trace_event_call *call = trace_probe_event_call(tp); 847 829 int len; 848 830 char *print_fmt; 849 831 ··· 856 836 857 837 /* Second: actually write the @print_fmt */ 858 838 __set_print_fmt(tp, print_fmt, len + 1, is_return); 859 - tp->call.print_fmt = print_fmt; 839 + call->print_fmt = print_fmt; 860 840 861 841 return 0; 862 842 } ··· 883 863 if (ret) 884 864 return ret; 885 865 } 866 + return 0; 867 + } 868 + 869 + 870 + void trace_probe_cleanup(struct trace_probe *tp) 871 + { 872 + struct trace_event_call *call = trace_probe_event_call(tp); 873 + int i; 874 + 875 + for (i = 0; i < tp->nr_args; i++) 876 + traceprobe_free_probe_arg(&tp->args[i]); 877 + 878 + kfree(call->class->system); 879 + kfree(call->name); 880 + kfree(call->print_fmt); 881 + } 882 + 883 + int trace_probe_init(struct trace_probe *tp, const char *event, 884 + const char *group) 885 + { 886 + struct trace_event_call *call = trace_probe_event_call(tp); 887 + 888 + if (!event || !group) 889 + return -EINVAL; 890 + 891 + call->class = &tp->class; 892 + call->name = kstrdup(event, GFP_KERNEL); 893 + if (!call->name) 894 + return -ENOMEM; 895 + 896 + tp->class.system = kstrdup(group, GFP_KERNEL); 897 + if (!tp->class.system) { 898 + kfree(call->name); 899 + call->name = NULL; 900 + return -ENOMEM; 901 + } 902 + INIT_LIST_HEAD(&tp->files); 903 + INIT_LIST_HEAD(&tp->class.fields); 904 + 905 + return 0; 906 + } 907 + 908 + int trace_probe_register_event_call(struct trace_probe *tp) 909 + { 910 + struct trace_event_call *call = trace_probe_event_call(tp); 911 + int ret; 912 + 913 + ret = register_trace_event(&call->event); 914 + if (!ret) 915 + return -ENODEV; 916 + 917 + ret = trace_add_event_call(call); 918 + if (ret) 919 + unregister_trace_event(&call->event); 920 + 921 + return ret; 922 + } 923 + 924 + int trace_probe_add_file(struct trace_probe *tp, struct trace_event_file *file) 925 + { 926 + struct event_file_link *link; 927 + 928 + link = kmalloc(sizeof(*link), GFP_KERNEL); 929 + if (!link) 930 + return -ENOMEM; 931 + 932 + link->file = file; 933 + INIT_LIST_HEAD(&link->list); 934 + list_add_tail_rcu(&link->list, &tp->files); 935 + trace_probe_set_flag(tp, TP_FLAG_TRACE); 936 + return 0; 937 + } 938 + 939 + struct event_file_link *trace_probe_get_file_link(struct trace_probe *tp, 940 + struct trace_event_file *file) 941 + { 942 + struct event_file_link *link; 943 + 944 + trace_probe_for_each_link(link, tp) { 945 + if (link->file == file) 946 + return link; 947 + } 948 + 949 + return NULL; 950 + } 951 + 952 + int trace_probe_remove_file(struct trace_probe *tp, 953 + struct trace_event_file *file) 954 + { 955 + struct event_file_link *link; 956 + 957 + link = trace_probe_get_file_link(tp, file); 958 + if (!link) 959 + return -ENOENT; 960 + 961 + list_del_rcu(&link->list); 962 + synchronize_rcu(); 963 + kfree(link); 964 + 965 + if (list_empty(&tp->files)) 966 + trace_probe_clear_flag(tp, TP_FLAG_TRACE); 967 + 886 968 return 0; 887 969 }
+62 -17
kernel/trace/trace_probe.h
··· 55 55 /* Flags for trace_probe */ 56 56 #define TP_FLAG_TRACE 1 57 57 #define TP_FLAG_PROFILE 2 58 - #define TP_FLAG_REGISTERED 4 59 58 60 59 /* data_loc: data location, compatible with u32 */ 61 60 #define make_data_loc(len, offs) \ ··· 91 92 FETCH_OP_FOFFS, /* File offset: .immediate */ 92 93 // Stage 2 (dereference) op 93 94 FETCH_OP_DEREF, /* Dereference: .offset */ 95 + FETCH_OP_UDEREF, /* User-space Dereference: .offset */ 94 96 // Stage 3 (store) ops 95 97 FETCH_OP_ST_RAW, /* Raw: .size */ 96 98 FETCH_OP_ST_MEM, /* Mem: .offset, .size */ 99 + FETCH_OP_ST_UMEM, /* Mem: .offset, .size */ 97 100 FETCH_OP_ST_STRING, /* String: .offset, .size */ 101 + FETCH_OP_ST_USTRING, /* User String: .offset, .size */ 98 102 // Stage 4 (modify) op 99 103 FETCH_OP_MOD_BF, /* Bitfield: .basesize, .lshift, .rshift */ 100 104 // Stage 5 (loop) op ··· 237 235 struct list_head list; 238 236 }; 239 237 240 - static inline bool trace_probe_is_enabled(struct trace_probe *tp) 238 + static inline bool trace_probe_test_flag(struct trace_probe *tp, 239 + unsigned int flag) 241 240 { 242 - return !!(tp->flags & (TP_FLAG_TRACE | TP_FLAG_PROFILE)); 241 + return !!(tp->flags & flag); 243 242 } 244 243 245 - static inline bool trace_probe_is_registered(struct trace_probe *tp) 244 + static inline void trace_probe_set_flag(struct trace_probe *tp, 245 + unsigned int flag) 246 246 { 247 - return !!(tp->flags & TP_FLAG_REGISTERED); 247 + tp->flags |= flag; 248 248 } 249 + 250 + static inline void trace_probe_clear_flag(struct trace_probe *tp, 251 + unsigned int flag) 252 + { 253 + tp->flags &= ~flag; 254 + } 255 + 256 + static inline bool trace_probe_is_enabled(struct trace_probe *tp) 257 + { 258 + return trace_probe_test_flag(tp, TP_FLAG_TRACE | TP_FLAG_PROFILE); 259 + } 260 + 261 + static inline const char *trace_probe_name(struct trace_probe *tp) 262 + { 263 + return trace_event_name(&tp->call); 264 + } 265 + 266 + static inline const char *trace_probe_group_name(struct trace_probe *tp) 267 + { 268 + return tp->call.class->system; 269 + } 270 + 271 + static inline struct trace_event_call * 272 + trace_probe_event_call(struct trace_probe *tp) 273 + { 274 + return &tp->call; 275 + } 276 + 277 + static inline int trace_probe_unregister_event_call(struct trace_probe *tp) 278 + { 279 + /* tp->event is unregistered in trace_remove_event_call() */ 280 + return trace_remove_event_call(&tp->call); 281 + } 282 + 283 + static inline bool trace_probe_has_single_file(struct trace_probe *tp) 284 + { 285 + return !!list_is_singular(&tp->files); 286 + } 287 + 288 + int trace_probe_init(struct trace_probe *tp, const char *event, 289 + const char *group); 290 + void trace_probe_cleanup(struct trace_probe *tp); 291 + int trace_probe_register_event_call(struct trace_probe *tp); 292 + int trace_probe_add_file(struct trace_probe *tp, struct trace_event_file *file); 293 + int trace_probe_remove_file(struct trace_probe *tp, 294 + struct trace_event_file *file); 295 + struct event_file_link *trace_probe_get_file_link(struct trace_probe *tp, 296 + struct trace_event_file *file); 297 + 298 + #define trace_probe_for_each_link(pos, tp) \ 299 + list_for_each_entry(pos, &(tp)->files, list) 300 + #define trace_probe_for_each_link_rcu(pos, tp) \ 301 + list_for_each_entry_rcu(pos, &(tp)->files, list) 249 302 250 303 /* Check the name is good for event/group/fields */ 251 304 static inline bool is_good_name(const char *name) ··· 312 255 return false; 313 256 } 314 257 return true; 315 - } 316 - 317 - static inline struct event_file_link * 318 - find_event_file_link(struct trace_probe *tp, struct trace_event_file *file) 319 - { 320 - struct event_file_link *link; 321 - 322 - list_for_each_entry(link, &tp->files, list) 323 - if (link->file == file) 324 - return link; 325 - 326 - return NULL; 327 258 } 328 259 329 260 #define TPARG_FL_RETURN BIT(0)
+30 -6
kernel/trace/trace_probe_tmpl.h
··· 59 59 static nokprobe_inline int fetch_store_strlen(unsigned long addr); 60 60 static nokprobe_inline int 61 61 fetch_store_string(unsigned long addr, void *dest, void *base); 62 + static nokprobe_inline int fetch_store_strlen_user(unsigned long addr); 63 + static nokprobe_inline int 64 + fetch_store_string_user(unsigned long addr, void *dest, void *base); 62 65 static nokprobe_inline int 63 66 probe_mem_read(void *dest, void *src, size_t size); 67 + static nokprobe_inline int 68 + probe_mem_read_user(void *dest, void *src, size_t size); 64 69 65 70 /* From the 2nd stage, routine is same */ 66 71 static nokprobe_inline int ··· 79 74 80 75 stage2: 81 76 /* 2nd stage: dereference memory if needed */ 82 - while (code->op == FETCH_OP_DEREF) { 83 - lval = val; 84 - ret = probe_mem_read(&val, (void *)val + code->offset, 85 - sizeof(val)); 77 + do { 78 + if (code->op == FETCH_OP_DEREF) { 79 + lval = val; 80 + ret = probe_mem_read(&val, (void *)val + code->offset, 81 + sizeof(val)); 82 + } else if (code->op == FETCH_OP_UDEREF) { 83 + lval = val; 84 + ret = probe_mem_read_user(&val, 85 + (void *)val + code->offset, sizeof(val)); 86 + } else 87 + break; 86 88 if (ret) 87 89 return ret; 88 90 code++; 89 - } 91 + } while (1); 90 92 91 93 s3 = code; 92 94 stage3: ··· 101 89 if (unlikely(!dest)) { 102 90 if (code->op == FETCH_OP_ST_STRING) { 103 91 ret = fetch_store_strlen(val + code->offset); 92 + code++; 93 + goto array; 94 + } else if (code->op == FETCH_OP_ST_USTRING) { 95 + ret += fetch_store_strlen_user(val + code->offset); 104 96 code++; 105 97 goto array; 106 98 } else ··· 118 102 case FETCH_OP_ST_MEM: 119 103 probe_mem_read(dest, (void *)val + code->offset, code->size); 120 104 break; 105 + case FETCH_OP_ST_UMEM: 106 + probe_mem_read_user(dest, (void *)val + code->offset, code->size); 107 + break; 121 108 case FETCH_OP_ST_STRING: 122 109 loc = *(u32 *)dest; 123 110 ret = fetch_store_string(val + code->offset, dest, base); 111 + break; 112 + case FETCH_OP_ST_USTRING: 113 + loc = *(u32 *)dest; 114 + ret = fetch_store_string_user(val + code->offset, dest, base); 124 115 break; 125 116 default: 126 117 return -EILSEQ; ··· 146 123 total += ret; 147 124 if (++i < code->param) { 148 125 code = s3; 149 - if (s3->op != FETCH_OP_ST_STRING) { 126 + if (s3->op != FETCH_OP_ST_STRING && 127 + s3->op != FETCH_OP_ST_USTRING) { 150 128 dest += s3->size; 151 129 val += s3->size; 152 130 goto stage3;
+70 -110
kernel/trace/trace_uprobe.c
··· 140 140 141 141 return copy_from_user(dest, vaddr, size) ? -EFAULT : 0; 142 142 } 143 + 144 + static nokprobe_inline int 145 + probe_mem_read_user(void *dest, void *src, size_t size) 146 + { 147 + return probe_mem_read(dest, src, size); 148 + } 149 + 143 150 /* 144 151 * Fetch a null-terminated string. Caller MUST set *(u32 *)dest with max 145 152 * length and relative data location. ··· 183 176 return ret; 184 177 } 185 178 179 + static nokprobe_inline int 180 + fetch_store_string_user(unsigned long addr, void *dest, void *base) 181 + { 182 + return fetch_store_string(addr, dest, base); 183 + } 184 + 186 185 /* Return the length of string -- including null terminal byte */ 187 186 static nokprobe_inline int 188 187 fetch_store_strlen(unsigned long addr) ··· 202 189 len = strnlen_user(vaddr, MAX_STRING_SIZE); 203 190 204 191 return (len > MAX_STRING_SIZE) ? 0 : len; 192 + } 193 + 194 + static nokprobe_inline int 195 + fetch_store_strlen_user(unsigned long addr) 196 + { 197 + return fetch_store_strlen(addr); 205 198 } 206 199 207 200 static unsigned long translate_user_vaddr(unsigned long file_offset) ··· 289 270 { 290 271 struct trace_uprobe *tu = to_trace_uprobe(ev); 291 272 292 - return strcmp(trace_event_name(&tu->tp.call), event) == 0 && 293 - (!system || strcmp(tu->tp.call.class->system, system) == 0); 273 + return strcmp(trace_probe_name(&tu->tp), event) == 0 && 274 + (!system || strcmp(trace_probe_group_name(&tu->tp), system) == 0); 294 275 } 295 276 296 277 /* ··· 300 281 alloc_trace_uprobe(const char *group, const char *event, int nargs, bool is_ret) 301 282 { 302 283 struct trace_uprobe *tu; 303 - 304 - if (!event || !group) 305 - return ERR_PTR(-EINVAL); 284 + int ret; 306 285 307 286 tu = kzalloc(SIZEOF_TRACE_UPROBE(nargs), GFP_KERNEL); 308 287 if (!tu) 309 288 return ERR_PTR(-ENOMEM); 310 289 311 - tu->tp.call.class = &tu->tp.class; 312 - tu->tp.call.name = kstrdup(event, GFP_KERNEL); 313 - if (!tu->tp.call.name) 314 - goto error; 315 - 316 - tu->tp.class.system = kstrdup(group, GFP_KERNEL); 317 - if (!tu->tp.class.system) 290 + ret = trace_probe_init(&tu->tp, event, group); 291 + if (ret < 0) 318 292 goto error; 319 293 320 294 dyn_event_init(&tu->devent, &trace_uprobe_ops); 321 - INIT_LIST_HEAD(&tu->tp.files); 322 295 tu->consumer.handler = uprobe_dispatcher; 323 296 if (is_ret) 324 297 tu->consumer.ret_handler = uretprobe_dispatcher; ··· 318 307 return tu; 319 308 320 309 error: 321 - kfree(tu->tp.call.name); 322 310 kfree(tu); 323 311 324 - return ERR_PTR(-ENOMEM); 312 + return ERR_PTR(ret); 325 313 } 326 314 327 315 static void free_trace_uprobe(struct trace_uprobe *tu) 328 316 { 329 - int i; 330 - 331 317 if (!tu) 332 318 return; 333 319 334 - for (i = 0; i < tu->tp.nr_args; i++) 335 - traceprobe_free_probe_arg(&tu->tp.args[i]); 336 - 337 320 path_put(&tu->path); 338 - kfree(tu->tp.call.class->system); 339 - kfree(tu->tp.call.name); 321 + trace_probe_cleanup(&tu->tp); 340 322 kfree(tu->filename); 341 323 kfree(tu); 342 324 } ··· 340 336 struct trace_uprobe *tu; 341 337 342 338 for_each_trace_uprobe(tu, pos) 343 - if (strcmp(trace_event_name(&tu->tp.call), event) == 0 && 344 - strcmp(tu->tp.call.class->system, group) == 0) 339 + if (strcmp(trace_probe_name(&tu->tp), event) == 0 && 340 + strcmp(trace_probe_group_name(&tu->tp), group) == 0) 345 341 return tu; 346 342 347 343 return NULL; ··· 376 372 struct trace_uprobe *tmp, *old = NULL; 377 373 struct inode *new_inode = d_real_inode(new->path.dentry); 378 374 379 - old = find_probe_event(trace_event_name(&new->tp.call), 380 - new->tp.call.class->system); 375 + old = find_probe_event(trace_probe_name(&new->tp), 376 + trace_probe_group_name(&new->tp)); 381 377 382 378 for_each_trace_uprobe(tmp, pos) { 383 379 if ((old ? old != tmp : true) && ··· 582 578 goto error; 583 579 } 584 580 581 + ret = traceprobe_set_print_fmt(&tu->tp, is_ret_probe(tu)); 582 + if (ret < 0) 583 + goto error; 584 + 585 585 ret = register_trace_uprobe(tu); 586 586 if (!ret) 587 587 goto out; ··· 629 621 char c = is_ret_probe(tu) ? 'r' : 'p'; 630 622 int i; 631 623 632 - seq_printf(m, "%c:%s/%s %s:0x%0*lx", c, tu->tp.call.class->system, 633 - trace_event_name(&tu->tp.call), tu->filename, 624 + seq_printf(m, "%c:%s/%s %s:0x%0*lx", c, trace_probe_group_name(&tu->tp), 625 + trace_probe_name(&tu->tp), tu->filename, 634 626 (int)(sizeof(void *) * 2), tu->offset); 635 627 636 628 if (tu->ref_ctr_offset) ··· 700 692 701 693 tu = to_trace_uprobe(ev); 702 694 seq_printf(m, " %s %-44s %15lu\n", tu->filename, 703 - trace_event_name(&tu->tp.call), tu->nhit); 695 + trace_probe_name(&tu->tp), tu->nhit); 704 696 return 0; 705 697 } 706 698 ··· 826 818 struct ring_buffer *buffer; 827 819 void *data; 828 820 int size, esize; 829 - struct trace_event_call *call = &tu->tp.call; 821 + struct trace_event_call *call = trace_probe_event_call(&tu->tp); 830 822 831 823 WARN_ON(call != trace_file->event_call); 832 824 ··· 868 860 return 0; 869 861 870 862 rcu_read_lock(); 871 - list_for_each_entry_rcu(link, &tu->tp.files, list) 863 + trace_probe_for_each_link_rcu(link, &tu->tp) 872 864 __uprobe_trace_func(tu, 0, regs, ucb, dsize, link->file); 873 865 rcu_read_unlock(); 874 866 ··· 882 874 struct event_file_link *link; 883 875 884 876 rcu_read_lock(); 885 - list_for_each_entry_rcu(link, &tu->tp.files, list) 877 + trace_probe_for_each_link_rcu(link, &tu->tp) 886 878 __uprobe_trace_func(tu, func, regs, ucb, dsize, link->file); 887 879 rcu_read_unlock(); 888 880 } ··· 901 893 902 894 if (is_ret_probe(tu)) { 903 895 trace_seq_printf(s, "%s: (0x%lx <- 0x%lx)", 904 - trace_event_name(&tu->tp.call), 896 + trace_probe_name(&tu->tp), 905 897 entry->vaddr[1], entry->vaddr[0]); 906 898 data = DATAOF_TRACE_ENTRY(entry, true); 907 899 } else { 908 900 trace_seq_printf(s, "%s: (0x%lx)", 909 - trace_event_name(&tu->tp.call), 901 + trace_probe_name(&tu->tp), 910 902 entry->vaddr[0]); 911 903 data = DATAOF_TRACE_ENTRY(entry, false); 912 904 } ··· 929 921 filter_func_t filter) 930 922 { 931 923 bool enabled = trace_probe_is_enabled(&tu->tp); 932 - struct event_file_link *link = NULL; 933 924 int ret; 934 925 935 926 if (file) { 936 - if (tu->tp.flags & TP_FLAG_PROFILE) 927 + if (trace_probe_test_flag(&tu->tp, TP_FLAG_PROFILE)) 937 928 return -EINTR; 938 929 939 - link = kmalloc(sizeof(*link), GFP_KERNEL); 940 - if (!link) 941 - return -ENOMEM; 942 - 943 - link->file = file; 944 - list_add_tail_rcu(&link->list, &tu->tp.files); 945 - 946 - tu->tp.flags |= TP_FLAG_TRACE; 930 + ret = trace_probe_add_file(&tu->tp, file); 931 + if (ret < 0) 932 + return ret; 947 933 } else { 948 - if (tu->tp.flags & TP_FLAG_TRACE) 934 + if (trace_probe_test_flag(&tu->tp, TP_FLAG_TRACE)) 949 935 return -EINTR; 950 936 951 - tu->tp.flags |= TP_FLAG_PROFILE; 937 + trace_probe_set_flag(&tu->tp, TP_FLAG_PROFILE); 952 938 } 953 939 954 940 WARN_ON(!uprobe_filter_is_empty(&tu->filter)); ··· 972 970 uprobe_buffer_disable(); 973 971 974 972 err_flags: 975 - if (file) { 976 - list_del(&link->list); 977 - kfree(link); 978 - tu->tp.flags &= ~TP_FLAG_TRACE; 979 - } else { 980 - tu->tp.flags &= ~TP_FLAG_PROFILE; 981 - } 973 + if (file) 974 + trace_probe_remove_file(&tu->tp, file); 975 + else 976 + trace_probe_clear_flag(&tu->tp, TP_FLAG_PROFILE); 977 + 982 978 return ret; 983 979 } 984 980 ··· 987 987 return; 988 988 989 989 if (file) { 990 - struct event_file_link *link; 991 - 992 - link = find_event_file_link(&tu->tp, file); 993 - if (!link) 990 + if (trace_probe_remove_file(&tu->tp, file) < 0) 994 991 return; 995 992 996 - list_del_rcu(&link->list); 997 - /* synchronize with u{,ret}probe_trace_func */ 998 - synchronize_rcu(); 999 - kfree(link); 1000 - 1001 - if (!list_empty(&tu->tp.files)) 993 + if (trace_probe_is_enabled(&tu->tp)) 1002 994 return; 1003 - } 995 + } else 996 + trace_probe_clear_flag(&tu->tp, TP_FLAG_PROFILE); 1004 997 1005 998 WARN_ON(!uprobe_filter_is_empty(&tu->filter)); 1006 999 1007 1000 uprobe_unregister(tu->inode, tu->offset, &tu->consumer); 1008 1001 tu->inode = NULL; 1009 - tu->tp.flags &= file ? ~TP_FLAG_TRACE : ~TP_FLAG_PROFILE; 1010 1002 1011 1003 uprobe_buffer_disable(); 1012 1004 } ··· 1118 1126 unsigned long func, struct pt_regs *regs, 1119 1127 struct uprobe_cpu_buffer *ucb, int dsize) 1120 1128 { 1121 - struct trace_event_call *call = &tu->tp.call; 1129 + struct trace_event_call *call = trace_probe_event_call(&tu->tp); 1122 1130 struct uprobe_trace_entry_head *entry; 1123 1131 struct hlist_head *head; 1124 1132 void *data; ··· 1271 1279 ucb = uprobe_buffer_get(); 1272 1280 store_trace_args(ucb->buf, &tu->tp, regs, esize, dsize); 1273 1281 1274 - if (tu->tp.flags & TP_FLAG_TRACE) 1282 + if (trace_probe_test_flag(&tu->tp, TP_FLAG_TRACE)) 1275 1283 ret |= uprobe_trace_func(tu, regs, ucb, dsize); 1276 1284 1277 1285 #ifdef CONFIG_PERF_EVENTS 1278 - if (tu->tp.flags & TP_FLAG_PROFILE) 1286 + if (trace_probe_test_flag(&tu->tp, TP_FLAG_PROFILE)) 1279 1287 ret |= uprobe_perf_func(tu, regs, ucb, dsize); 1280 1288 #endif 1281 1289 uprobe_buffer_put(ucb); ··· 1306 1314 ucb = uprobe_buffer_get(); 1307 1315 store_trace_args(ucb->buf, &tu->tp, regs, esize, dsize); 1308 1316 1309 - if (tu->tp.flags & TP_FLAG_TRACE) 1317 + if (trace_probe_test_flag(&tu->tp, TP_FLAG_TRACE)) 1310 1318 uretprobe_trace_func(tu, func, regs, ucb, dsize); 1311 1319 1312 1320 #ifdef CONFIG_PERF_EVENTS 1313 - if (tu->tp.flags & TP_FLAG_PROFILE) 1321 + if (trace_probe_test_flag(&tu->tp, TP_FLAG_PROFILE)) 1314 1322 uretprobe_perf_func(tu, func, regs, ucb, dsize); 1315 1323 #endif 1316 1324 uprobe_buffer_put(ucb); ··· 1321 1329 .trace = print_uprobe_event 1322 1330 }; 1323 1331 1324 - static inline void init_trace_event_call(struct trace_uprobe *tu, 1325 - struct trace_event_call *call) 1332 + static inline void init_trace_event_call(struct trace_uprobe *tu) 1326 1333 { 1327 - INIT_LIST_HEAD(&call->class->fields); 1334 + struct trace_event_call *call = trace_probe_event_call(&tu->tp); 1335 + 1328 1336 call->event.funcs = &uprobe_funcs; 1329 1337 call->class->define_fields = uprobe_event_define_fields; 1330 1338 ··· 1335 1343 1336 1344 static int register_uprobe_event(struct trace_uprobe *tu) 1337 1345 { 1338 - struct trace_event_call *call = &tu->tp.call; 1339 - int ret = 0; 1346 + init_trace_event_call(tu); 1340 1347 1341 - init_trace_event_call(tu, call); 1342 - 1343 - if (traceprobe_set_print_fmt(&tu->tp, is_ret_probe(tu)) < 0) 1344 - return -ENOMEM; 1345 - 1346 - ret = register_trace_event(&call->event); 1347 - if (!ret) { 1348 - kfree(call->print_fmt); 1349 - return -ENODEV; 1350 - } 1351 - 1352 - ret = trace_add_event_call(call); 1353 - 1354 - if (ret) { 1355 - pr_info("Failed to register uprobe event: %s\n", 1356 - trace_event_name(call)); 1357 - kfree(call->print_fmt); 1358 - unregister_trace_event(&call->event); 1359 - } 1360 - 1361 - return ret; 1348 + return trace_probe_register_event_call(&tu->tp); 1362 1349 } 1363 1350 1364 1351 static int unregister_uprobe_event(struct trace_uprobe *tu) 1365 1352 { 1366 - int ret; 1367 - 1368 - /* tu->event is unregistered in trace_remove_event_call() */ 1369 - ret = trace_remove_event_call(&tu->tp.call); 1370 - if (ret) 1371 - return ret; 1372 - kfree(tu->tp.call.print_fmt); 1373 - tu->tp.call.print_fmt = NULL; 1374 - return 0; 1353 + return trace_probe_unregister_event_call(&tu->tp); 1375 1354 } 1376 1355 1377 1356 #ifdef CONFIG_PERF_EVENTS ··· 1382 1419 tu->path = path; 1383 1420 tu->ref_ctr_offset = ref_ctr_offset; 1384 1421 tu->filename = kstrdup(name, GFP_KERNEL); 1385 - init_trace_event_call(tu, &tu->tp.call); 1422 + init_trace_event_call(tu); 1386 1423 1387 1424 if (traceprobe_set_print_fmt(&tu->tp, is_ret_probe(tu)) < 0) { 1388 1425 ret = -ENOMEM; 1389 1426 goto error; 1390 1427 } 1391 1428 1392 - return &tu->tp.call; 1429 + return trace_probe_event_call(&tu->tp); 1393 1430 error: 1394 1431 free_trace_uprobe(tu); 1395 1432 return ERR_PTR(ret); ··· 1400 1437 struct trace_uprobe *tu; 1401 1438 1402 1439 tu = container_of(event_call, struct trace_uprobe, tp.call); 1403 - 1404 - kfree(tu->tp.call.print_fmt); 1405 - tu->tp.call.print_fmt = NULL; 1406 1440 1407 1441 free_trace_uprobe(tu); 1408 1442 }
+2 -2
kernel/tracepoint.c
··· 55 55 56 56 static inline void *allocate_probes(int count) 57 57 { 58 - struct tp_probes *p = kmalloc(count * sizeof(struct tracepoint_func) 59 - + sizeof(struct tp_probes), GFP_KERNEL); 58 + struct tp_probes *p = kmalloc(struct_size(p, probes, count), 59 + GFP_KERNEL); 60 60 return p == NULL ? NULL : p->probes; 61 61 } 62 62
+116 -6
mm/maccess.c
··· 6 6 #include <linux/mm.h> 7 7 #include <linux/uaccess.h> 8 8 9 + static __always_inline long 10 + probe_read_common(void *dst, const void __user *src, size_t size) 11 + { 12 + long ret; 13 + 14 + pagefault_disable(); 15 + ret = __copy_from_user_inatomic(dst, src, size); 16 + pagefault_enable(); 17 + 18 + return ret ? -EFAULT : 0; 19 + } 20 + 9 21 /** 10 - * probe_kernel_read(): safely attempt to read from a location 22 + * probe_kernel_read(): safely attempt to read from a kernel-space location 11 23 * @dst: pointer to the buffer that shall take the data 12 24 * @src: address to read from 13 25 * @size: size of the data chunk ··· 42 30 mm_segment_t old_fs = get_fs(); 43 31 44 32 set_fs(KERNEL_DS); 45 - pagefault_disable(); 46 - ret = __copy_from_user_inatomic(dst, 47 - (__force const void __user *)src, size); 48 - pagefault_enable(); 33 + ret = probe_read_common(dst, (__force const void __user *)src, size); 49 34 set_fs(old_fs); 50 35 51 - return ret ? -EFAULT : 0; 36 + return ret; 52 37 } 53 38 EXPORT_SYMBOL_GPL(probe_kernel_read); 39 + 40 + /** 41 + * probe_user_read(): safely attempt to read from a user-space location 42 + * @dst: pointer to the buffer that shall take the data 43 + * @src: address to read from. This must be a user address. 44 + * @size: size of the data chunk 45 + * 46 + * Safely read from user address @src to the buffer at @dst. If a kernel fault 47 + * happens, handle that and return -EFAULT. 48 + */ 49 + 50 + long __weak probe_user_read(void *dst, const void __user *src, size_t size) 51 + __attribute__((alias("__probe_user_read"))); 52 + 53 + long __probe_user_read(void *dst, const void __user *src, size_t size) 54 + { 55 + long ret = -EFAULT; 56 + mm_segment_t old_fs = get_fs(); 57 + 58 + set_fs(USER_DS); 59 + if (access_ok(src, size)) 60 + ret = probe_read_common(dst, src, size); 61 + set_fs(old_fs); 62 + 63 + return ret; 64 + } 65 + EXPORT_SYMBOL_GPL(probe_user_read); 54 66 55 67 /** 56 68 * probe_kernel_write(): safely attempt to write to a location ··· 102 66 return ret ? -EFAULT : 0; 103 67 } 104 68 EXPORT_SYMBOL_GPL(probe_kernel_write); 69 + 105 70 106 71 /** 107 72 * strncpy_from_unsafe: - Copy a NUL terminated string from unsafe address. ··· 142 105 set_fs(old_fs); 143 106 144 107 return ret ? -EFAULT : src - unsafe_addr; 108 + } 109 + 110 + /** 111 + * strncpy_from_unsafe_user: - Copy a NUL terminated string from unsafe user 112 + * address. 113 + * @dst: Destination address, in kernel space. This buffer must be at 114 + * least @count bytes long. 115 + * @unsafe_addr: Unsafe user address. 116 + * @count: Maximum number of bytes to copy, including the trailing NUL. 117 + * 118 + * Copies a NUL-terminated string from unsafe user address to kernel buffer. 119 + * 120 + * On success, returns the length of the string INCLUDING the trailing NUL. 121 + * 122 + * If access fails, returns -EFAULT (some data may have been copied 123 + * and the trailing NUL added). 124 + * 125 + * If @count is smaller than the length of the string, copies @count-1 bytes, 126 + * sets the last byte of @dst buffer to NUL and returns @count. 127 + */ 128 + long strncpy_from_unsafe_user(char *dst, const void __user *unsafe_addr, 129 + long count) 130 + { 131 + mm_segment_t old_fs = get_fs(); 132 + long ret; 133 + 134 + if (unlikely(count <= 0)) 135 + return 0; 136 + 137 + set_fs(USER_DS); 138 + pagefault_disable(); 139 + ret = strncpy_from_user(dst, unsafe_addr, count); 140 + pagefault_enable(); 141 + set_fs(old_fs); 142 + 143 + if (ret >= count) { 144 + ret = count; 145 + dst[ret - 1] = '\0'; 146 + } else if (ret > 0) { 147 + ret++; 148 + } 149 + 150 + return ret; 151 + } 152 + 153 + /** 154 + * strnlen_unsafe_user: - Get the size of a user string INCLUDING final NUL. 155 + * @unsafe_addr: The string to measure. 156 + * @count: Maximum count (including NUL) 157 + * 158 + * Get the size of a NUL-terminated string in user space without pagefault. 159 + * 160 + * Returns the size of the string INCLUDING the terminating NUL. 161 + * 162 + * If the string is too long, returns a number larger than @count. User 163 + * has to check the return value against "> count". 164 + * On exception (or invalid count), returns 0. 165 + * 166 + * Unlike strnlen_user, this can be used from IRQ handler etc. because 167 + * it disables pagefaults. 168 + */ 169 + long strnlen_unsafe_user(const void __user *unsafe_addr, long count) 170 + { 171 + mm_segment_t old_fs = get_fs(); 172 + int ret; 173 + 174 + set_fs(USER_DS); 175 + pagefault_disable(); 176 + ret = strnlen_user(unsafe_addr, count); 177 + pagefault_enable(); 178 + set_fs(old_fs); 179 + 180 + return ret; 145 181 }
+2 -1
tools/perf/Documentation/perf-probe.txt
··· 194 194 -------------- 195 195 Each probe argument follows below syntax. 196 196 197 - [NAME=]LOCALVAR|$retval|%REG|@SYMBOL[:TYPE] 197 + [NAME=]LOCALVAR|$retval|%REG|@SYMBOL[:TYPE][@user] 198 198 199 199 'NAME' specifies the name of this argument (optional). You can use the name of local variable, local data structure member (e.g. var->field, var.field2), local array with fixed index (e.g. array[1], var->array[0], var->pointer[2]), or kprobe-tracer argument format (e.g. $retval, %ax, etc). Note that the name of this argument will be set as the last member name if you specify a local data structure member (e.g. field2 for 'var->field1.field2'.) 200 200 '$vars' and '$params' special arguments are also available for NAME, '$vars' is expanded to the local variables (including function parameters) which can access at given probe point. '$params' is expanded to only the function parameters. 201 201 'TYPE' casts the type of this argument (optional). If omitted, perf probe automatically set the type based on debuginfo (*). Currently, basic types (u8/u16/u32/u64/s8/s16/s32/s64), hexadecimal integers (x/x8/x16/x32/x64), signedness casting (u/s), "string" and bitfield are supported. (see TYPES for detail) 202 202 On x86 systems %REG is always the short form of the register: for example %AX. %RAX or %EAX is not valid. 203 + "@user" is a special attribute which means the LOCALVAR will be treated as a user-space memory. This is only valid for kprobe event. 203 204 204 205 TYPES 205 206 -----
+11
tools/perf/util/probe-event.c
··· 1562 1562 str = tmp + 1; 1563 1563 } 1564 1564 1565 + tmp = strchr(str, '@'); 1566 + if (tmp && tmp != str && strcmp(tmp + 1, "user")) { /* user attr */ 1567 + if (!user_access_is_supported()) { 1568 + semantic_error("ftrace does not support user access\n"); 1569 + return -EINVAL; 1570 + } 1571 + *tmp = '\0'; 1572 + arg->user_access = true; 1573 + pr_debug("user_access "); 1574 + } 1575 + 1565 1576 tmp = strchr(str, ':'); 1566 1577 if (tmp) { /* Type setting */ 1567 1578 *tmp = '\0';
+2
tools/perf/util/probe-event.h
··· 37 37 struct probe_trace_arg_ref { 38 38 struct probe_trace_arg_ref *next; /* Next reference */ 39 39 long offset; /* Offset value */ 40 + bool user_access; /* User-memory access */ 40 41 }; 41 42 42 43 /* kprobe-tracer and uprobe-tracer tracing argument */ ··· 83 82 char *var; /* Variable name */ 84 83 char *type; /* Type name */ 85 84 struct perf_probe_arg_field *field; /* Structure fields */ 85 + bool user_access; /* User-memory access */ 86 86 }; 87 87 88 88 /* Perf probe probing event (point + arg) */
+7
tools/perf/util/probe-file.c
··· 1005 1005 FTRACE_README_PROBE_TYPE_X = 0, 1006 1006 FTRACE_README_KRETPROBE_OFFSET, 1007 1007 FTRACE_README_UPROBE_REF_CTR, 1008 + FTRACE_README_USER_ACCESS, 1008 1009 FTRACE_README_END, 1009 1010 }; 1010 1011 ··· 1018 1017 DEFINE_TYPE(FTRACE_README_PROBE_TYPE_X, "*type: * x8/16/32/64,*"), 1019 1018 DEFINE_TYPE(FTRACE_README_KRETPROBE_OFFSET, "*place (kretprobe): *"), 1020 1019 DEFINE_TYPE(FTRACE_README_UPROBE_REF_CTR, "*ref_ctr_offset*"), 1020 + DEFINE_TYPE(FTRACE_README_USER_ACCESS, "*[u]<offset>*"), 1021 1021 }; 1022 1022 1023 1023 static bool scan_ftrace_readme(enum ftrace_readme type) ··· 1078 1076 bool uprobe_ref_ctr_is_supported(void) 1079 1077 { 1080 1078 return scan_ftrace_readme(FTRACE_README_UPROBE_REF_CTR); 1079 + } 1080 + 1081 + bool user_access_is_supported(void) 1082 + { 1083 + return scan_ftrace_readme(FTRACE_README_USER_ACCESS); 1081 1084 }
+1
tools/perf/util/probe-file.h
··· 70 70 bool probe_type_is_available(enum probe_type type); 71 71 bool kretprobe_offset_is_supported(void); 72 72 bool uprobe_ref_ctr_is_supported(void); 73 + bool user_access_is_supported(void); 73 74 #else /* ! HAVE_LIBELF_SUPPORT */ 74 75 static inline struct probe_cache *probe_cache__new(const char *tgt __maybe_unused, struct nsinfo *nsi __maybe_unused) 75 76 {
+12 -7
tools/perf/util/probe-finder.c
··· 280 280 281 281 static int convert_variable_type(Dwarf_Die *vr_die, 282 282 struct probe_trace_arg *tvar, 283 - const char *cast) 283 + const char *cast, bool user_access) 284 284 { 285 285 struct probe_trace_arg_ref **ref_ptr = &tvar->ref; 286 286 Dwarf_Die type; ··· 320 320 pr_debug("%s type is %s.\n", 321 321 dwarf_diename(vr_die), dwarf_diename(&type)); 322 322 323 - if (cast && strcmp(cast, "string") == 0) { /* String type */ 323 + if (cast && (!strcmp(cast, "string") || !strcmp(cast, "ustring"))) { 324 + /* String type */ 324 325 ret = dwarf_tag(&type); 325 326 if (ret != DW_TAG_pointer_type && 326 327 ret != DW_TAG_array_type) { ··· 344 343 pr_warning("Out of memory error\n"); 345 344 return -ENOMEM; 346 345 } 346 + (*ref_ptr)->user_access = user_access; 347 347 } 348 348 if (!die_compare_name(&type, "char") && 349 349 !die_compare_name(&type, "unsigned char")) { ··· 399 397 static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname, 400 398 struct perf_probe_arg_field *field, 401 399 struct probe_trace_arg_ref **ref_ptr, 402 - Dwarf_Die *die_mem) 400 + Dwarf_Die *die_mem, bool user_access) 403 401 { 404 402 struct probe_trace_arg_ref *ref = *ref_ptr; 405 403 Dwarf_Die type; ··· 436 434 *ref_ptr = ref; 437 435 } 438 436 ref->offset += dwarf_bytesize(&type) * field->index; 437 + ref->user_access = user_access; 439 438 goto next; 440 439 } else if (tag == DW_TAG_pointer_type) { 441 440 /* Check the pointer and dereference */ ··· 508 505 } 509 506 } 510 507 ref->offset += (long)offs; 508 + ref->user_access = user_access; 511 509 512 510 /* If this member is unnamed, we need to reuse this field */ 513 511 if (!dwarf_diename(die_mem)) 514 512 return convert_variable_fields(die_mem, varname, field, 515 - &ref, die_mem); 513 + &ref, die_mem, user_access); 516 514 517 515 next: 518 516 /* Converting next field */ 519 517 if (field->next) 520 518 return convert_variable_fields(die_mem, field->name, 521 - field->next, &ref, die_mem); 519 + field->next, &ref, die_mem, user_access); 522 520 else 523 521 return 0; 524 522 } ··· 545 541 else if (ret == 0 && pf->pvar->field) { 546 542 ret = convert_variable_fields(vr_die, pf->pvar->var, 547 543 pf->pvar->field, &pf->tvar->ref, 548 - &die_mem); 544 + &die_mem, pf->pvar->user_access); 549 545 vr_die = &die_mem; 550 546 } 551 547 if (ret == 0) 552 - ret = convert_variable_type(vr_die, pf->tvar, pf->pvar->type); 548 + ret = convert_variable_type(vr_die, pf->tvar, pf->pvar->type, 549 + pf->pvar->user_access); 553 550 /* *expr will be cached in libdw. Don't free it. */ 554 551 return ret; 555 552 }
+32 -6
tools/testing/selftests/ftrace/ftracetest
··· 23 23 exit $1 24 24 } 25 25 26 + # default error 27 + err_ret=1 28 + 29 + # kselftest skip code is 4 30 + err_skip=4 31 + 26 32 errexit() { # message 27 33 echo "Error: $1" 1>&2 28 - exit 1 34 + exit $err_ret 29 35 } 30 36 31 37 # Ensuring user privilege ··· 122 116 } 123 117 124 118 # Parameters 125 - DEBUGFS_DIR=`grep debugfs /proc/mounts | cut -f2 -d' ' | head -1` 126 - if [ -z "$DEBUGFS_DIR" ]; then 127 - TRACING_DIR=`grep tracefs /proc/mounts | cut -f2 -d' ' | head -1` 128 - else 129 - TRACING_DIR=$DEBUGFS_DIR/tracing 119 + TRACING_DIR=`grep tracefs /proc/mounts | cut -f2 -d' ' | head -1` 120 + if [ -z "$TRACING_DIR" ]; then 121 + DEBUGFS_DIR=`grep debugfs /proc/mounts | cut -f2 -d' ' | head -1` 122 + if [ -z "$DEBUGFS_DIR" ]; then 123 + # If tracefs exists, then so does /sys/kernel/tracing 124 + if [ -d "/sys/kernel/tracing" ]; then 125 + mount -t tracefs nodev /sys/kernel/tracing || 126 + errexit "Failed to mount /sys/kernel/tracing" 127 + TRACING_DIR="/sys/kernel/tracing" 128 + # If debugfs exists, then so does /sys/kernel/debug 129 + elif [ -d "/sys/kernel/debug" ]; then 130 + mount -t debugfs nodev /sys/kernel/debug || 131 + errexit "Failed to mount /sys/kernel/debug" 132 + TRACING_DIR="/sys/kernel/debug/tracing" 133 + else 134 + err_ret=$err_skip 135 + errexit "debugfs and tracefs are not configured in this kernel" 136 + fi 137 + else 138 + TRACING_DIR="$DEBUGFS_DIR/tracing" 139 + fi 140 + fi 141 + if [ ! -d "$TRACING_DIR" ]; then 142 + err_ret=$err_skip 143 + errexit "ftrace is not configured in this kernel" 130 144 fi 131 145 132 146 TOP_DIR=`absdir $0`
+2 -2
tools/testing/selftests/ftrace/test.d/functions
··· 91 91 reset_events_filter 92 92 reset_ftrace_filter 93 93 disable_events 94 - echo > set_event_pid # event tracer is always on 95 - echo > set_ftrace_pid 94 + [ -f set_event_pid ] && echo > set_event_pid 95 + [ -f set_ftrace_pid ] && echo > set_ftrace_pid 96 96 [ -f set_ftrace_filter ] && echo | tee set_ftrace_* 97 97 [ -f set_graph_function ] && echo | tee set_graph_* 98 98 [ -f stack_trace_filter ] && echo > stack_trace_filter
+32
tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_user.tc
··· 1 + #!/bin/sh 2 + # SPDX-License-Identifier: GPL-2.0 3 + # description: Kprobe event user-memory access 4 + 5 + [ -f kprobe_events ] || exit_unsupported # this is configurable 6 + 7 + grep -q '\$arg<N>' README || exit_unresolved # depends on arch 8 + grep -A10 "fetcharg:" README | grep -q 'ustring' || exit_unsupported 9 + grep -A10 "fetcharg:" README | grep -q '\[u\]<offset>' || exit_unsupported 10 + 11 + :;: "user-memory access syntax and ustring working on user memory";: 12 + echo 'p:myevent do_sys_open path=+0($arg2):ustring path2=+u0($arg2):string' \ 13 + > kprobe_events 14 + 15 + grep myevent kprobe_events | \ 16 + grep -q 'path=+0($arg2):ustring path2=+u0($arg2):string' 17 + echo 1 > events/kprobes/myevent/enable 18 + echo > /dev/null 19 + echo 0 > events/kprobes/myevent/enable 20 + 21 + grep myevent trace | grep -q 'path="/dev/null" path2="/dev/null"' 22 + 23 + :;: "user-memory access syntax and ustring not working with kernel memory";: 24 + echo 'p:myevent vfs_symlink path=+0($arg3):ustring path2=+u0($arg3):string' \ 25 + > kprobe_events 26 + echo 1 > events/kprobes/myevent/enable 27 + ln -s foo $TMPDIR/bar 28 + echo 0 > events/kprobes/myevent/enable 29 + 30 + grep myevent trace | grep -q 'path=(fault) path2=(fault)' 31 + 32 + exit 0