aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Poimboeuf <jpoimboe@kernel.org>2024-02-27 12:54:17 -0800
committerJosh Poimboeuf <jpoimboe@kernel.org>2024-02-27 13:10:06 -0800
commitf7ed19fcccac5cbf7d12937a6b122d36ca80ba3b (patch)
treeb07fb7cc479118142aaf3ee9a07eeb0460fb502a
parentafb9cce6ad6e808cf659f43925941be96f61b9c9 (diff)
downloadlinux-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.h3
-rw-r--r--kernel/kexec_core.c1
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)
{