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

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip

* 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (25 commits)
perf: Fix SIGIO handling
perf top: Don't stop if no kernel symtab is found
perf top: Handle kptr_restrict
perf top: Remove unused macro
perf events: initialize fd array to -1 instead of 0
perf tools: Make sure kptr_restrict warnings fit 80 col terms
perf tools: Fix build on older systems
perf symbols: Handle /proc/sys/kernel/kptr_restrict
perf: Remove duplicate headers
ftrace: Add internal recursive checks
tracing: Update btrfs's tracepoints to use u64 interface
tracing: Add __print_symbolic_u64 to avoid warnings on 32bit machine
ftrace: Set ops->flag to enabled even on static function tracing
tracing: Have event with function tracer check error return
ftrace: Have ftrace_startup() return failure code
jump_label: Check entries limit in __jump_label_update
ftrace/recordmcount: Avoid STT_FUNC symbols as base on ARM
scripts/tags.sh: Add magic for trace-events for etags too
scripts/tags.sh: Fix ctags for DEFINE_EVENT()
x86/ftrace: Fix compiler warning in ftrace.c
...

+360 -107
+2 -2
arch/blackfin/mm/maccess.c
··· 16 16 return bfin_mem_access_type(addr, size); 17 17 } 18 18 19 - long probe_kernel_read(void *dst, void *src, size_t size) 19 + long probe_kernel_read(void *dst, const void *src, size_t size) 20 20 { 21 21 unsigned long lsrc = (unsigned long)src; 22 22 int mem_type; ··· 55 55 return -EFAULT; 56 56 } 57 57 58 - long probe_kernel_write(void *dst, void *src, size_t size) 58 + long probe_kernel_write(void *dst, const void *src, size_t size) 59 59 { 60 60 unsigned long ldst = (unsigned long)dst; 61 61 int mem_type;
+2 -2
arch/s390/mm/maccess.c
··· 19 19 * using the stura instruction. 20 20 * Returns the number of bytes copied or -EFAULT. 21 21 */ 22 - static long probe_kernel_write_odd(void *dst, void *src, size_t size) 22 + static long probe_kernel_write_odd(void *dst, const void *src, size_t size) 23 23 { 24 24 unsigned long count, aligned; 25 25 int offset, mask; ··· 45 45 return rc ? rc : count; 46 46 } 47 47 48 - long probe_kernel_write(void *dst, void *src, size_t size) 48 + long probe_kernel_write(void *dst, const void *src, size_t size) 49 49 { 50 50 long copied = 0; 51 51
+6 -6
arch/x86/kernel/ftrace.c
··· 123 123 static atomic_t nmi_running = ATOMIC_INIT(0); 124 124 static int mod_code_status; /* holds return value of text write */ 125 125 static void *mod_code_ip; /* holds the IP to write to */ 126 - static void *mod_code_newcode; /* holds the text to write to the IP */ 126 + static const void *mod_code_newcode; /* holds the text to write to the IP */ 127 127 128 128 static unsigned nmi_wait_count; 129 129 static atomic_t nmi_update_count = ATOMIC_INIT(0); ··· 225 225 } 226 226 227 227 static int 228 - do_ftrace_mod_code(unsigned long ip, void *new_code) 228 + do_ftrace_mod_code(unsigned long ip, const void *new_code) 229 229 { 230 230 /* 231 231 * On x86_64, kernel text mappings are mapped read-only with ··· 266 266 } 267 267 268 268 static int 269 - ftrace_modify_code(unsigned long ip, unsigned char *old_code, 270 - unsigned char *new_code) 269 + ftrace_modify_code(unsigned long ip, unsigned const char *old_code, 270 + unsigned const char *new_code) 271 271 { 272 272 unsigned char replaced[MCOUNT_INSN_SIZE]; 273 273 ··· 301 301 int ftrace_make_nop(struct module *mod, 302 302 struct dyn_ftrace *rec, unsigned long addr) 303 303 { 304 - unsigned char *new, *old; 304 + unsigned const char *new, *old; 305 305 unsigned long ip = rec->ip; 306 306 307 307 old = ftrace_call_replace(ip, addr); ··· 312 312 313 313 int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) 314 314 { 315 - unsigned char *new, *old; 315 + unsigned const char *new, *old; 316 316 unsigned long ip = rec->ip; 317 317 318 318 old = ftrace_nop_replace();
+55 -42
arch/x86/oprofile/op_model_amd.c
··· 316 316 wrmsrl(MSR_AMD64_IBSOPCTL, 0); 317 317 } 318 318 319 - static inline int eilvt_is_available(int offset) 319 + static inline int get_eilvt(int offset) 320 320 { 321 - /* check if we may assign a vector */ 322 321 return !setup_APIC_eilvt(offset, 0, APIC_EILVT_MSG_NMI, 1); 322 + } 323 + 324 + static inline int put_eilvt(int offset) 325 + { 326 + return !setup_APIC_eilvt(offset, 0, 0, 1); 323 327 } 324 328 325 329 static inline int ibs_eilvt_valid(void) 326 330 { 327 331 int offset; 328 332 u64 val; 333 + int valid = 0; 334 + 335 + preempt_disable(); 329 336 330 337 rdmsrl(MSR_AMD64_IBSCTL, val); 331 338 offset = val & IBSCTL_LVT_OFFSET_MASK; ··· 340 333 if (!(val & IBSCTL_LVT_OFFSET_VALID)) { 341 334 pr_err(FW_BUG "cpu %d, invalid IBS interrupt offset %d (MSR%08X=0x%016llx)\n", 342 335 smp_processor_id(), offset, MSR_AMD64_IBSCTL, val); 343 - return 0; 336 + goto out; 344 337 } 345 338 346 - if (!eilvt_is_available(offset)) { 339 + if (!get_eilvt(offset)) { 347 340 pr_err(FW_BUG "cpu %d, IBS interrupt offset %d not available (MSR%08X=0x%016llx)\n", 348 341 smp_processor_id(), offset, MSR_AMD64_IBSCTL, val); 349 - return 0; 342 + goto out; 350 343 } 351 344 352 - return 1; 345 + valid = 1; 346 + out: 347 + preempt_enable(); 348 + 349 + return valid; 353 350 } 354 351 355 352 static inline int get_ibs_offset(void) ··· 611 600 612 601 static int force_ibs_eilvt_setup(void) 613 602 { 614 - int i; 603 + int offset; 615 604 int ret; 616 605 617 - /* find the next free available EILVT entry */ 618 - for (i = 1; i < 4; i++) { 619 - if (!eilvt_is_available(i)) 620 - continue; 621 - ret = setup_ibs_ctl(i); 622 - if (ret) 623 - return ret; 624 - pr_err(FW_BUG "using offset %d for IBS interrupts\n", i); 625 - return 0; 606 + /* 607 + * find the next free available EILVT entry, skip offset 0, 608 + * pin search to this cpu 609 + */ 610 + preempt_disable(); 611 + for (offset = 1; offset < APIC_EILVT_NR_MAX; offset++) { 612 + if (get_eilvt(offset)) 613 + break; 614 + } 615 + preempt_enable(); 616 + 617 + if (offset == APIC_EILVT_NR_MAX) { 618 + printk(KERN_DEBUG "No EILVT entry available\n"); 619 + return -EBUSY; 626 620 } 627 621 628 - printk(KERN_DEBUG "No EILVT entry available\n"); 629 - 630 - return -EBUSY; 631 - } 632 - 633 - static int __init_ibs_nmi(void) 634 - { 635 - int ret; 636 - 637 - if (ibs_eilvt_valid()) 638 - return 0; 639 - 640 - ret = force_ibs_eilvt_setup(); 622 + ret = setup_ibs_ctl(offset); 641 623 if (ret) 642 - return ret; 624 + goto out; 643 625 644 - if (!ibs_eilvt_valid()) 645 - return -EFAULT; 626 + if (!ibs_eilvt_valid()) { 627 + ret = -EFAULT; 628 + goto out; 629 + } 646 630 631 + pr_err(FW_BUG "using offset %d for IBS interrupts\n", offset); 647 632 pr_err(FW_BUG "workaround enabled for IBS LVT offset\n"); 648 633 649 634 return 0; 635 + out: 636 + preempt_disable(); 637 + put_eilvt(offset); 638 + preempt_enable(); 639 + return ret; 650 640 } 651 641 652 642 /* 653 643 * check and reserve APIC extended interrupt LVT offset for IBS if 654 644 * available 655 - * 656 - * init_ibs() preforms implicitly cpu-local operations, so pin this 657 - * thread to its current CPU 658 645 */ 659 646 660 647 static void init_ibs(void) 661 648 { 662 - preempt_disable(); 663 - 664 649 ibs_caps = get_ibs_caps(); 650 + 665 651 if (!ibs_caps) 652 + return; 653 + 654 + if (ibs_eilvt_valid()) 666 655 goto out; 667 656 668 - if (__init_ibs_nmi() < 0) 669 - ibs_caps = 0; 670 - else 671 - printk(KERN_INFO "oprofile: AMD IBS detected (0x%08x)\n", ibs_caps); 657 + if (!force_ibs_eilvt_setup()) 658 + goto out; 659 + 660 + /* Failed to setup ibs */ 661 + ibs_caps = 0; 662 + return; 672 663 673 664 out: 674 - preempt_enable(); 665 + printk(KERN_INFO "oprofile: AMD IBS detected (0x%08x)\n", ibs_caps); 675 666 } 676 667 677 668 static int (*create_arch_files)(struct super_block *sb, struct dentry *root);
+1 -1
drivers/oprofile/event_buffer.h
··· 11 11 #define EVENT_BUFFER_H 12 12 13 13 #include <linux/types.h> 14 - #include <asm/mutex.h> 14 + #include <linux/mutex.h> 15 15 16 16 int alloc_event_buffer(void); 17 17
+1 -1
drivers/oprofile/oprof.c
··· 14 14 #include <linux/moduleparam.h> 15 15 #include <linux/workqueue.h> 16 16 #include <linux/time.h> 17 - #include <asm/mutex.h> 17 + #include <linux/mutex.h> 18 18 19 19 #include "oprof.h" 20 20 #include "event_buffer.h"
+12
include/linux/ftrace_event.h
··· 16 16 const char *name; 17 17 }; 18 18 19 + struct trace_print_flags_u64 { 20 + unsigned long long mask; 21 + const char *name; 22 + }; 23 + 19 24 const char *ftrace_print_flags_seq(struct trace_seq *p, const char *delim, 20 25 unsigned long flags, 21 26 const struct trace_print_flags *flag_array); 22 27 23 28 const char *ftrace_print_symbols_seq(struct trace_seq *p, unsigned long val, 24 29 const struct trace_print_flags *symbol_array); 30 + 31 + #if BITS_PER_LONG == 32 32 + const char *ftrace_print_symbols_seq_u64(struct trace_seq *p, 33 + unsigned long long val, 34 + const struct trace_print_flags_u64 35 + *symbol_array); 36 + #endif 25 37 26 38 const char *ftrace_print_hex_seq(struct trace_seq *p, 27 39 const unsigned char *buf, int len);
+1 -1
include/linux/sched.h
··· 1546 1546 #ifdef CONFIG_TRACING 1547 1547 /* state flags for use by tracers */ 1548 1548 unsigned long trace; 1549 - /* bitmask of trace recursion */ 1549 + /* bitmask and counter of trace recursion */ 1550 1550 unsigned long trace_recursion; 1551 1551 #endif /* CONFIG_TRACING */ 1552 1552 #ifdef CONFIG_CGROUP_MEM_RES_CTLR /* memcg uses this to do batch job */
+4 -4
include/linux/uaccess.h
··· 93 93 * Safely read from address @src to the buffer at @dst. If a kernel fault 94 94 * happens, handle that and return -EFAULT. 95 95 */ 96 - extern long probe_kernel_read(void *dst, void *src, size_t size); 97 - extern long __probe_kernel_read(void *dst, void *src, size_t size); 96 + extern long probe_kernel_read(void *dst, const void *src, size_t size); 97 + extern long __probe_kernel_read(void *dst, const void *src, size_t size); 98 98 99 99 /* 100 100 * probe_kernel_write(): safely attempt to write to a location ··· 105 105 * Safely write to address @dst from the buffer at @src. If a kernel fault 106 106 * happens, handle that and return -EFAULT. 107 107 */ 108 - extern long notrace probe_kernel_write(void *dst, void *src, size_t size); 109 - extern long notrace __probe_kernel_write(void *dst, void *src, size_t size); 108 + extern long notrace probe_kernel_write(void *dst, const void *src, size_t size); 109 + extern long notrace __probe_kernel_write(void *dst, const void *src, size_t size); 110 110 111 111 #endif /* __LINUX_UACCESS_H__ */
+2 -2
include/trace/events/btrfs.h
··· 28 28 { BTRFS_SHARED_DATA_REF_KEY, "SHARED_DATA_REF" }) 29 29 30 30 #define __show_root_type(obj) \ 31 - __print_symbolic(obj, \ 31 + __print_symbolic_u64(obj, \ 32 32 { BTRFS_ROOT_TREE_OBJECTID, "ROOT_TREE" }, \ 33 33 { BTRFS_EXTENT_TREE_OBJECTID, "EXTENT_TREE" }, \ 34 34 { BTRFS_CHUNK_TREE_OBJECTID, "CHUNK_TREE" }, \ ··· 125 125 ); 126 126 127 127 #define __show_map_type(type) \ 128 - __print_symbolic(type, \ 128 + __print_symbolic_u64(type, \ 129 129 { EXTENT_MAP_LAST_BYTE, "LAST_BYTE" }, \ 130 130 { EXTENT_MAP_HOLE, "HOLE" }, \ 131 131 { EXTENT_MAP_INLINE, "INLINE" }, \
+13
include/trace/ftrace.h
··· 205 205 ftrace_print_symbols_seq(p, value, symbols); \ 206 206 }) 207 207 208 + #undef __print_symbolic_u64 209 + #if BITS_PER_LONG == 32 210 + #define __print_symbolic_u64(value, symbol_array...) \ 211 + ({ \ 212 + static const struct trace_print_flags_u64 symbols[] = \ 213 + { symbol_array, { -1, NULL } }; \ 214 + ftrace_print_symbols_seq_u64(p, value, symbols); \ 215 + }) 216 + #else 217 + #define __print_symbolic_u64(value, symbol_array...) \ 218 + __print_symbolic(value, symbol_array) 219 + #endif 220 + 208 221 #undef __print_hex 209 222 #define __print_hex(buf, buf_len) ftrace_print_hex_seq(p, buf, buf_len) 210 223
+8
kernel/events/core.c
··· 5028 5028 else 5029 5029 perf_event_output(event, nmi, data, regs); 5030 5030 5031 + if (event->fasync && event->pending_kill) { 5032 + if (nmi) { 5033 + event->pending_wakeup = 1; 5034 + irq_work_queue(&event->pending); 5035 + } else 5036 + perf_event_wakeup(event); 5037 + } 5038 + 5031 5039 return ret; 5032 5040 } 5033 5041
+13 -5
kernel/jump_label.c
··· 105 105 } 106 106 107 107 static void __jump_label_update(struct jump_label_key *key, 108 - struct jump_entry *entry, int enable) 108 + struct jump_entry *entry, 109 + struct jump_entry *stop, int enable) 109 110 { 110 - for (; entry->key == (jump_label_t)(unsigned long)key; entry++) { 111 + for (; (entry < stop) && 112 + (entry->key == (jump_label_t)(unsigned long)key); 113 + entry++) { 111 114 /* 112 115 * entry->code set to 0 invalidates module init text sections 113 116 * kernel_text_address() verifies we are not in core kernel ··· 184 181 struct jump_label_mod *mod = key->next; 185 182 186 183 while (mod) { 187 - __jump_label_update(key, mod->entries, enable); 184 + struct module *m = mod->mod; 185 + 186 + __jump_label_update(key, mod->entries, 187 + m->jump_entries + m->num_jump_entries, 188 + enable); 188 189 mod = mod->next; 189 190 } 190 191 } ··· 252 245 key->next = jlm; 253 246 254 247 if (jump_label_enabled(key)) 255 - __jump_label_update(key, iter, JUMP_LABEL_ENABLE); 248 + __jump_label_update(key, iter, iter_stop, 249 + JUMP_LABEL_ENABLE); 256 250 } 257 251 258 252 return 0; ··· 379 371 380 372 /* if there are no users, entry can be NULL */ 381 373 if (entry) 382 - __jump_label_update(key, entry, enable); 374 + __jump_label_update(key, entry, __stop___jump_table, enable); 383 375 384 376 #ifdef CONFIG_MODULES 385 377 __jump_label_mod_update(key, enable);
+24 -7
kernel/trace/ftrace.c
··· 109 109 static void ftrace_global_list_func(unsigned long ip, 110 110 unsigned long parent_ip) 111 111 { 112 - struct ftrace_ops *op = rcu_dereference_raw(ftrace_global_list); /*see above*/ 112 + struct ftrace_ops *op; 113 113 114 + if (unlikely(trace_recursion_test(TRACE_GLOBAL_BIT))) 115 + return; 116 + 117 + trace_recursion_set(TRACE_GLOBAL_BIT); 118 + op = rcu_dereference_raw(ftrace_global_list); /*see above*/ 114 119 while (op != &ftrace_list_end) { 115 120 op->func(ip, parent_ip); 116 121 op = rcu_dereference_raw(op->next); /*see above*/ 117 122 }; 123 + trace_recursion_clear(TRACE_GLOBAL_BIT); 118 124 } 119 125 120 126 static void ftrace_pid_func(unsigned long ip, unsigned long parent_ip) ··· 1644 1638 ftrace_run_update_code(command); 1645 1639 } 1646 1640 1647 - static void ftrace_startup(struct ftrace_ops *ops, int command) 1641 + static int ftrace_startup(struct ftrace_ops *ops, int command) 1648 1642 { 1649 1643 bool hash_enable = true; 1650 1644 1651 1645 if (unlikely(ftrace_disabled)) 1652 - return; 1646 + return -ENODEV; 1653 1647 1654 1648 ftrace_start_up++; 1655 1649 command |= FTRACE_ENABLE_CALLS; ··· 1668 1662 ftrace_hash_rec_enable(ops, 1); 1669 1663 1670 1664 ftrace_startup_enable(command); 1665 + 1666 + return 0; 1671 1667 } 1672 1668 1673 1669 static void ftrace_shutdown(struct ftrace_ops *ops, int command) ··· 2509 2501 2510 2502 ret = __register_ftrace_function(&trace_probe_ops); 2511 2503 if (!ret) 2512 - ftrace_startup(&trace_probe_ops, 0); 2504 + ret = ftrace_startup(&trace_probe_ops, 0); 2513 2505 2514 2506 ftrace_probe_registered = 1; 2515 2507 } ··· 3474 3466 static inline int ftrace_init_dyn_debugfs(struct dentry *d_tracer) { return 0; } 3475 3467 static inline void ftrace_startup_enable(int command) { } 3476 3468 /* Keep as macros so we do not need to define the commands */ 3477 - # define ftrace_startup(ops, command) do { } while (0) 3469 + # define ftrace_startup(ops, command) \ 3470 + ({ \ 3471 + (ops)->flags |= FTRACE_OPS_FL_ENABLED; \ 3472 + 0; \ 3473 + }) 3478 3474 # define ftrace_shutdown(ops, command) do { } while (0) 3479 3475 # define ftrace_startup_sysctl() do { } while (0) 3480 3476 # define ftrace_shutdown_sysctl() do { } while (0) ··· 3496 3484 { 3497 3485 struct ftrace_ops *op; 3498 3486 3487 + if (unlikely(trace_recursion_test(TRACE_INTERNAL_BIT))) 3488 + return; 3489 + 3490 + trace_recursion_set(TRACE_INTERNAL_BIT); 3499 3491 /* 3500 3492 * Some of the ops may be dynamically allocated, 3501 3493 * they must be freed after a synchronize_sched(). ··· 3512 3496 op = rcu_dereference_raw(op->next); 3513 3497 }; 3514 3498 preempt_enable_notrace(); 3499 + trace_recursion_clear(TRACE_INTERNAL_BIT); 3515 3500 } 3516 3501 3517 3502 static void clear_ftrace_swapper(void) ··· 3816 3799 3817 3800 ret = __register_ftrace_function(ops); 3818 3801 if (!ret) 3819 - ftrace_startup(ops, 0); 3802 + ret = ftrace_startup(ops, 0); 3820 3803 3821 3804 3822 3805 out_unlock: ··· 4062 4045 ftrace_graph_return = retfunc; 4063 4046 ftrace_graph_entry = entryfunc; 4064 4047 4065 - ftrace_startup(&global_ops, FTRACE_START_FUNC_RET); 4048 + ret = ftrace_startup(&global_ops, FTRACE_START_FUNC_RET); 4066 4049 4067 4050 out: 4068 4051 mutex_unlock(&ftrace_lock);
+5 -5
kernel/trace/ring_buffer.c
··· 2216 2216 2217 2217 printk_once(KERN_WARNING "Tracing recursion: depth[%ld]:" 2218 2218 "HC[%lu]:SC[%lu]:NMI[%lu]\n", 2219 - current->trace_recursion, 2219 + trace_recursion_buffer(), 2220 2220 hardirq_count() >> HARDIRQ_SHIFT, 2221 2221 softirq_count() >> SOFTIRQ_SHIFT, 2222 2222 in_nmi()); ··· 2226 2226 2227 2227 static inline int trace_recursive_lock(void) 2228 2228 { 2229 - current->trace_recursion++; 2229 + trace_recursion_inc(); 2230 2230 2231 - if (likely(current->trace_recursion < TRACE_RECURSIVE_DEPTH)) 2231 + if (likely(trace_recursion_buffer() < TRACE_RECURSIVE_DEPTH)) 2232 2232 return 0; 2233 2233 2234 2234 trace_recursive_fail(); ··· 2238 2238 2239 2239 static inline void trace_recursive_unlock(void) 2240 2240 { 2241 - WARN_ON_ONCE(!current->trace_recursion); 2241 + WARN_ON_ONCE(!trace_recursion_buffer()); 2242 2242 2243 - current->trace_recursion--; 2243 + trace_recursion_dec(); 2244 2244 } 2245 2245 2246 2246 #else
+15
kernel/trace/trace.h
··· 784 784 FTRACE_ENTRY(call, struct_name, id, PARAMS(tstruct), PARAMS(print)) 785 785 #include "trace_entries.h" 786 786 787 + /* Only current can touch trace_recursion */ 788 + #define trace_recursion_inc() do { (current)->trace_recursion++; } while (0) 789 + #define trace_recursion_dec() do { (current)->trace_recursion--; } while (0) 790 + 791 + /* Ring buffer has the 10 LSB bits to count */ 792 + #define trace_recursion_buffer() ((current)->trace_recursion & 0x3ff) 793 + 794 + /* for function tracing recursion */ 795 + #define TRACE_INTERNAL_BIT (1<<11) 796 + #define TRACE_GLOBAL_BIT (1<<12) 797 + 798 + #define trace_recursion_set(bit) do { (current)->trace_recursion |= (bit); } while (0) 799 + #define trace_recursion_clear(bit) do { (current)->trace_recursion &= ~(bit); } while (0) 800 + #define trace_recursion_test(bit) ((current)->trace_recursion & (bit)) 801 + 787 802 #endif /* _LINUX_KERNEL_TRACE_H */
+6 -1
kernel/trace/trace_events.c
··· 1657 1657 1658 1658 static __init void event_trace_self_test_with_function(void) 1659 1659 { 1660 - register_ftrace_function(&trace_ops); 1660 + int ret; 1661 + ret = register_ftrace_function(&trace_ops); 1662 + if (WARN_ON(ret < 0)) { 1663 + pr_info("Failed to enable function tracer for event tests\n"); 1664 + return; 1665 + } 1661 1666 pr_info("Running tests again, along with the function tracer\n"); 1662 1667 event_trace_self_tests(); 1663 1668 unregister_ftrace_function(&trace_ops);
+27
kernel/trace/trace_output.c
··· 353 353 } 354 354 EXPORT_SYMBOL(ftrace_print_symbols_seq); 355 355 356 + #if BITS_PER_LONG == 32 357 + const char * 358 + ftrace_print_symbols_seq_u64(struct trace_seq *p, unsigned long long val, 359 + const struct trace_print_flags_u64 *symbol_array) 360 + { 361 + int i; 362 + const char *ret = p->buffer + p->len; 363 + 364 + for (i = 0; symbol_array[i].name; i++) { 365 + 366 + if (val != symbol_array[i].mask) 367 + continue; 368 + 369 + trace_seq_puts(p, symbol_array[i].name); 370 + break; 371 + } 372 + 373 + if (!p->len) 374 + trace_seq_printf(p, "0x%llx", val); 375 + 376 + trace_seq_putc(p, 0); 377 + 378 + return ret; 379 + } 380 + EXPORT_SYMBOL(ftrace_print_symbols_seq_u64); 381 + #endif 382 + 356 383 const char * 357 384 ftrace_print_hex_seq(struct trace_seq *p, const unsigned char *buf, int buf_len) 358 385 {
+3 -6
kernel/watchdog.c
··· 415 415 #endif /* CONFIG_HARDLOCKUP_DETECTOR */ 416 416 417 417 /* prepare/enable/disable routines */ 418 - static int watchdog_prepare_cpu(int cpu) 418 + static void watchdog_prepare_cpu(int cpu) 419 419 { 420 420 struct hrtimer *hrtimer = &per_cpu(watchdog_hrtimer, cpu); 421 421 422 422 WARN_ON(per_cpu(softlockup_watchdog, cpu)); 423 423 hrtimer_init(hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); 424 424 hrtimer->function = watchdog_timer_fn; 425 - 426 - return 0; 427 425 } 428 426 429 427 static int watchdog_enable(int cpu) ··· 540 542 cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) 541 543 { 542 544 int hotcpu = (unsigned long)hcpu; 543 - int err = 0; 544 545 545 546 switch (action) { 546 547 case CPU_UP_PREPARE: 547 548 case CPU_UP_PREPARE_FROZEN: 548 - err = watchdog_prepare_cpu(hotcpu); 549 + watchdog_prepare_cpu(hotcpu); 549 550 break; 550 551 case CPU_ONLINE: 551 552 case CPU_ONLINE_FROZEN: 552 553 if (watchdog_enabled) 553 - err = watchdog_enable(hotcpu); 554 + watchdog_enable(hotcpu); 554 555 break; 555 556 #ifdef CONFIG_HOTPLUG_CPU 556 557 case CPU_UP_CANCELED:
+4 -4
mm/maccess.c
··· 15 15 * happens, handle that and return -EFAULT. 16 16 */ 17 17 18 - long __weak probe_kernel_read(void *dst, void *src, size_t size) 18 + long __weak probe_kernel_read(void *dst, const void *src, size_t size) 19 19 __attribute__((alias("__probe_kernel_read"))); 20 20 21 - long __probe_kernel_read(void *dst, void *src, size_t size) 21 + long __probe_kernel_read(void *dst, const void *src, size_t size) 22 22 { 23 23 long ret; 24 24 mm_segment_t old_fs = get_fs(); ··· 43 43 * Safely write to address @dst from the buffer at @src. If a kernel fault 44 44 * happens, handle that and return -EFAULT. 45 45 */ 46 - long __weak probe_kernel_write(void *dst, void *src, size_t size) 46 + long __weak probe_kernel_write(void *dst, const void *src, size_t size) 47 47 __attribute__((alias("__probe_kernel_write"))); 48 48 49 - long __probe_kernel_write(void *dst, void *src, size_t size) 49 + long __probe_kernel_write(void *dst, const void *src, size_t size) 50 50 { 51 51 long ret; 52 52 mm_segment_t old_fs = get_fs();
+8
scripts/recordmcount.h
··· 43 43 #undef ELF_R_INFO 44 44 #undef Elf_r_info 45 45 #undef ELF_ST_BIND 46 + #undef ELF_ST_TYPE 46 47 #undef fn_ELF_R_SYM 47 48 #undef fn_ELF_R_INFO 48 49 #undef uint_t ··· 77 76 # define ELF_R_INFO ELF64_R_INFO 78 77 # define Elf_r_info Elf64_r_info 79 78 # define ELF_ST_BIND ELF64_ST_BIND 79 + # define ELF_ST_TYPE ELF64_ST_TYPE 80 80 # define fn_ELF_R_SYM fn_ELF64_R_SYM 81 81 # define fn_ELF_R_INFO fn_ELF64_R_INFO 82 82 # define uint_t uint64_t ··· 110 108 # define ELF_R_INFO ELF32_R_INFO 111 109 # define Elf_r_info Elf32_r_info 112 110 # define ELF_ST_BIND ELF32_ST_BIND 111 + # define ELF_ST_TYPE ELF32_ST_TYPE 113 112 # define fn_ELF_R_SYM fn_ELF32_R_SYM 114 113 # define fn_ELF_R_INFO fn_ELF32_R_INFO 115 114 # define uint_t uint32_t ··· 430 427 if (txtndx == w2(symp->st_shndx) 431 428 /* avoid STB_WEAK */ 432 429 && (STB_LOCAL == st_bind || STB_GLOBAL == st_bind)) { 430 + /* function symbols on ARM have quirks, avoid them */ 431 + if (w2(ehdr->e_machine) == EM_ARM 432 + && ELF_ST_TYPE(symp->st_info) == STT_FUNC) 433 + continue; 434 + 433 435 *recvalp = _w(symp->st_value); 434 436 return symp - sym0; 435 437 }
+4 -2
scripts/tags.sh
··· 132 132 --regex-asm='/^ENTRY\(([^)]*)\).*/\1/' \ 133 133 --regex-c='/^SYSCALL_DEFINE[[:digit:]]?\(([^,)]*).*/sys_\1/' \ 134 134 --regex-c++='/^TRACE_EVENT\(([^,)]*).*/trace_\1/' \ 135 - --regex-c++='/^DEFINE_EVENT\(([^,)]*).*/trace_\1/' 135 + --regex-c++='/^DEFINE_EVENT\([^,)]*, *([^,)]*).*/trace_\1/' 136 136 137 137 all_kconfigs | xargs $1 -a \ 138 138 --langdef=kconfig --language-force=kconfig \ ··· 152 152 { 153 153 all_sources | xargs $1 -a \ 154 154 --regex='/^ENTRY(\([^)]*\)).*/\1/' \ 155 - --regex='/^SYSCALL_DEFINE[0-9]?(\([^,)]*\).*/sys_\1/' 155 + --regex='/^SYSCALL_DEFINE[0-9]?(\([^,)]*\).*/sys_\1/' \ 156 + --regex='/^TRACE_EVENT(\([^,)]*\).*/trace_\1/' \ 157 + --regex='/^DEFINE_EVENT([^,)]*, *\([^,)]*\).*/trace_\1/' 156 158 157 159 all_kconfigs | xargs $1 -a \ 158 160 --regex='/^[ \t]*\(\(menu\)*config\)[ \t]+\([a-zA-Z0-9_]+\)/\3/'
+2
tools/perf/Makefile
··· 215 215 LIB_H += ../../include/linux/perf_event.h 216 216 LIB_H += ../../include/linux/rbtree.h 217 217 LIB_H += ../../include/linux/list.h 218 + LIB_H += ../../include/linux/const.h 218 219 LIB_H += ../../include/linux/hash.h 219 220 LIB_H += ../../include/linux/stringify.h 220 221 LIB_H += util/include/linux/bitmap.h 221 222 LIB_H += util/include/linux/bitops.h 222 223 LIB_H += util/include/linux/compiler.h 224 + LIB_H += util/include/linux/const.h 223 225 LIB_H += util/include/linux/ctype.h 224 226 LIB_H += util/include/linux/kernel.h 225 227 LIB_H += util/include/linux/list.h
-2
tools/perf/builtin-annotate.c
··· 8 8 #include "builtin.h" 9 9 10 10 #include "util/util.h" 11 - 12 - #include "util/util.h" 13 11 #include "util/color.h" 14 12 #include <linux/list.h> 15 13 #include "util/cache.h"
+10
tools/perf/builtin-record.c
··· 823 823 824 824 symbol__init(); 825 825 826 + if (symbol_conf.kptr_restrict) 827 + pr_warning( 828 + "WARNING: Kernel address maps (/proc/{kallsyms,modules}) are restricted,\n" 829 + "check /proc/sys/kernel/kptr_restrict.\n\n" 830 + "Samples in kernel functions may not be resolved if a suitable vmlinux\n" 831 + "file is not found in the buildid cache or in the vmlinux path.\n\n" 832 + "Samples in kernel modules won't be resolved at all.\n\n" 833 + "If some relocation was applied (e.g. kexec) symbols may be misresolved\n" 834 + "even with a suitable vmlinux or kallsyms file.\n\n"); 835 + 826 836 if (no_buildid_cache || no_buildid) 827 837 disable_buildid_cache(); 828 838
+23
tools/perf/builtin-report.c
··· 116 116 if (al.filtered || (hide_unresolved && al.sym == NULL)) 117 117 return 0; 118 118 119 + if (al.map != NULL) 120 + al.map->dso->hit = 1; 121 + 119 122 if (perf_session__add_hist_entry(session, &al, sample, evsel)) { 120 123 pr_debug("problem incrementing symbol period, skipping event\n"); 121 124 return -1; ··· 252 249 u64 nr_samples; 253 250 struct perf_session *session; 254 251 struct perf_evsel *pos; 252 + struct map *kernel_map; 253 + struct kmap *kernel_kmap; 255 254 const char *help = "For a higher level overview, try: perf report --sort comm,dso"; 256 255 257 256 signal(SIGINT, sig_handler); ··· 272 267 ret = perf_session__process_events(session, &event_ops); 273 268 if (ret) 274 269 goto out_delete; 270 + 271 + kernel_map = session->host_machine.vmlinux_maps[MAP__FUNCTION]; 272 + kernel_kmap = map__kmap(kernel_map); 273 + if (kernel_map == NULL || 274 + (kernel_map->dso->hit && 275 + (kernel_kmap->ref_reloc_sym == NULL || 276 + kernel_kmap->ref_reloc_sym->addr == 0))) { 277 + const struct dso *kdso = kernel_map->dso; 278 + 279 + ui__warning( 280 + "Kernel address maps (/proc/{kallsyms,modules}) were restricted.\n\n" 281 + "Check /proc/sys/kernel/kptr_restrict before running 'perf record'.\n\n%s\n\n" 282 + "Samples in kernel modules can't be resolved as well.\n\n", 283 + RB_EMPTY_ROOT(&kdso->symbols[MAP__FUNCTION]) ? 284 + "As no suitable kallsyms nor vmlinux was found, kernel samples\n" 285 + "can't be resolved." : 286 + "If some relocation was applied (e.g. kexec) symbols may be misresolved."); 287 + } 275 288 276 289 if (dump_trace) { 277 290 perf_session__fprintf_nr_events(session, stdout);
-1
tools/perf/builtin-script.c
··· 10 10 #include "util/symbol.h" 11 11 #include "util/thread.h" 12 12 #include "util/trace-event.h" 13 - #include "util/parse-options.h" 14 13 #include "util/util.h" 15 14 #include "util/evlist.h" 16 15 #include "util/evsel.h"
+30 -7
tools/perf/builtin-top.c
··· 62 62 #include <linux/unistd.h> 63 63 #include <linux/types.h> 64 64 65 - #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) 66 - 67 65 static struct perf_top top = { 68 66 .count_filter = 5, 69 67 .delay_secs = 2, ··· 80 82 81 83 static int default_interval = 0; 82 84 85 + static bool kptr_restrict_warned; 86 + static bool vmlinux_warned; 83 87 static bool inherit = false; 84 88 static int realtime_prio = 0; 85 89 static bool group = false; ··· 740 740 al.filtered) 741 741 return; 742 742 743 + if (!kptr_restrict_warned && 744 + symbol_conf.kptr_restrict && 745 + al.cpumode == PERF_RECORD_MISC_KERNEL) { 746 + ui__warning( 747 + "Kernel address maps (/proc/{kallsyms,modules}) are restricted.\n\n" 748 + "Check /proc/sys/kernel/kptr_restrict.\n\n" 749 + "Kernel%s samples will not be resolved.\n", 750 + !RB_EMPTY_ROOT(&al.map->dso->symbols[MAP__FUNCTION]) ? 751 + " modules" : ""); 752 + if (use_browser <= 0) 753 + sleep(5); 754 + kptr_restrict_warned = true; 755 + } 756 + 743 757 if (al.sym == NULL) { 758 + const char *msg = "Kernel samples will not be resolved.\n"; 744 759 /* 745 760 * As we do lazy loading of symtabs we only will know if the 746 761 * specified vmlinux file is invalid when we actually have a ··· 767 752 * --hide-kernel-symbols, even if the user specifies an 768 753 * invalid --vmlinux ;-) 769 754 */ 770 - if (al.map == machine->vmlinux_maps[MAP__FUNCTION] && 755 + if (!kptr_restrict_warned && !vmlinux_warned && 756 + al.map == machine->vmlinux_maps[MAP__FUNCTION] && 771 757 RB_EMPTY_ROOT(&al.map->dso->symbols[MAP__FUNCTION])) { 772 - ui__warning("The %s file can't be used\n", 773 - symbol_conf.vmlinux_name); 774 - exit_browser(0); 775 - exit(1); 758 + if (symbol_conf.vmlinux_name) { 759 + ui__warning("The %s file can't be used.\n%s", 760 + symbol_conf.vmlinux_name, msg); 761 + } else { 762 + ui__warning("A vmlinux file was not found.\n%s", 763 + msg); 764 + } 765 + 766 + if (use_browser <= 0) 767 + sleep(5); 768 + vmlinux_warned = true; 776 769 } 777 770 778 771 return;
+12 -3
tools/perf/util/event.c
··· 553 553 goto out_problem; 554 554 555 555 perf_event__set_kernel_mmap_len(event, machine->vmlinux_maps); 556 - perf_session__set_kallsyms_ref_reloc_sym(machine->vmlinux_maps, 557 - symbol_name, 558 - event->mmap.pgoff); 556 + 557 + /* 558 + * Avoid using a zero address (kptr_restrict) for the ref reloc 559 + * symbol. Effectively having zero here means that at record 560 + * time /proc/sys/kernel/kptr_restrict was non zero. 561 + */ 562 + if (event->mmap.pgoff != 0) { 563 + perf_session__set_kallsyms_ref_reloc_sym(machine->vmlinux_maps, 564 + symbol_name, 565 + event->mmap.pgoff); 566 + } 567 + 559 568 if (machine__is_default_guest(machine)) { 560 569 /* 561 570 * preload dso of guest kernel and modules
+10
tools/perf/util/evsel.c
··· 35 35 36 36 int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads) 37 37 { 38 + int cpu, thread; 38 39 evsel->fd = xyarray__new(ncpus, nthreads, sizeof(int)); 40 + 41 + if (evsel->fd) { 42 + for (cpu = 0; cpu < ncpus; cpu++) { 43 + for (thread = 0; thread < nthreads; thread++) { 44 + FD(evsel, cpu, thread) = -1; 45 + } 46 + } 47 + } 48 + 39 49 return evsel->fd != NULL ? 0 : -ENOMEM; 40 50 } 41 51
+6 -2
tools/perf/util/header.c
··· 193 193 *linkname = malloc(size), *targetname; 194 194 int len, err = -1; 195 195 196 - if (is_kallsyms) 196 + if (is_kallsyms) { 197 + if (symbol_conf.kptr_restrict) { 198 + pr_debug("Not caching a kptr_restrict'ed /proc/kallsyms\n"); 199 + return 0; 200 + } 197 201 realname = (char *)name; 198 - else 202 + } else 199 203 realname = realpath(name, NULL); 200 204 201 205 if (realname == NULL || filename == NULL || linkname == NULL)
+1
tools/perf/util/include/linux/const.h
··· 1 + #include "../../../../include/linux/const.h"
+48
tools/perf/util/symbol.c
··· 676 676 return count + moved; 677 677 } 678 678 679 + static bool symbol__restricted_filename(const char *filename, 680 + const char *restricted_filename) 681 + { 682 + bool restricted = false; 683 + 684 + if (symbol_conf.kptr_restrict) { 685 + char *r = realpath(filename, NULL); 686 + 687 + if (r != NULL) { 688 + restricted = strcmp(r, restricted_filename) == 0; 689 + free(r); 690 + return restricted; 691 + } 692 + } 693 + 694 + return restricted; 695 + } 696 + 679 697 int dso__load_kallsyms(struct dso *dso, const char *filename, 680 698 struct map *map, symbol_filter_t filter) 681 699 { 700 + if (symbol__restricted_filename(filename, "/proc/kallsyms")) 701 + return -1; 702 + 682 703 if (dso__load_all_kallsyms(dso, filename, map) < 0) 683 704 return -1; 684 705 ··· 1811 1790 modules = path; 1812 1791 } 1813 1792 1793 + if (symbol__restricted_filename(path, "/proc/modules")) 1794 + return -1; 1795 + 1814 1796 file = fopen(modules, "r"); 1815 1797 if (file == NULL) 1816 1798 return -1; ··· 2263 2239 } 2264 2240 } 2265 2241 2242 + if (symbol__restricted_filename(filename, "/proc/kallsyms")) 2243 + return 0; 2244 + 2266 2245 if (kallsyms__parse(filename, &args, symbol__in_kernel) <= 0) 2267 2246 return 0; 2268 2247 ··· 2437 2410 return 0; 2438 2411 } 2439 2412 2413 + static bool symbol__read_kptr_restrict(void) 2414 + { 2415 + bool value = false; 2416 + 2417 + if (geteuid() != 0) { 2418 + FILE *fp = fopen("/proc/sys/kernel/kptr_restrict", "r"); 2419 + if (fp != NULL) { 2420 + char line[8]; 2421 + 2422 + if (fgets(line, sizeof(line), fp) != NULL) 2423 + value = atoi(line) != 0; 2424 + 2425 + fclose(fp); 2426 + } 2427 + } 2428 + 2429 + return value; 2430 + } 2431 + 2440 2432 int symbol__init(void) 2441 2433 { 2442 2434 const char *symfs; ··· 2501 2455 symbol_conf.symfs = ""; 2502 2456 if (symfs != symbol_conf.symfs) 2503 2457 free((void *)symfs); 2458 + 2459 + symbol_conf.kptr_restrict = symbol__read_kptr_restrict(); 2504 2460 2505 2461 symbol_conf.initialized = true; 2506 2462 return 0;
+2 -1
tools/perf/util/symbol.h
··· 75 75 use_callchain, 76 76 exclude_other, 77 77 show_cpu_utilization, 78 - initialized; 78 + initialized, 79 + kptr_restrict; 79 80 const char *vmlinux_name, 80 81 *kallsyms_name, 81 82 *source_prefix,