diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/debug/debug_core.c | 52 | ||||
| -rw-r--r-- | kernel/debug/kdb/kdb_bp.c | 37 | ||||
| -rw-r--r-- | kernel/debug/kdb/kdb_debugger.c | 4 | ||||
| -rw-r--r-- | kernel/debug/kdb/kdb_main.c | 267 | ||||
| -rw-r--r-- | kernel/debug/kdb/kdb_private.h | 3 | ||||
| -rw-r--r-- | kernel/events/core.c | 19 | ||||
| -rw-r--r-- | kernel/exit.c | 12 | ||||
| -rw-r--r-- | kernel/locking/mutex-debug.c | 2 | ||||
| -rw-r--r-- | kernel/range.c | 10 | ||||
| -rw-r--r-- | kernel/sched/core.c | 13 | ||||
| -rw-r--r-- | kernel/sched/deadline.c | 25 | ||||
| -rw-r--r-- | kernel/sched/fair.c | 6 | ||||
| -rw-r--r-- | kernel/trace/ftrace.c | 53 | ||||
| -rw-r--r-- | kernel/trace/trace.c | 1 | ||||
| -rw-r--r-- | kernel/trace/trace_events.c | 69 | ||||
| -rw-r--r-- | kernel/trace/trace_kdb.c | 4 | 
16 files changed, 365 insertions, 212 deletions
| diff --git a/kernel/debug/debug_core.c b/kernel/debug/debug_core.c index 1adf62b39b96..07ce18ca71e0 100644 --- a/kernel/debug/debug_core.c +++ b/kernel/debug/debug_core.c @@ -27,6 +27,9 @@   * version 2. This program is licensed "as is" without any warranty of any   * kind, whether express or implied.   */ + +#define pr_fmt(fmt) "KGDB: " fmt +  #include <linux/pid_namespace.h>  #include <linux/clocksource.h>  #include <linux/serial_core.h> @@ -196,8 +199,8 @@ int __weak kgdb_validate_break_address(unsigned long addr)  		return err;  	err = kgdb_arch_remove_breakpoint(&tmp);  	if (err) -		printk(KERN_ERR "KGDB: Critical breakpoint error, kernel " -		   "memory destroyed at: %lx", addr); +		pr_err("Critical breakpoint error, kernel memory destroyed at: %lx\n", +		       addr);  	return err;  } @@ -256,8 +259,8 @@ int dbg_activate_sw_breakpoints(void)  		error = kgdb_arch_set_breakpoint(&kgdb_break[i]);  		if (error) {  			ret = error; -			printk(KERN_INFO "KGDB: BP install failed: %lx", -			       kgdb_break[i].bpt_addr); +			pr_info("BP install failed: %lx\n", +				kgdb_break[i].bpt_addr);  			continue;  		} @@ -319,8 +322,8 @@ int dbg_deactivate_sw_breakpoints(void)  			continue;  		error = kgdb_arch_remove_breakpoint(&kgdb_break[i]);  		if (error) { -			printk(KERN_INFO "KGDB: BP remove failed: %lx\n", -			       kgdb_break[i].bpt_addr); +			pr_info("BP remove failed: %lx\n", +				kgdb_break[i].bpt_addr);  			ret = error;  		} @@ -367,7 +370,7 @@ int dbg_remove_all_break(void)  			goto setundefined;  		error = kgdb_arch_remove_breakpoint(&kgdb_break[i]);  		if (error) -			printk(KERN_ERR "KGDB: breakpoint remove failed: %lx\n", +			pr_err("breakpoint remove failed: %lx\n",  			       kgdb_break[i].bpt_addr);  setundefined:  		kgdb_break[i].state = BP_UNDEFINED; @@ -400,9 +403,9 @@ static int kgdb_io_ready(int print_wait)  	if (print_wait) {  #ifdef CONFIG_KGDB_KDB  		if (!dbg_kdb_mode) -			printk(KERN_CRIT "KGDB: waiting... or $3#33 for KDB\n"); +			pr_crit("waiting... or $3#33 for KDB\n");  #else -		printk(KERN_CRIT "KGDB: Waiting for remote debugger\n"); +		pr_crit("Waiting for remote debugger\n");  #endif  	}  	return 1; @@ -430,8 +433,7 @@ static int kgdb_reenter_check(struct kgdb_state *ks)  		exception_level = 0;  		kgdb_skipexception(ks->ex_vector, ks->linux_regs);  		dbg_activate_sw_breakpoints(); -		printk(KERN_CRIT "KGDB: re-enter error: breakpoint removed %lx\n", -			addr); +		pr_crit("re-enter error: breakpoint removed %lx\n", addr);  		WARN_ON_ONCE(1);  		return 1; @@ -444,7 +446,7 @@ static int kgdb_reenter_check(struct kgdb_state *ks)  		panic("Recursive entry to debugger");  	} -	printk(KERN_CRIT "KGDB: re-enter exception: ALL breakpoints killed\n"); +	pr_crit("re-enter exception: ALL breakpoints killed\n");  #ifdef CONFIG_KGDB_KDB  	/* Allow kdb to debug itself one level */  	return 0; @@ -471,6 +473,7 @@ static int kgdb_cpu_enter(struct kgdb_state *ks, struct pt_regs *regs,  	int cpu;  	int trace_on = 0;  	int online_cpus = num_online_cpus(); +	u64 time_left;  	kgdb_info[ks->cpu].enter_kgdb++;  	kgdb_info[ks->cpu].exception_state |= exception_state; @@ -595,9 +598,13 @@ return_normal:  	/*  	 * Wait for the other CPUs to be notified and be waiting for us:  	 */ -	while (kgdb_do_roundup && (atomic_read(&masters_in_kgdb) + -				atomic_read(&slaves_in_kgdb)) != online_cpus) +	time_left = loops_per_jiffy * HZ; +	while (kgdb_do_roundup && --time_left && +	       (atomic_read(&masters_in_kgdb) + atomic_read(&slaves_in_kgdb)) != +		   online_cpus)  		cpu_relax(); +	if (!time_left) +		pr_crit("KGDB: Timed out waiting for secondary CPUs.\n");  	/*  	 * At this point the primary processor is completely @@ -795,15 +802,15 @@ static struct console kgdbcons = {  static void sysrq_handle_dbg(int key)  {  	if (!dbg_io_ops) { -		printk(KERN_CRIT "ERROR: No KGDB I/O module available\n"); +		pr_crit("ERROR: No KGDB I/O module available\n");  		return;  	}  	if (!kgdb_connected) {  #ifdef CONFIG_KGDB_KDB  		if (!dbg_kdb_mode) -			printk(KERN_CRIT "KGDB or $3#33 for KDB\n"); +			pr_crit("KGDB or $3#33 for KDB\n");  #else -		printk(KERN_CRIT "Entering KGDB\n"); +		pr_crit("Entering KGDB\n");  #endif  	} @@ -945,7 +952,7 @@ static void kgdb_initial_breakpoint(void)  {  	kgdb_break_asap = 0; -	printk(KERN_CRIT "kgdb: Waiting for connection from remote gdb...\n"); +	pr_crit("Waiting for connection from remote gdb...\n");  	kgdb_breakpoint();  } @@ -964,8 +971,7 @@ int kgdb_register_io_module(struct kgdb_io *new_dbg_io_ops)  	if (dbg_io_ops) {  		spin_unlock(&kgdb_registration_lock); -		printk(KERN_ERR "kgdb: Another I/O driver is already " -				"registered with KGDB.\n"); +		pr_err("Another I/O driver is already registered with KGDB\n");  		return -EBUSY;  	} @@ -981,8 +987,7 @@ int kgdb_register_io_module(struct kgdb_io *new_dbg_io_ops)  	spin_unlock(&kgdb_registration_lock); -	printk(KERN_INFO "kgdb: Registered I/O driver %s.\n", -	       new_dbg_io_ops->name); +	pr_info("Registered I/O driver %s\n", new_dbg_io_ops->name);  	/* Arm KGDB now. */  	kgdb_register_callbacks(); @@ -1017,8 +1022,7 @@ void kgdb_unregister_io_module(struct kgdb_io *old_dbg_io_ops)  	spin_unlock(&kgdb_registration_lock); -	printk(KERN_INFO -		"kgdb: Unregistered I/O driver %s, debugger disabled.\n", +	pr_info("Unregistered I/O driver %s, debugger disabled\n",  		old_dbg_io_ops->name);  }  EXPORT_SYMBOL_GPL(kgdb_unregister_io_module); diff --git a/kernel/debug/kdb/kdb_bp.c b/kernel/debug/kdb/kdb_bp.c index b20d544f20c2..e1dbf4a2c69e 100644 --- a/kernel/debug/kdb/kdb_bp.c +++ b/kernel/debug/kdb/kdb_bp.c @@ -531,22 +531,29 @@ void __init kdb_initbptab(void)  	for (i = 0, bp = kdb_breakpoints; i < KDB_MAXBPT; i++, bp++)  		bp->bp_free = 1; -	kdb_register_repeat("bp", kdb_bp, "[<vaddr>]", -		"Set/Display breakpoints", 0, KDB_REPEAT_NO_ARGS); -	kdb_register_repeat("bl", kdb_bp, "[<vaddr>]", -		"Display breakpoints", 0, KDB_REPEAT_NO_ARGS); +	kdb_register_flags("bp", kdb_bp, "[<vaddr>]", +		"Set/Display breakpoints", 0, +		KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS); +	kdb_register_flags("bl", kdb_bp, "[<vaddr>]", +		"Display breakpoints", 0, +		KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS);  	if (arch_kgdb_ops.flags & KGDB_HW_BREAKPOINT) -		kdb_register_repeat("bph", kdb_bp, "[<vaddr>]", -		"[datar [length]|dataw [length]]   Set hw brk", 0, KDB_REPEAT_NO_ARGS); -	kdb_register_repeat("bc", kdb_bc, "<bpnum>", -		"Clear Breakpoint", 0, KDB_REPEAT_NONE); -	kdb_register_repeat("be", kdb_bc, "<bpnum>", -		"Enable Breakpoint", 0, KDB_REPEAT_NONE); -	kdb_register_repeat("bd", kdb_bc, "<bpnum>", -		"Disable Breakpoint", 0, KDB_REPEAT_NONE); - -	kdb_register_repeat("ss", kdb_ss, "", -		"Single Step", 1, KDB_REPEAT_NO_ARGS); +		kdb_register_flags("bph", kdb_bp, "[<vaddr>]", +		"[datar [length]|dataw [length]]   Set hw brk", 0, +		KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS); +	kdb_register_flags("bc", kdb_bc, "<bpnum>", +		"Clear Breakpoint", 0, +		KDB_ENABLE_FLOW_CTRL); +	kdb_register_flags("be", kdb_bc, "<bpnum>", +		"Enable Breakpoint", 0, +		KDB_ENABLE_FLOW_CTRL); +	kdb_register_flags("bd", kdb_bc, "<bpnum>", +		"Disable Breakpoint", 0, +		KDB_ENABLE_FLOW_CTRL); + +	kdb_register_flags("ss", kdb_ss, "", +		"Single Step", 1, +		KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS);  	/*  	 * Architecture dependent initialization.  	 */ diff --git a/kernel/debug/kdb/kdb_debugger.c b/kernel/debug/kdb/kdb_debugger.c index 8859ca34dcfe..15e1a7af5dd0 100644 --- a/kernel/debug/kdb/kdb_debugger.c +++ b/kernel/debug/kdb/kdb_debugger.c @@ -129,6 +129,10 @@ int kdb_stub(struct kgdb_state *ks)  		ks->pass_exception = 1;  		KDB_FLAG_SET(CATASTROPHIC);  	} +	/* set CATASTROPHIC if the system contains unresponsive processors */ +	for_each_online_cpu(i) +		if (!kgdb_info[i].enter_kgdb) +			KDB_FLAG_SET(CATASTROPHIC);  	if (KDB_STATE(SSBPT) && reason == KDB_REASON_SSTEP) {  		KDB_STATE_CLEAR(SSBPT);  		KDB_STATE_CLEAR(DOING_SS); diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c index 379650b984f8..f191bddf64b8 100644 --- a/kernel/debug/kdb/kdb_main.c +++ b/kernel/debug/kdb/kdb_main.c @@ -12,6 +12,7 @@   */  #include <linux/ctype.h> +#include <linux/types.h>  #include <linux/string.h>  #include <linux/kernel.h>  #include <linux/kmsg_dump.h> @@ -23,6 +24,7 @@  #include <linux/vmalloc.h>  #include <linux/atomic.h>  #include <linux/module.h> +#include <linux/moduleparam.h>  #include <linux/mm.h>  #include <linux/init.h>  #include <linux/kallsyms.h> @@ -42,6 +44,12 @@  #include <linux/slab.h>  #include "kdb_private.h" +#undef	MODULE_PARAM_PREFIX +#define	MODULE_PARAM_PREFIX "kdb." + +static int kdb_cmd_enabled = CONFIG_KDB_DEFAULT_ENABLE; +module_param_named(cmd_enable, kdb_cmd_enabled, int, 0600); +  #define GREP_LEN 256  char kdb_grep_string[GREP_LEN];  int kdb_grepping_flag; @@ -121,6 +129,7 @@ static kdbmsg_t kdbmsgs[] = {  	KDBMSG(BADLENGTH, "Invalid length field"),  	KDBMSG(NOBP, "No Breakpoint exists"),  	KDBMSG(BADADDR, "Invalid address"), +	KDBMSG(NOPERM, "Permission denied"),  };  #undef KDBMSG @@ -188,6 +197,26 @@ struct task_struct *kdb_curr_task(int cpu)  }  /* + * Check whether the flags of the current command and the permissions + * of the kdb console has allow a command to be run. + */ +static inline bool kdb_check_flags(kdb_cmdflags_t flags, int permissions, +				   bool no_args) +{ +	/* permissions comes from userspace so needs massaging slightly */ +	permissions &= KDB_ENABLE_MASK; +	permissions |= KDB_ENABLE_ALWAYS_SAFE; + +	/* some commands change group when launched with no arguments */ +	if (no_args) +		permissions |= permissions << KDB_ENABLE_NO_ARGS_SHIFT; + +	flags |= KDB_ENABLE_ALL; + +	return permissions & flags; +} + +/*   * kdbgetenv - This function will return the character string value of   *	an environment variable.   * Parameters: @@ -476,6 +505,15 @@ int kdbgetaddrarg(int argc, const char **argv, int *nextarg,  	kdb_symtab_t symtab;  	/* +	 * If the enable flags prohibit both arbitrary memory access +	 * and flow control then there are no reasonable grounds to +	 * provide symbol lookup. +	 */ +	if (!kdb_check_flags(KDB_ENABLE_MEM_READ | KDB_ENABLE_FLOW_CTRL, +			     kdb_cmd_enabled, false)) +		return KDB_NOPERM; + +	/*  	 * Process arguments which follow the following syntax:  	 *  	 *  symbol | numeric-address [+/- numeric-offset] @@ -641,8 +679,13 @@ static int kdb_defcmd2(const char *cmdstr, const char *argv0)  		if (!s->count)  			s->usable = 0;  		if (s->usable) -			kdb_register(s->name, kdb_exec_defcmd, -				     s->usage, s->help, 0); +			/* macros are always safe because when executed each +			 * internal command re-enters kdb_parse() and is +			 * safety checked individually. +			 */ +			kdb_register_flags(s->name, kdb_exec_defcmd, s->usage, +					   s->help, 0, +					   KDB_ENABLE_ALWAYS_SAFE);  		return 0;  	}  	if (!s->usable) @@ -1003,25 +1046,22 @@ int kdb_parse(const char *cmdstr)  	if (i < kdb_max_commands) {  		int result; + +		if (!kdb_check_flags(tp->cmd_flags, kdb_cmd_enabled, argc <= 1)) +			return KDB_NOPERM; +  		KDB_STATE_SET(CMD);  		result = (*tp->cmd_func)(argc-1, (const char **)argv);  		if (result && ignore_errors && result > KDB_CMD_GO)  			result = 0;  		KDB_STATE_CLEAR(CMD); -		switch (tp->cmd_repeat) { -		case KDB_REPEAT_NONE: -			argc = 0; -			if (argv[0]) -				*(argv[0]) = '\0'; -			break; -		case KDB_REPEAT_NO_ARGS: -			argc = 1; -			if (argv[1]) -				*(argv[1]) = '\0'; -			break; -		case KDB_REPEAT_WITH_ARGS: -			break; -		} + +		if (tp->cmd_flags & KDB_REPEAT_WITH_ARGS) +			return result; + +		argc = tp->cmd_flags & KDB_REPEAT_NO_ARGS ? 1 : 0; +		if (argv[argc]) +			*(argv[argc]) = '\0';  		return result;  	} @@ -1921,10 +1961,14 @@ static int kdb_rm(int argc, const char **argv)   */  static int kdb_sr(int argc, const char **argv)  { +	bool check_mask = +	    !kdb_check_flags(KDB_ENABLE_ALL, kdb_cmd_enabled, false); +  	if (argc != 1)  		return KDB_ARGCOUNT; +  	kdb_trap_printk++; -	__handle_sysrq(*argv[1], false); +	__handle_sysrq(*argv[1], check_mask);  	kdb_trap_printk--;  	return 0; @@ -2157,6 +2201,8 @@ static void kdb_cpu_status(void)  	for (start_cpu = -1, i = 0; i < NR_CPUS; i++) {  		if (!cpu_online(i)) {  			state = 'F';	/* cpu is offline */ +		} else if (!kgdb_info[i].enter_kgdb) { +			state = 'D';	/* cpu is online but unresponsive */  		} else {  			state = ' ';	/* cpu is responding to kdb */  			if (kdb_task_state_char(KDB_TSK(i)) == 'I') @@ -2210,7 +2256,7 @@ static int kdb_cpu(int argc, const char **argv)  	/*  	 * Validate cpunum  	 */ -	if ((cpunum > NR_CPUS) || !cpu_online(cpunum)) +	if ((cpunum > NR_CPUS) || !kgdb_info[cpunum].enter_kgdb)  		return KDB_BADCPUNUM;  	dbg_switch_cpu = cpunum; @@ -2375,6 +2421,8 @@ static int kdb_help(int argc, const char **argv)  			return 0;  		if (!kt->cmd_name)  			continue; +		if (!kdb_check_flags(kt->cmd_flags, kdb_cmd_enabled, true)) +			continue;  		if (strlen(kt->cmd_usage) > 20)  			space = "\n                                    ";  		kdb_printf("%-15.15s %-20s%s%s\n", kt->cmd_name, @@ -2629,7 +2677,7 @@ static int kdb_grep_help(int argc, const char **argv)  }  /* - * kdb_register_repeat - This function is used to register a kernel + * kdb_register_flags - This function is used to register a kernel   * 	debugger command.   * Inputs:   *	cmd	Command name @@ -2641,12 +2689,12 @@ static int kdb_grep_help(int argc, const char **argv)   *	zero for success, one if a duplicate command.   */  #define kdb_command_extend 50	/* arbitrary */ -int kdb_register_repeat(char *cmd, -			kdb_func_t func, -			char *usage, -			char *help, -			short minlen, -			kdb_repeat_t repeat) +int kdb_register_flags(char *cmd, +		       kdb_func_t func, +		       char *usage, +		       char *help, +		       short minlen, +		       kdb_cmdflags_t flags)  {  	int i;  	kdbtab_t *kp; @@ -2694,19 +2742,18 @@ int kdb_register_repeat(char *cmd,  	kp->cmd_func   = func;  	kp->cmd_usage  = usage;  	kp->cmd_help   = help; -	kp->cmd_flags  = 0;  	kp->cmd_minlen = minlen; -	kp->cmd_repeat = repeat; +	kp->cmd_flags  = flags;  	return 0;  } -EXPORT_SYMBOL_GPL(kdb_register_repeat); +EXPORT_SYMBOL_GPL(kdb_register_flags);  /*   * kdb_register - Compatibility register function for commands that do   *	not need to specify a repeat state.  Equivalent to - *	kdb_register_repeat with KDB_REPEAT_NONE. + *	kdb_register_flags with flags set to 0.   * Inputs:   *	cmd	Command name   *	func	Function to execute the command @@ -2721,8 +2768,7 @@ int kdb_register(char *cmd,  	     char *help,  	     short minlen)  { -	return kdb_register_repeat(cmd, func, usage, help, minlen, -				   KDB_REPEAT_NONE); +	return kdb_register_flags(cmd, func, usage, help, minlen, 0);  }  EXPORT_SYMBOL_GPL(kdb_register); @@ -2764,80 +2810,109 @@ static void __init kdb_inittab(void)  	for_each_kdbcmd(kp, i)  		kp->cmd_name = NULL; -	kdb_register_repeat("md", kdb_md, "<vaddr>", +	kdb_register_flags("md", kdb_md, "<vaddr>",  	  "Display Memory Contents, also mdWcN, e.g. md8c1", 1, -			    KDB_REPEAT_NO_ARGS); -	kdb_register_repeat("mdr", kdb_md, "<vaddr> <bytes>", -	  "Display Raw Memory", 0, KDB_REPEAT_NO_ARGS); -	kdb_register_repeat("mdp", kdb_md, "<paddr> <bytes>", -	  "Display Physical Memory", 0, KDB_REPEAT_NO_ARGS); -	kdb_register_repeat("mds", kdb_md, "<vaddr>", -	  "Display Memory Symbolically", 0, KDB_REPEAT_NO_ARGS); -	kdb_register_repeat("mm", kdb_mm, "<vaddr> <contents>", -	  "Modify Memory Contents", 0, KDB_REPEAT_NO_ARGS); -	kdb_register_repeat("go", kdb_go, "[<vaddr>]", -	  "Continue Execution", 1, KDB_REPEAT_NONE); -	kdb_register_repeat("rd", kdb_rd, "", -	  "Display Registers", 0, KDB_REPEAT_NONE); -	kdb_register_repeat("rm", kdb_rm, "<reg> <contents>", -	  "Modify Registers", 0, KDB_REPEAT_NONE); -	kdb_register_repeat("ef", kdb_ef, "<vaddr>", -	  "Display exception frame", 0, KDB_REPEAT_NONE); -	kdb_register_repeat("bt", kdb_bt, "[<vaddr>]", -	  "Stack traceback", 1, KDB_REPEAT_NONE); -	kdb_register_repeat("btp", kdb_bt, "<pid>", -	  "Display stack for process <pid>", 0, KDB_REPEAT_NONE); -	kdb_register_repeat("bta", kdb_bt, "[D|R|S|T|C|Z|E|U|I|M|A]", -	  "Backtrace all processes matching state flag", 0, KDB_REPEAT_NONE); -	kdb_register_repeat("btc", kdb_bt, "", -	  "Backtrace current process on each cpu", 0, KDB_REPEAT_NONE); -	kdb_register_repeat("btt", kdb_bt, "<vaddr>", +	  KDB_ENABLE_MEM_READ | KDB_REPEAT_NO_ARGS); +	kdb_register_flags("mdr", kdb_md, "<vaddr> <bytes>", +	  "Display Raw Memory", 0, +	  KDB_ENABLE_MEM_READ | KDB_REPEAT_NO_ARGS); +	kdb_register_flags("mdp", kdb_md, "<paddr> <bytes>", +	  "Display Physical Memory", 0, +	  KDB_ENABLE_MEM_READ | KDB_REPEAT_NO_ARGS); +	kdb_register_flags("mds", kdb_md, "<vaddr>", +	  "Display Memory Symbolically", 0, +	  KDB_ENABLE_MEM_READ | KDB_REPEAT_NO_ARGS); +	kdb_register_flags("mm", kdb_mm, "<vaddr> <contents>", +	  "Modify Memory Contents", 0, +	  KDB_ENABLE_MEM_WRITE | KDB_REPEAT_NO_ARGS); +	kdb_register_flags("go", kdb_go, "[<vaddr>]", +	  "Continue Execution", 1, +	  KDB_ENABLE_REG_WRITE | KDB_ENABLE_ALWAYS_SAFE_NO_ARGS); +	kdb_register_flags("rd", kdb_rd, "", +	  "Display Registers", 0, +	  KDB_ENABLE_REG_READ); +	kdb_register_flags("rm", kdb_rm, "<reg> <contents>", +	  "Modify Registers", 0, +	  KDB_ENABLE_REG_WRITE); +	kdb_register_flags("ef", kdb_ef, "<vaddr>", +	  "Display exception frame", 0, +	  KDB_ENABLE_MEM_READ); +	kdb_register_flags("bt", kdb_bt, "[<vaddr>]", +	  "Stack traceback", 1, +	  KDB_ENABLE_MEM_READ | KDB_ENABLE_INSPECT_NO_ARGS); +	kdb_register_flags("btp", kdb_bt, "<pid>", +	  "Display stack for process <pid>", 0, +	  KDB_ENABLE_INSPECT); +	kdb_register_flags("bta", kdb_bt, "[D|R|S|T|C|Z|E|U|I|M|A]", +	  "Backtrace all processes matching state flag", 0, +	  KDB_ENABLE_INSPECT); +	kdb_register_flags("btc", kdb_bt, "", +	  "Backtrace current process on each cpu", 0, +	  KDB_ENABLE_INSPECT); +	kdb_register_flags("btt", kdb_bt, "<vaddr>",  	  "Backtrace process given its struct task address", 0, -			    KDB_REPEAT_NONE); -	kdb_register_repeat("env", kdb_env, "", -	  "Show environment variables", 0, KDB_REPEAT_NONE); -	kdb_register_repeat("set", kdb_set, "", -	  "Set environment variables", 0, KDB_REPEAT_NONE); -	kdb_register_repeat("help", kdb_help, "", -	  "Display Help Message", 1, KDB_REPEAT_NONE); -	kdb_register_repeat("?", kdb_help, "", -	  "Display Help Message", 0, KDB_REPEAT_NONE); -	kdb_register_repeat("cpu", kdb_cpu, "<cpunum>", -	  "Switch to new cpu", 0, KDB_REPEAT_NONE); -	kdb_register_repeat("kgdb", kdb_kgdb, "", -	  "Enter kgdb mode", 0, KDB_REPEAT_NONE); -	kdb_register_repeat("ps", kdb_ps, "[<flags>|A]", -	  "Display active task list", 0, KDB_REPEAT_NONE); -	kdb_register_repeat("pid", kdb_pid, "<pidnum>", -	  "Switch to another task", 0, KDB_REPEAT_NONE); -	kdb_register_repeat("reboot", kdb_reboot, "", -	  "Reboot the machine immediately", 0, KDB_REPEAT_NONE); +	  KDB_ENABLE_MEM_READ | KDB_ENABLE_INSPECT_NO_ARGS); +	kdb_register_flags("env", kdb_env, "", +	  "Show environment variables", 0, +	  KDB_ENABLE_ALWAYS_SAFE); +	kdb_register_flags("set", kdb_set, "", +	  "Set environment variables", 0, +	  KDB_ENABLE_ALWAYS_SAFE); +	kdb_register_flags("help", kdb_help, "", +	  "Display Help Message", 1, +	  KDB_ENABLE_ALWAYS_SAFE); +	kdb_register_flags("?", kdb_help, "", +	  "Display Help Message", 0, +	  KDB_ENABLE_ALWAYS_SAFE); +	kdb_register_flags("cpu", kdb_cpu, "<cpunum>", +	  "Switch to new cpu", 0, +	  KDB_ENABLE_ALWAYS_SAFE_NO_ARGS); +	kdb_register_flags("kgdb", kdb_kgdb, "", +	  "Enter kgdb mode", 0, 0); +	kdb_register_flags("ps", kdb_ps, "[<flags>|A]", +	  "Display active task list", 0, +	  KDB_ENABLE_INSPECT); +	kdb_register_flags("pid", kdb_pid, "<pidnum>", +	  "Switch to another task", 0, +	  KDB_ENABLE_INSPECT); +	kdb_register_flags("reboot", kdb_reboot, "", +	  "Reboot the machine immediately", 0, +	  KDB_ENABLE_REBOOT);  #if defined(CONFIG_MODULES) -	kdb_register_repeat("lsmod", kdb_lsmod, "", -	  "List loaded kernel modules", 0, KDB_REPEAT_NONE); +	kdb_register_flags("lsmod", kdb_lsmod, "", +	  "List loaded kernel modules", 0, +	  KDB_ENABLE_INSPECT);  #endif  #if defined(CONFIG_MAGIC_SYSRQ) -	kdb_register_repeat("sr", kdb_sr, "<key>", -	  "Magic SysRq key", 0, KDB_REPEAT_NONE); +	kdb_register_flags("sr", kdb_sr, "<key>", +	  "Magic SysRq key", 0, +	  KDB_ENABLE_ALWAYS_SAFE);  #endif  #if defined(CONFIG_PRINTK) -	kdb_register_repeat("dmesg", kdb_dmesg, "[lines]", -	  "Display syslog buffer", 0, KDB_REPEAT_NONE); +	kdb_register_flags("dmesg", kdb_dmesg, "[lines]", +	  "Display syslog buffer", 0, +	  KDB_ENABLE_ALWAYS_SAFE);  #endif  	if (arch_kgdb_ops.enable_nmi) { -		kdb_register_repeat("disable_nmi", kdb_disable_nmi, "", -		  "Disable NMI entry to KDB", 0, KDB_REPEAT_NONE); -	} -	kdb_register_repeat("defcmd", kdb_defcmd, "name \"usage\" \"help\"", -	  "Define a set of commands, down to endefcmd", 0, KDB_REPEAT_NONE); -	kdb_register_repeat("kill", kdb_kill, "<-signal> <pid>", -	  "Send a signal to a process", 0, KDB_REPEAT_NONE); -	kdb_register_repeat("summary", kdb_summary, "", -	  "Summarize the system", 4, KDB_REPEAT_NONE); -	kdb_register_repeat("per_cpu", kdb_per_cpu, "<sym> [<bytes>] [<cpu>]", -	  "Display per_cpu variables", 3, KDB_REPEAT_NONE); -	kdb_register_repeat("grephelp", kdb_grep_help, "", -	  "Display help on | grep", 0, KDB_REPEAT_NONE); +		kdb_register_flags("disable_nmi", kdb_disable_nmi, "", +		  "Disable NMI entry to KDB", 0, +		  KDB_ENABLE_ALWAYS_SAFE); +	} +	kdb_register_flags("defcmd", kdb_defcmd, "name \"usage\" \"help\"", +	  "Define a set of commands, down to endefcmd", 0, +	  KDB_ENABLE_ALWAYS_SAFE); +	kdb_register_flags("kill", kdb_kill, "<-signal> <pid>", +	  "Send a signal to a process", 0, +	  KDB_ENABLE_SIGNAL); +	kdb_register_flags("summary", kdb_summary, "", +	  "Summarize the system", 4, +	  KDB_ENABLE_ALWAYS_SAFE); +	kdb_register_flags("per_cpu", kdb_per_cpu, "<sym> [<bytes>] [<cpu>]", +	  "Display per_cpu variables", 3, +	  KDB_ENABLE_MEM_READ); +	kdb_register_flags("grephelp", kdb_grep_help, "", +	  "Display help on | grep", 0, +	  KDB_ENABLE_ALWAYS_SAFE);  }  /* Execute any commands defined in kdb_cmds.  */ diff --git a/kernel/debug/kdb/kdb_private.h b/kernel/debug/kdb/kdb_private.h index 7afd3c8c41d5..eaacd1693954 100644 --- a/kernel/debug/kdb/kdb_private.h +++ b/kernel/debug/kdb/kdb_private.h @@ -172,10 +172,9 @@ typedef struct _kdbtab {  	kdb_func_t cmd_func;		/* Function to execute command */  	char    *cmd_usage;		/* Usage String for this command */  	char    *cmd_help;		/* Help message for this command */ -	short    cmd_flags;		/* Parsing flags */  	short    cmd_minlen;		/* Minimum legal # command  					 * chars required */ -	kdb_repeat_t cmd_repeat;	/* Does command auto repeat on enter? */ +	kdb_cmdflags_t cmd_flags;	/* Command behaviour flags */  } kdbtab_t;  extern int kdb_bt(int, const char **);	/* KDB display back trace */ diff --git a/kernel/events/core.c b/kernel/events/core.c index 4c1ee7f2bebc..882f835a0d85 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -4461,18 +4461,14 @@ perf_output_sample_regs(struct perf_output_handle *handle,  }  static void perf_sample_regs_user(struct perf_regs *regs_user, -				  struct pt_regs *regs) +				  struct pt_regs *regs, +				  struct pt_regs *regs_user_copy)  { -	if (!user_mode(regs)) { -		if (current->mm) -			regs = task_pt_regs(current); -		else -			regs = NULL; -	} - -	if (regs) { -		regs_user->abi  = perf_reg_abi(current); +	if (user_mode(regs)) { +		regs_user->abi = perf_reg_abi(current);  		regs_user->regs = regs; +	} else if (current->mm) { +		perf_get_regs_user(regs_user, regs, regs_user_copy);  	} else {  		regs_user->abi = PERF_SAMPLE_REGS_ABI_NONE;  		regs_user->regs = NULL; @@ -4951,7 +4947,8 @@ void perf_prepare_sample(struct perf_event_header *header,  	}  	if (sample_type & (PERF_SAMPLE_REGS_USER | PERF_SAMPLE_STACK_USER)) -		perf_sample_regs_user(&data->regs_user, regs); +		perf_sample_regs_user(&data->regs_user, regs, +				      &data->regs_user_copy);  	if (sample_type & PERF_SAMPLE_REGS_USER) {  		/* regs dump ABI info */ diff --git a/kernel/exit.c b/kernel/exit.c index 1ea4369890a3..6806c55475ee 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -1287,9 +1287,15 @@ static int wait_task_continued(struct wait_opts *wo, struct task_struct *p)  static int wait_consider_task(struct wait_opts *wo, int ptrace,  				struct task_struct *p)  { +	/* +	 * We can race with wait_task_zombie() from another thread. +	 * Ensure that EXIT_ZOMBIE -> EXIT_DEAD/EXIT_TRACE transition +	 * can't confuse the checks below. +	 */ +	int exit_state = ACCESS_ONCE(p->exit_state);  	int ret; -	if (unlikely(p->exit_state == EXIT_DEAD)) +	if (unlikely(exit_state == EXIT_DEAD))  		return 0;  	ret = eligible_child(wo, p); @@ -1310,7 +1316,7 @@ static int wait_consider_task(struct wait_opts *wo, int ptrace,  		return 0;  	} -	if (unlikely(p->exit_state == EXIT_TRACE)) { +	if (unlikely(exit_state == EXIT_TRACE)) {  		/*  		 * ptrace == 0 means we are the natural parent. In this case  		 * we should clear notask_error, debugger will notify us. @@ -1337,7 +1343,7 @@ static int wait_consider_task(struct wait_opts *wo, int ptrace,  	}  	/* slay zombie? */ -	if (p->exit_state == EXIT_ZOMBIE) { +	if (exit_state == EXIT_ZOMBIE) {  		/* we don't reap group leaders with subthreads */  		if (!delay_group_leader(p)) {  			/* diff --git a/kernel/locking/mutex-debug.c b/kernel/locking/mutex-debug.c index 5cf6731b98e9..3ef3736002d8 100644 --- a/kernel/locking/mutex-debug.c +++ b/kernel/locking/mutex-debug.c @@ -80,13 +80,13 @@ void debug_mutex_unlock(struct mutex *lock)  			DEBUG_LOCKS_WARN_ON(lock->owner != current);  		DEBUG_LOCKS_WARN_ON(!lock->wait_list.prev && !lock->wait_list.next); -		mutex_clear_owner(lock);  	}  	/*  	 * __mutex_slowpath_needs_to_unlock() is explicitly 0 for debug  	 * mutexes so that we can do it here after we've verified state.  	 */ +	mutex_clear_owner(lock);  	atomic_set(&lock->count, 1);  } diff --git a/kernel/range.c b/kernel/range.c index 322ea8e93e4b..82cfc285b046 100644 --- a/kernel/range.c +++ b/kernel/range.c @@ -113,12 +113,12 @@ static int cmp_range(const void *x1, const void *x2)  {  	const struct range *r1 = x1;  	const struct range *r2 = x2; -	s64 start1, start2; -	start1 = r1->start; -	start2 = r2->start; - -	return start1 - start2; +	if (r1->start < r2->start) +		return -1; +	if (r1->start > r2->start) +		return 1; +	return 0;  }  int clean_sort_range(struct range *range, int az) diff --git a/kernel/sched/core.c b/kernel/sched/core.c index b5797b78add6..c0accc00566e 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -7113,9 +7113,6 @@ void __init sched_init(void)  #ifdef CONFIG_RT_GROUP_SCHED  	alloc_size += 2 * nr_cpu_ids * sizeof(void **);  #endif -#ifdef CONFIG_CPUMASK_OFFSTACK -	alloc_size += num_possible_cpus() * cpumask_size(); -#endif  	if (alloc_size) {  		ptr = (unsigned long)kzalloc(alloc_size, GFP_NOWAIT); @@ -7135,13 +7132,13 @@ void __init sched_init(void)  		ptr += nr_cpu_ids * sizeof(void **);  #endif /* CONFIG_RT_GROUP_SCHED */ +	}  #ifdef CONFIG_CPUMASK_OFFSTACK -		for_each_possible_cpu(i) { -			per_cpu(load_balance_mask, i) = (void *)ptr; -			ptr += cpumask_size(); -		} -#endif /* CONFIG_CPUMASK_OFFSTACK */ +	for_each_possible_cpu(i) { +		per_cpu(load_balance_mask, i) = (cpumask_var_t)kzalloc_node( +			cpumask_size(), GFP_KERNEL, cpu_to_node(i));  	} +#endif /* CONFIG_CPUMASK_OFFSTACK */  	init_rt_bandwidth(&def_rt_bandwidth,  			global_rt_period(), global_rt_runtime()); diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c index e5db8c6feebd..b52092f2636d 100644 --- a/kernel/sched/deadline.c +++ b/kernel/sched/deadline.c @@ -570,24 +570,7 @@ void init_dl_task_timer(struct sched_dl_entity *dl_se)  static  int dl_runtime_exceeded(struct rq *rq, struct sched_dl_entity *dl_se)  { -	int dmiss = dl_time_before(dl_se->deadline, rq_clock(rq)); -	int rorun = dl_se->runtime <= 0; - -	if (!rorun && !dmiss) -		return 0; - -	/* -	 * If we are beyond our current deadline and we are still -	 * executing, then we have already used some of the runtime of -	 * the next instance. Thus, if we do not account that, we are -	 * stealing bandwidth from the system at each deadline miss! -	 */ -	if (dmiss) { -		dl_se->runtime = rorun ? dl_se->runtime : 0; -		dl_se->runtime -= rq_clock(rq) - dl_se->deadline; -	} - -	return 1; +	return (dl_se->runtime <= 0);  }  extern bool sched_rt_bandwidth_account(struct rt_rq *rt_rq); @@ -826,10 +809,10 @@ enqueue_dl_entity(struct sched_dl_entity *dl_se,  	 * parameters of the task might need updating. Otherwise,  	 * we want a replenishment of its runtime.  	 */ -	if (!dl_se->dl_new && flags & ENQUEUE_REPLENISH) -		replenish_dl_entity(dl_se, pi_se); -	else +	if (dl_se->dl_new || flags & ENQUEUE_WAKEUP)  		update_dl_entity(dl_se, pi_se); +	else if (flags & ENQUEUE_REPLENISH) +		replenish_dl_entity(dl_se, pi_se);  	__enqueue_dl_entity(dl_se);  } diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index df2cdf77f899..40667cbf371b 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -4005,6 +4005,10 @@ void __start_cfs_bandwidth(struct cfs_bandwidth *cfs_b, bool force)  static void destroy_cfs_bandwidth(struct cfs_bandwidth *cfs_b)  { +	/* init_cfs_bandwidth() was not called */ +	if (!cfs_b->throttled_cfs_rq.next) +		return; +  	hrtimer_cancel(&cfs_b->period_timer);  	hrtimer_cancel(&cfs_b->slack_timer);  } @@ -4424,7 +4428,7 @@ static long effective_load(struct task_group *tg, int cpu, long wl, long wg)  		 * wl = S * s'_i; see (2)  		 */  		if (W > 0 && w < W) -			wl = (w * tg->shares) / W; +			wl = (w * (long)tg->shares) / W;  		else  			wl = tg->shares; diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 929a733d302e..224e768bdc73 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -2497,12 +2497,14 @@ static void ftrace_run_update_code(int command)  }  static void ftrace_run_modify_code(struct ftrace_ops *ops, int command, -				   struct ftrace_hash *old_hash) +				   struct ftrace_ops_hash *old_hash)  {  	ops->flags |= FTRACE_OPS_FL_MODIFYING; -	ops->old_hash.filter_hash = old_hash; +	ops->old_hash.filter_hash = old_hash->filter_hash; +	ops->old_hash.notrace_hash = old_hash->notrace_hash;  	ftrace_run_update_code(command);  	ops->old_hash.filter_hash = NULL; +	ops->old_hash.notrace_hash = NULL;  	ops->flags &= ~FTRACE_OPS_FL_MODIFYING;  } @@ -3579,7 +3581,7 @@ static struct ftrace_ops trace_probe_ops __read_mostly =  static int ftrace_probe_registered; -static void __enable_ftrace_function_probe(struct ftrace_hash *old_hash) +static void __enable_ftrace_function_probe(struct ftrace_ops_hash *old_hash)  {  	int ret;  	int i; @@ -3637,6 +3639,7 @@ int  register_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,  			      void *data)  { +	struct ftrace_ops_hash old_hash_ops;  	struct ftrace_func_probe *entry;  	struct ftrace_hash **orig_hash = &trace_probe_ops.func_hash->filter_hash;  	struct ftrace_hash *old_hash = *orig_hash; @@ -3658,6 +3661,10 @@ register_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,  	mutex_lock(&trace_probe_ops.func_hash->regex_lock); +	old_hash_ops.filter_hash = old_hash; +	/* Probes only have filters */ +	old_hash_ops.notrace_hash = NULL; +  	hash = alloc_and_copy_ftrace_hash(FTRACE_HASH_DEFAULT_BITS, old_hash);  	if (!hash) {  		count = -ENOMEM; @@ -3718,7 +3725,7 @@ register_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,  	ret = ftrace_hash_move(&trace_probe_ops, 1, orig_hash, hash); -	__enable_ftrace_function_probe(old_hash); +	__enable_ftrace_function_probe(&old_hash_ops);  	if (!ret)  		free_ftrace_hash_rcu(old_hash); @@ -4006,10 +4013,34 @@ ftrace_match_addr(struct ftrace_hash *hash, unsigned long ip, int remove)  }  static void ftrace_ops_update_code(struct ftrace_ops *ops, -				   struct ftrace_hash *old_hash) +				   struct ftrace_ops_hash *old_hash)  { -	if (ops->flags & FTRACE_OPS_FL_ENABLED && ftrace_enabled) +	struct ftrace_ops *op; + +	if (!ftrace_enabled) +		return; + +	if (ops->flags & FTRACE_OPS_FL_ENABLED) {  		ftrace_run_modify_code(ops, FTRACE_UPDATE_CALLS, old_hash); +		return; +	} + +	/* +	 * If this is the shared global_ops filter, then we need to +	 * check if there is another ops that shares it, is enabled. +	 * If so, we still need to run the modify code. +	 */ +	if (ops->func_hash != &global_ops.local_hash) +		return; + +	do_for_each_ftrace_op(op, ftrace_ops_list) { +		if (op->func_hash == &global_ops.local_hash && +		    op->flags & FTRACE_OPS_FL_ENABLED) { +			ftrace_run_modify_code(op, FTRACE_UPDATE_CALLS, old_hash); +			/* Only need to do this once */ +			return; +		} +	} while_for_each_ftrace_op(op);  }  static int @@ -4017,6 +4048,7 @@ ftrace_set_hash(struct ftrace_ops *ops, unsigned char *buf, int len,  		unsigned long ip, int remove, int reset, int enable)  {  	struct ftrace_hash **orig_hash; +	struct ftrace_ops_hash old_hash_ops;  	struct ftrace_hash *old_hash;  	struct ftrace_hash *hash;  	int ret; @@ -4053,9 +4085,11 @@ ftrace_set_hash(struct ftrace_ops *ops, unsigned char *buf, int len,  	mutex_lock(&ftrace_lock);  	old_hash = *orig_hash; +	old_hash_ops.filter_hash = ops->func_hash->filter_hash; +	old_hash_ops.notrace_hash = ops->func_hash->notrace_hash;  	ret = ftrace_hash_move(ops, enable, orig_hash, hash);  	if (!ret) { -		ftrace_ops_update_code(ops, old_hash); +		ftrace_ops_update_code(ops, &old_hash_ops);  		free_ftrace_hash_rcu(old_hash);  	}  	mutex_unlock(&ftrace_lock); @@ -4267,6 +4301,7 @@ static void __init set_ftrace_early_filters(void)  int ftrace_regex_release(struct inode *inode, struct file *file)  {  	struct seq_file *m = (struct seq_file *)file->private_data; +	struct ftrace_ops_hash old_hash_ops;  	struct ftrace_iterator *iter;  	struct ftrace_hash **orig_hash;  	struct ftrace_hash *old_hash; @@ -4300,10 +4335,12 @@ int ftrace_regex_release(struct inode *inode, struct file *file)  		mutex_lock(&ftrace_lock);  		old_hash = *orig_hash; +		old_hash_ops.filter_hash = iter->ops->func_hash->filter_hash; +		old_hash_ops.notrace_hash = iter->ops->func_hash->notrace_hash;  		ret = ftrace_hash_move(iter->ops, filter_hash,  				       orig_hash, iter->hash);  		if (!ret) { -			ftrace_ops_update_code(iter->ops, old_hash); +			ftrace_ops_update_code(iter->ops, &old_hash_ops);  			free_ftrace_hash_rcu(old_hash);  		}  		mutex_unlock(&ftrace_lock); diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 2e767972e99c..4a9079b9f082 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -6918,7 +6918,6 @@ void __init trace_init(void)  			tracepoint_printk = 0;  	}  	tracer_alloc_buffers(); -	init_ftrace_syscalls();  	trace_event_init();	  } diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index 366a78a3e61e..b03a0ea77b99 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c @@ -2429,12 +2429,39 @@ static __init int event_trace_memsetup(void)  	return 0;  } +static __init void +early_enable_events(struct trace_array *tr, bool disable_first) +{ +	char *buf = bootup_event_buf; +	char *token; +	int ret; + +	while (true) { +		token = strsep(&buf, ","); + +		if (!token) +			break; +		if (!*token) +			continue; + +		/* Restarting syscalls requires that we stop them first */ +		if (disable_first) +			ftrace_set_clr_event(tr, token, 0); + +		ret = ftrace_set_clr_event(tr, token, 1); +		if (ret) +			pr_warn("Failed to enable trace event: %s\n", token); + +		/* Put back the comma to allow this to be called again */ +		if (buf) +			*(buf - 1) = ','; +	} +} +  static __init int event_trace_enable(void)  {  	struct trace_array *tr = top_trace_array();  	struct ftrace_event_call **iter, *call; -	char *buf = bootup_event_buf; -	char *token;  	int ret;  	if (!tr) @@ -2456,18 +2483,7 @@ static __init int event_trace_enable(void)  	 */  	__trace_early_add_events(tr); -	while (true) { -		token = strsep(&buf, ","); - -		if (!token) -			break; -		if (!*token) -			continue; - -		ret = ftrace_set_clr_event(tr, token, 1); -		if (ret) -			pr_warn("Failed to enable trace event: %s\n", token); -	} +	early_enable_events(tr, false);  	trace_printk_start_comm(); @@ -2478,6 +2494,31 @@ static __init int event_trace_enable(void)  	return 0;  } +/* + * event_trace_enable() is called from trace_event_init() first to + * initialize events and perhaps start any events that are on the + * command line. Unfortunately, there are some events that will not + * start this early, like the system call tracepoints that need + * to set the TIF_SYSCALL_TRACEPOINT flag of pid 1. But event_trace_enable() + * is called before pid 1 starts, and this flag is never set, making + * the syscall tracepoint never get reached, but the event is enabled + * regardless (and not doing anything). + */ +static __init int event_trace_enable_again(void) +{ +	struct trace_array *tr; + +	tr = top_trace_array(); +	if (!tr) +		return -ENODEV; + +	early_enable_events(tr, true); + +	return 0; +} + +early_initcall(event_trace_enable_again); +  static __init int event_trace_init(void)  {  	struct trace_array *tr; diff --git a/kernel/trace/trace_kdb.c b/kernel/trace/trace_kdb.c index b0b1c44e923a..3ccf5c2c1320 100644 --- a/kernel/trace/trace_kdb.c +++ b/kernel/trace/trace_kdb.c @@ -132,8 +132,8 @@ static int kdb_ftdump(int argc, const char **argv)  static __init int kdb_ftrace_register(void)  { -	kdb_register_repeat("ftdump", kdb_ftdump, "[skip_#lines] [cpu]", -			    "Dump ftrace log", 0, KDB_REPEAT_NONE); +	kdb_register_flags("ftdump", kdb_ftdump, "[skip_#lines] [cpu]", +			    "Dump ftrace log", 0, KDB_ENABLE_ALWAYS_SAFE);  	return 0;  } | 
