diff options
author | Ingo Molnar | 2017-10-14 10:11:45 +0200 |
---|---|---|
committer | Ingo Molnar | 2017-10-14 10:11:45 +0200 |
commit | 6edcf57233108df2e50ab5d3fa695ea958b4c779 (patch) | |
tree | 7f233132de3cf1d438ac5ca51cfa6e9c48f8b86f /kernel/extable.c | |
parent | x86/unwinder: Make CONFIG_UNWINDER_ORC=y the default in the 64-bit defconfig (diff) | |
parent | objtool: Upgrade libelf-devel warning to error for CONFIG_ORC_UNWINDER (diff) | |
download | kernel-qcow2-linux-6edcf57233108df2e50ab5d3fa695ea958b4c779.tar.gz kernel-qcow2-linux-6edcf57233108df2e50ab5d3fa695ea958b4c779.tar.xz kernel-qcow2-linux-6edcf57233108df2e50ab5d3fa695ea958b4c779.zip |
Merge branch 'core/urgent' into x86/asm, to pick up dependency
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'kernel/extable.c')
-rw-r--r-- | kernel/extable.c | 45 |
1 files changed, 31 insertions, 14 deletions
diff --git a/kernel/extable.c b/kernel/extable.c index 38c2412401a1..9aa1cc41ecf7 100644 --- a/kernel/extable.c +++ b/kernel/extable.c @@ -102,15 +102,7 @@ int core_kernel_data(unsigned long addr) int __kernel_text_address(unsigned long addr) { - if (core_kernel_text(addr)) - return 1; - if (is_module_text_address(addr)) - return 1; - if (is_ftrace_trampoline(addr)) - return 1; - if (is_kprobe_optinsn_slot(addr) || is_kprobe_insn_slot(addr)) - return 1; - if (is_bpf_text_address(addr)) + if (kernel_text_address(addr)) return 1; /* * There might be init symbols in saved stacktraces. @@ -127,17 +119,42 @@ int __kernel_text_address(unsigned long addr) int kernel_text_address(unsigned long addr) { + bool no_rcu; + int ret = 1; + if (core_kernel_text(addr)) return 1; + + /* + * If a stack dump happens while RCU is not watching, then + * RCU needs to be notified that it requires to start + * watching again. This can happen either by tracing that + * triggers a stack trace, or a WARN() that happens during + * coming back from idle, or cpu on or offlining. + * + * is_module_text_address() as well as the kprobe slots + * and is_bpf_text_address() require RCU to be watching. + */ + no_rcu = !rcu_is_watching(); + + /* Treat this like an NMI as it can happen anywhere */ + if (no_rcu) + rcu_nmi_enter(); + if (is_module_text_address(addr)) - return 1; + goto out; if (is_ftrace_trampoline(addr)) - return 1; + goto out; if (is_kprobe_optinsn_slot(addr) || is_kprobe_insn_slot(addr)) - return 1; + goto out; if (is_bpf_text_address(addr)) - return 1; - return 0; + goto out; + ret = 0; +out: + if (no_rcu) + rcu_nmi_exit(); + + return ret; } /* |