diff options
author | Josh Poimboeuf <jpoimboe@kernel.org> | 2024-02-27 12:54:17 -0800 |
---|---|---|
committer | Josh Poimboeuf <jpoimboe@kernel.org> | 2024-02-27 13:10:06 -0800 |
commit | f7ed19fcccac5cbf7d12937a6b122d36ca80ba3b (patch) | |
tree | b07fb7cc479118142aaf3ee9a07eeb0460fb502a | |
parent | afb9cce6ad6e808cf659f43925941be96f61b9c9 (diff) | |
download | linux-objtool-kexec.tar.gz |
x86/kexec: Fix ORC unwinding from __crash_kexec()objtool-kexec
__crash_kexec() doesn't have any ORC unwinder coverage due to its
STACK_FRAME_NON_STANDARD() annotation. So unwinding from that function
(e.g., in crash) fails.
It has that annotation because objtool is confused by how
crash_setup_regs() saves the registers. However, the rest of the
function is normal. So objtool doesn't need to skip the entire
function.
Improve __crash_kexec()'s ORC coverage by narrowing the window of the
ORC undefined state.
Reported-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
-rw-r--r-- | arch/x86/include/asm/kexec.h | 3 | ||||
-rw-r--r-- | kernel/kexec_core.c | 1 |
2 files changed, 3 insertions, 1 deletions
diff --git a/arch/x86/include/asm/kexec.h b/arch/x86/include/asm/kexec.h index 91ca9a9ee3a2b2..42ce9575eca9ae 100644 --- a/arch/x86/include/asm/kexec.h +++ b/arch/x86/include/asm/kexec.h @@ -91,7 +91,9 @@ static inline void crash_setup_regs(struct pt_regs *newregs, asm volatile("movl %%es, %%eax;" :"=a"(newregs->es)); asm volatile("pushfl; popl %0" :"=m"(newregs->flags)); #else + asm volatile(UNWIND_HINT_SAVE); asm volatile("movq %%rbx,%0" : "=m"(newregs->bx)); + asm volatile(UNWIND_HINT_UNDEFINED); asm volatile("movq %%rcx,%0" : "=m"(newregs->cx)); asm volatile("movq %%rdx,%0" : "=m"(newregs->dx)); asm volatile("movq %%rsi,%0" : "=m"(newregs->si)); @@ -109,6 +111,7 @@ static inline void crash_setup_regs(struct pt_regs *newregs, asm volatile("movq %%r15,%0" : "=m"(newregs->r15)); asm volatile("movl %%ss, %%eax;" :"=a"(newregs->ss)); asm volatile("movl %%cs, %%eax;" :"=a"(newregs->cs)); + asm volatile(UNWIND_HINT_RESTORE); asm volatile("pushfq; popq %0" :"=m"(newregs->flags)); #endif newregs->ip = _THIS_IP_; diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c index d08fc7b5db9790..f14e012e08177b 100644 --- a/kernel/kexec_core.c +++ b/kernel/kexec_core.c @@ -1054,7 +1054,6 @@ void __noclone __crash_kexec(struct pt_regs *regs) kexec_unlock(); } } -STACK_FRAME_NON_STANDARD(__crash_kexec); __bpf_kfunc void crash_kexec(struct pt_regs *regs) { |