Skip to contentSkip to conversation

x86/asm: Add unwind hint annotations to head code

PATCH New Josh Poimboeuf 2 participants 17 messages Sep 19, 2017 – Sep 28, 2017

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

v2 cover x86/asm: Add unwind hint annotations to head code

v2:
- Add missing include in xen patch 7/8

Add some annotations to allow objtool to understand the head code. Among other things, this allows the ORC unwinder to completely unwind an idle task.

Also do a few cleanups while I'm there.

Josh Poimboeuf (8):
objtool: Don't report end of section error after an empty unwind hint x86/head: Remove confusing comment
x86/head: Remove unused 'bad_address' code
x86/head: Fix head ELF function annotations
x86/boot: Annotate verify_cpu() as a callable function x86/xen: Fix xen head ELF annotations
x86/xen: Add unwind hint annotations
x86/head: Add unwind hint annotations

 arch/x86/kernel/Makefile     |  1 -
 arch/x86/kernel/head_64.S    | 27 +++++++++++++++------------
 arch/x86/kernel/verify_cpu.S |  3 ++-
 arch/x86/xen/xen-head.S      | 11 ++++++++---
 tools/objtool/check.c        |  7 +++++--
 5 files changed, 30 insertions(+), 19 deletions(-)
Signature · 1 line
2.13.5
#1 lore raw

PATCH v2 1/8 objtool: Don't report end of section error after an empty unwind hint

If asm code specifies an UNWIND_HINT_EMPTY hint, don't warn if the section ends unexpectedly. This can happen with the xen-head.S code because the hypercall_page is "text" but it's all zeros.

---
 tools/objtool/check.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)
tools/objtool/check.c +5 -2
index f744617c9946..d8683f0fe04d 100644
@@ -1737,11 +1737,14 @@ static int validate_branch(struct objtool_file *file, struct instruction *first,
 		if (insn->dead_end)
 			return 0;
 
-		insn = next_insn;
-		if (!insn) {
+		if (!next_insn) {
+			if (state.cfa.base == CFI_UNDEFINED)
+				return 0;
 			WARN("%s: unexpected end of section", sec->name);
 			return 1;
 		}
+
+		insn = next_insn;
 	}
 
 	return 0;
Signature · 1 line
2.13.5
#2 lore raw

[tip:core/objtool] objtool: Don't report end of section error after an empty unwind hint

objtool: Don't report end of section error after an empty unwind hint
Commit-ID:  00d96180dc38ef872ac471c2d3e14b067cbd895d
Gitweb:     https://git.kernel.org/tip/00d96180dc38ef872ac471c2d3e14b067cbd895d
Author:     Josh Poimboeuf <[email protected]>
AuthorDate: Mon, 18 Sep 2017 21:43:30 -0500
Committer:  Ingo Molnar <[email protected]>
CommitDate: Thu, 28 Sep 2017 09:39:02 +0200

objtool: Don't report end of section error after an empty unwind hint

If asm code specifies an UNWIND_HINT_EMPTY hint, don't warn if the section ends unexpectedly. This can happen with the xen-head.S code because the hypercall_page is "text" but it's all zeros.

---
 tools/objtool/check.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)
tools/objtool/check.c +5 -2
index a0c518e..83f370f 100644
@@ -1752,11 +1752,14 @@ static int validate_branch(struct objtool_file *file, struct instruction *first,
 		if (insn->dead_end)
 			return 0;
 
-		insn = next_insn;
-		if (!insn) {
+		if (!next_insn) {
+			if (state.cfa.base == CFI_UNDEFINED)
+				return 0;
 			WARN("%s: unexpected end of section", sec->name);
 			return 1;
 		}
+
+		insn = next_insn;
 	}
 
 	return 0;
#3 lore raw

PATCH v2 2/8 x86/head: Remove confusing comment

In reply to Josh Poimboeuf

This comment is actively wrong and confusing. It refers to the registers' stack offsets after the pt_regs has been constructed on the stack, but this code is *before* that.

At this point the stack just has the standard iret frame, for which no comment should be needed.

---
 arch/x86/kernel/head_64.S | 4 ----
 1 file changed, 4 deletions(-)
arch/x86/kernel/head_64.S +0 -4
index 513cbb012ecc..3b04e4c99389 100644
@@ -270,10 +270,6 @@ bad_address:
 
 	__INIT
 ENTRY(early_idt_handler_array)
-	# 104(%rsp) %rflags
-	#  96(%rsp) %cs
-	#  88(%rsp) %rip
-	#  80(%rsp) error code
 	i = 0
 	.rept NUM_EXCEPTION_VECTORS
 	.ifeq (EXCEPTION_ERRCODE_MASK >> i) & 1
Signature · 1 line
2.13.5
#4 lore raw

[tip:core/objtool] x86/head: Remove confusing comment

x86/head: Remove confusing comment
Commit-ID:  17270717e80de33a884ad328fea5f407d87f6d6a
Gitweb:     https://git.kernel.org/tip/17270717e80de33a884ad328fea5f407d87f6d6a
Author:     Josh Poimboeuf <[email protected]>
AuthorDate: Mon, 18 Sep 2017 21:43:31 -0500
Committer:  Ingo Molnar <[email protected]>
CommitDate: Thu, 28 Sep 2017 09:39:02 +0200

x86/head: Remove confusing comment

This comment is actively wrong and confusing. It refers to the registers' stack offsets after the pt_regs has been constructed on the stack, but this code is *before* that.

At this point the stack just has the standard iret frame, for which no comment should be needed.

---
 arch/x86/kernel/head_64.S | 4 ----
 1 file changed, 4 deletions(-)
arch/x86/kernel/head_64.S +0 -4
index 513cbb0..3b04e4c 100644
@@ -270,10 +270,6 @@ bad_address:
 
 	__INIT
 ENTRY(early_idt_handler_array)
-	# 104(%rsp) %rflags
-	#  96(%rsp) %cs
-	#  88(%rsp) %rip
-	#  80(%rsp) error code
 	i = 0
 	.rept NUM_EXCEPTION_VECTORS
 	.ifeq (EXCEPTION_ERRCODE_MASK >> i) & 1
#5 lore raw

PATCH v2 3/8 x86/head: Remove unused 'bad_address' code

In reply to Josh Poimboeuf

It's no longer possible for this code to be executed, so remove it.

---
 arch/x86/kernel/head_64.S | 3 ---
 1 file changed, 3 deletions(-)
arch/x86/kernel/head_64.S +0 -3
index 3b04e4c99389..afb0a1e22d41 100644
@@ -265,9 +265,6 @@ ENDPROC(start_cpu0)
 	.quad  init_thread_union + THREAD_SIZE - SIZEOF_PTREGS
 	__FINITDATA
 
-bad_address:
-	jmp bad_address
-
 	__INIT
 ENTRY(early_idt_handler_array)
 	i = 0
Signature · 1 line
2.13.5
#6 lore raw

[tip:core/objtool] x86/head: Remove unused 'bad_address' code

x86/head: Remove unused 'bad_address' code
Commit-ID:  a8b88e84d124bc92c4808e72b8b8c0e0bb538630
Gitweb:     https://git.kernel.org/tip/a8b88e84d124bc92c4808e72b8b8c0e0bb538630
Author:     Josh Poimboeuf <[email protected]>
AuthorDate: Mon, 18 Sep 2017 21:43:32 -0500
Committer:  Ingo Molnar <[email protected]>
CommitDate: Thu, 28 Sep 2017 09:39:03 +0200

x86/head: Remove unused 'bad_address' code

It's no longer possible for this code to be executed, so remove it.

---
 arch/x86/kernel/head_64.S | 3 ---
 1 file changed, 3 deletions(-)
arch/x86/kernel/head_64.S +0 -3
index 3b04e4c..afb0a1e 100644
@@ -265,9 +265,6 @@ ENDPROC(start_cpu0)
 	.quad  init_thread_union + THREAD_SIZE - SIZEOF_PTREGS
 	__FINITDATA
 
-bad_address:
-	jmp bad_address
-
 	__INIT
 ENTRY(early_idt_handler_array)
 	i = 0
#7 lore raw

PATCH v2 4/8 x86/head: Fix head ELF function annotations

In reply to Josh Poimboeuf

These functions aren't callable C-type functions, so don't annotate them as such.

---
 arch/x86/kernel/head_64.S | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
arch/x86/kernel/head_64.S +3 -3
index afb0a1e22d41..edacd579d504 100644
@@ -234,7 +234,7 @@ ENTRY(secondary_startup_64)
 	pushq	%rax		# target address in negative space
 	lretq
 .Lafter_lret:
-ENDPROC(secondary_startup_64)
+END(secondary_startup_64)
 
 #include "verify_cpu.S"
 
@@ -277,7 +277,7 @@ ENTRY(early_idt_handler_array)
 	i = i + 1
 	.fill early_idt_handler_array + i*EARLY_IDT_HANDLER_SIZE - ., 1, 0xcc
 	.endr
-ENDPROC(early_idt_handler_array)
+END(early_idt_handler_array)
 
 early_idt_handler_common:
 	/*
@@ -320,7 +320,7 @@ early_idt_handler_common:
 20:
 	decl early_recursion_flag(%rip)
 	jmp restore_regs_and_iret
-ENDPROC(early_idt_handler_common)
+END(early_idt_handler_common)
 
 	__INITDATA
 
Signature · 1 line
2.13.5
#8 lore raw

[tip:core/objtool] x86/head: Fix head ELF function annotations

x86/head: Fix head ELF function annotations
Commit-ID:  015a2ea5478680fc5216d56b7ff306f2a74efaf9
Gitweb:     https://git.kernel.org/tip/015a2ea5478680fc5216d56b7ff306f2a74efaf9
Author:     Josh Poimboeuf <[email protected]>
AuthorDate: Mon, 18 Sep 2017 21:43:33 -0500
Committer:  Ingo Molnar <[email protected]>
CommitDate: Thu, 28 Sep 2017 09:39:03 +0200

x86/head: Fix head ELF function annotations

These functions aren't callable C-type functions, so don't annotate them as such.

---
 arch/x86/kernel/head_64.S | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
arch/x86/kernel/head_64.S +3 -3
index afb0a1e..edacd57 100644
@@ -234,7 +234,7 @@ ENTRY(secondary_startup_64)
 	pushq	%rax		# target address in negative space
 	lretq
 .Lafter_lret:
-ENDPROC(secondary_startup_64)
+END(secondary_startup_64)
 
 #include "verify_cpu.S"
 
@@ -277,7 +277,7 @@ ENTRY(early_idt_handler_array)
 	i = i + 1
 	.fill early_idt_handler_array + i*EARLY_IDT_HANDLER_SIZE - ., 1, 0xcc
 	.endr
-ENDPROC(early_idt_handler_array)
+END(early_idt_handler_array)
 
 early_idt_handler_common:
 	/*
@@ -320,7 +320,7 @@ early_idt_handler_common:
 20:
 	decl early_recursion_flag(%rip)
 	jmp restore_regs_and_iret
-ENDPROC(early_idt_handler_common)
+END(early_idt_handler_common)
 
 	__INITDATA
 
#9 lore raw

PATCH v2 5/8 x86/boot: Annotate verify_cpu() as a callable function

In reply to Josh Poimboeuf

verify_cpu() is a callable function. Annotate it as such.

---
 arch/x86/kernel/verify_cpu.S | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
arch/x86/kernel/verify_cpu.S +2 -1
index 014ea59aa153..3d3c2f71f617 100644
@@ -33,7 +33,7 @@
 #include <asm/cpufeatures.h>
 #include <asm/msr-index.h>
 
-verify_cpu:
+ENTRY(verify_cpu)
 	pushf				# Save caller passed flags
 	push	$0			# Kill any dangerous flags
 	popf
@@ -139,3 +139,4 @@ verify_cpu:
 	popf				# Restore caller passed flags
 	xorl %eax, %eax
 	ret
+ENDPROC(verify_cpu)
Signature · 1 line
2.13.5
#10 lore raw

[tip:core/objtool] x86/boot: Annotate verify_cpu() as a callable function

x86/boot: Annotate verify_cpu() as a callable function
Commit-ID:  e93db75a0054b23a874a12c63376753544f3fe9e
Gitweb:     https://git.kernel.org/tip/e93db75a0054b23a874a12c63376753544f3fe9e
Author:     Josh Poimboeuf <[email protected]>
AuthorDate: Mon, 18 Sep 2017 21:43:34 -0500
Committer:  Ingo Molnar <[email protected]>
CommitDate: Thu, 28 Sep 2017 09:39:03 +0200

x86/boot: Annotate verify_cpu() as a callable function

verify_cpu() is a callable function. Annotate it as such.

---
 arch/x86/kernel/verify_cpu.S | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
arch/x86/kernel/verify_cpu.S +2 -1
index 014ea59..3d3c2f7 100644
@@ -33,7 +33,7 @@
 #include <asm/cpufeatures.h>
 #include <asm/msr-index.h>
 
-verify_cpu:
+ENTRY(verify_cpu)
 	pushf				# Save caller passed flags
 	push	$0			# Kill any dangerous flags
 	popf
@@ -139,3 +139,4 @@ verify_cpu:
 	popf				# Restore caller passed flags
 	xorl %eax, %eax
 	ret
+ENDPROC(verify_cpu)
#11 lore raw

PATCH v2 6/8 x86/xen: Fix xen head ELF annotations

In reply to Josh Poimboeuf

Mark the ends of the startup_xen and hypercall_page code sections.

---
 arch/x86/xen/xen-head.S | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
arch/x86/xen/xen-head.S +2 -2
index a7525e95d53f..9753225289e8 100644
@@ -33,7 +33,7 @@ ENTRY(startup_xen)
 	mov $init_thread_union+THREAD_SIZE, %_ASM_SP
 
 	jmp xen_start_kernel
-
+END(startup_xen)
 	__FINIT
 #endif
 
@@ -47,7 +47,7 @@ ENTRY(hypercall_page)
 	.type xen_hypercall_##n, @function; .size xen_hypercall_##n, 32
 #include <asm/xen-hypercalls.h>
 #undef HYPERCALL
-
+END(hypercall_page)
 .popsection
 
 	ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS,       .asciz "linux")
Signature · 1 line
2.13.5
#12 lore raw

[tip:core/objtool] x86/xen: Fix xen head ELF annotations

x86/xen: Fix xen head ELF annotations
Commit-ID:  2582d3df95c76d3b686453baf90b64d57e87d1e8
Gitweb:     https://git.kernel.org/tip/2582d3df95c76d3b686453baf90b64d57e87d1e8
Author:     Josh Poimboeuf <[email protected]>
AuthorDate: Mon, 18 Sep 2017 21:43:35 -0500
Committer:  Ingo Molnar <[email protected]>
CommitDate: Thu, 28 Sep 2017 09:39:03 +0200

x86/xen: Fix xen head ELF annotations

Mark the ends of the startup_xen and hypercall_page code sections.

---
 arch/x86/xen/xen-head.S | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
arch/x86/xen/xen-head.S +2 -2
index a7525e9..9753225 100644
@@ -33,7 +33,7 @@ ENTRY(startup_xen)
 	mov $init_thread_union+THREAD_SIZE, %_ASM_SP
 
 	jmp xen_start_kernel
-
+END(startup_xen)
 	__FINIT
 #endif
 
@@ -47,7 +47,7 @@ ENTRY(hypercall_page)
 	.type xen_hypercall_##n, @function; .size xen_hypercall_##n, 32
 #include <asm/xen-hypercalls.h>
 #undef HYPERCALL
-
+END(hypercall_page)
 .popsection
 
 	ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS,       .asciz "linux")
#13 lore raw

PATCH v2 7/8 x86/xen: Add unwind hint annotations

In reply to Josh Poimboeuf

Add unwind hint annotations to the xen head code so the ORC unwinder can read head_64.o.

hypercall_page needs empty annotations at 32-byte intervals to match the 'xen_hypercall_*' ELF functions at those locations.

---
 arch/x86/xen/xen-head.S | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)
arch/x86/xen/xen-head.S +6 -1
index 9753225289e8..124941d09b2b 100644
@@ -9,6 +9,7 @@
 #include <asm/boot.h>
 #include <asm/asm.h>
 #include <asm/page_types.h>
+#include <asm/unwind_hints.h>
 
 #include <xen/interface/elfnote.h>
 #include <xen/interface/features.h>
@@ -19,6 +20,7 @@
 #ifdef CONFIG_XEN_PV
 	__INIT
 ENTRY(startup_xen)
+	UNWIND_HINT_EMPTY
 	cld
 
 	/* Clear .bss */
@@ -40,7 +42,10 @@ END(startup_xen)
 .pushsection .text
 	.balign PAGE_SIZE
 ENTRY(hypercall_page)
-	.skip PAGE_SIZE
+	.rept (PAGE_SIZE / 32)
+		UNWIND_HINT_EMPTY
+		.skip 32
+	.endr
 
 #define HYPERCALL(n) \
 	.equ xen_hypercall_##n, hypercall_page + __HYPERVISOR_##n * 32; \
Signature · 1 line
2.13.5
#14 lore raw

[tip:core/objtool] x86/xen: Add unwind hint annotations

x86/xen: Add unwind hint annotations
Commit-ID:  abbe1cac6214d81d2f4e149aba64a8760703144e
Gitweb:     https://git.kernel.org/tip/abbe1cac6214d81d2f4e149aba64a8760703144e
Author:     Josh Poimboeuf <[email protected]>
AuthorDate: Mon, 18 Sep 2017 21:43:36 -0500
Committer:  Ingo Molnar <[email protected]>
CommitDate: Thu, 28 Sep 2017 09:39:03 +0200

x86/xen: Add unwind hint annotations

Add unwind hint annotations to the xen head code so the ORC unwinder can read head_64.o.

hypercall_page needs empty annotations at 32-byte intervals to match the 'xen_hypercall_*' ELF functions at those locations.

---
 arch/x86/xen/xen-head.S | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)
arch/x86/xen/xen-head.S +6 -1
index 9753225..124941d 100644
@@ -9,6 +9,7 @@
 #include <asm/boot.h>
 #include <asm/asm.h>
 #include <asm/page_types.h>
+#include <asm/unwind_hints.h>
 
 #include <xen/interface/elfnote.h>
 #include <xen/interface/features.h>
@@ -19,6 +20,7 @@
 #ifdef CONFIG_XEN_PV
 	__INIT
 ENTRY(startup_xen)
+	UNWIND_HINT_EMPTY
 	cld
 
 	/* Clear .bss */
@@ -40,7 +42,10 @@ END(startup_xen)
 .pushsection .text
 	.balign PAGE_SIZE
 ENTRY(hypercall_page)
-	.skip PAGE_SIZE
+	.rept (PAGE_SIZE / 32)
+		UNWIND_HINT_EMPTY
+		.skip 32
+	.endr
 
 #define HYPERCALL(n) \
 	.equ xen_hypercall_##n, hypercall_page + __HYPERVISOR_##n * 32; \
#15 lore raw

PATCH v2 8/8 x86/head: Add unwind hint annotations

In reply to Josh Poimboeuf

Jiri Slaby reported an ORC issue when unwinding from an idle task. The stack was:

    ffffffff811083c2 do_idle+0x142/0x1e0
    ffffffff8110861d cpu_startup_entry+0x5d/0x60
    ffffffff82715f58 start_kernel+0x3ff/0x407
    ffffffff827153e8 x86_64_start_kernel+0x14e/0x15d
    ffffffff810001bf secondary_startup_64+0x9f/0xa0

The ORC unwinder errored out at secondary_startup_64 because the head code isn't annotated yet so there wasn't a corresponding ORC entry.

Fix that and any other head-related unwinding issues by adding unwind hints to the head code.

---
 arch/x86/kernel/Makefile  |  1 -
 arch/x86/kernel/head_64.S | 14 ++++++++++++--
 2 files changed, 12 insertions(+), 3 deletions(-)
arch/x86/kernel/Makefile +0 -1
index fd0a7895b63f..d8e2b700d1db 100644
@@ -26,7 +26,6 @@ KASAN_SANITIZE_dumpstack.o				:= n
 KASAN_SANITIZE_dumpstack_$(BITS).o			:= n
 KASAN_SANITIZE_stacktrace.o := n
 
-OBJECT_FILES_NON_STANDARD_head_$(BITS).o		:= y
 OBJECT_FILES_NON_STANDARD_relocate_kernel_$(BITS).o	:= y
 OBJECT_FILES_NON_STANDARD_ftrace_$(BITS).o		:= y
 OBJECT_FILES_NON_STANDARD_test_nx.o			:= y
arch/x86/kernel/head_64.S +12 -2
index edacd579d504..42e32c2e51bb 100644
@@ -49,6 +49,7 @@ L3_START_KERNEL = pud_index(__START_KERNEL_map)
 	.code64
 	.globl startup_64
 startup_64:
+	UNWIND_HINT_EMPTY
 	/*
 	 * At this point the CPU runs in 64bit mode CS.L = 1 CS.D = 0,
 	 * and someone has loaded an identity mapped page table
@@ -88,6 +89,7 @@ startup_64:
 	addq	$(early_top_pgt - __START_KERNEL_map), %rax
 	jmp 1f
 ENTRY(secondary_startup_64)
+	UNWIND_HINT_EMPTY
 	/*
 	 * At this point the CPU runs in 64bit mode CS.L = 1 CS.D = 0,
 	 * and someone has loaded a mapped page table.
@@ -132,6 +134,7 @@ ENTRY(secondary_startup_64)
 	movq	$1f, %rax
 	jmp	*%rax
 1:
+	UNWIND_HINT_EMPTY
 
 	/* Check if nx is implemented */
 	movl	$0x80000001, %eax
@@ -246,6 +249,7 @@ END(secondary_startup_64)
  */
 ENTRY(start_cpu0)
 	movq	initial_stack(%rip), %rsp
+	UNWIND_HINT_EMPTY
 	jmp	.Ljump_to_C_code
 ENDPROC(start_cpu0)
 #endif
@@ -270,13 +274,18 @@ ENTRY(early_idt_handler_array)
 	i = 0
 	.rept NUM_EXCEPTION_VECTORS
 	.ifeq (EXCEPTION_ERRCODE_MASK >> i) & 1
-	pushq $0		# Dummy error code, to make stack frame uniform
+		UNWIND_HINT_IRET_REGS
+		pushq $0	# Dummy error code, to make stack frame uniform
+	.else
+		UNWIND_HINT_IRET_REGS offset=8
 	.endif
 	pushq $i		# 72(%rsp) Vector number
 	jmp early_idt_handler_common
+	UNWIND_HINT_IRET_REGS
 	i = i + 1
 	.fill early_idt_handler_array + i*EARLY_IDT_HANDLER_SIZE - ., 1, 0xcc
 	.endr
+	UNWIND_HINT_IRET_REGS offset=16
 END(early_idt_handler_array)
 
 early_idt_handler_common:
@@ -305,6 +314,7 @@ early_idt_handler_common:
 	pushq %r13				/* pt_regs->r13 */
 	pushq %r14				/* pt_regs->r14 */
 	pushq %r15				/* pt_regs->r15 */
+	UNWIND_HINT_REGS
 
 	cmpq $14,%rsi		/* Page fault? */
 	jnz 10f
@@ -427,7 +437,7 @@ ENTRY(phys_base)
 EXPORT_SYMBOL(phys_base)
 
 #include "../../x86/xen/xen-head.S"
-	
+
 	__PAGE_ALIGNED_BSS
 NEXT_PAGE(empty_zero_page)
 	.skip PAGE_SIZE
Signature · 1 line
2.13.5
#16 lore raw

[tip:core/objtool] x86/head: Add unwind hint annotations

x86/head: Add unwind hint annotations
Commit-ID:  2704fbb672d0d9a19414907fda7949283dcef6a1
Gitweb:     https://git.kernel.org/tip/2704fbb672d0d9a19414907fda7949283dcef6a1
Author:     Josh Poimboeuf <[email protected]>
AuthorDate: Mon, 18 Sep 2017 21:43:37 -0500
Committer:  Ingo Molnar <[email protected]>
CommitDate: Thu, 28 Sep 2017 09:39:04 +0200

x86/head: Add unwind hint annotations

Jiri Slaby reported an ORC issue when unwinding from an idle task. The stack was:

    ffffffff811083c2 do_idle+0x142/0x1e0
    ffffffff8110861d cpu_startup_entry+0x5d/0x60
    ffffffff82715f58 start_kernel+0x3ff/0x407
    ffffffff827153e8 x86_64_start_kernel+0x14e/0x15d
    ffffffff810001bf secondary_startup_64+0x9f/0xa0

The ORC unwinder errored out at secondary_startup_64 because the head code isn't annotated yet so there wasn't a corresponding ORC entry.

Fix that and any other head-related unwinding issues by adding unwind hints to the head code.

---
 arch/x86/kernel/Makefile  |  1 -
 arch/x86/kernel/head_64.S | 14 ++++++++++++--
 2 files changed, 12 insertions(+), 3 deletions(-)
arch/x86/kernel/Makefile +0 -1
index fd0a789..d8e2b70 100644
@@ -26,7 +26,6 @@ KASAN_SANITIZE_dumpstack.o				:= n
 KASAN_SANITIZE_dumpstack_$(BITS).o			:= n
 KASAN_SANITIZE_stacktrace.o := n
 
-OBJECT_FILES_NON_STANDARD_head_$(BITS).o		:= y
 OBJECT_FILES_NON_STANDARD_relocate_kernel_$(BITS).o	:= y
 OBJECT_FILES_NON_STANDARD_ftrace_$(BITS).o		:= y
 OBJECT_FILES_NON_STANDARD_test_nx.o			:= y
arch/x86/kernel/head_64.S +12 -2
index edacd57..42e32c2 100644
@@ -49,6 +49,7 @@ L3_START_KERNEL = pud_index(__START_KERNEL_map)
 	.code64
 	.globl startup_64
 startup_64:
+	UNWIND_HINT_EMPTY
 	/*
 	 * At this point the CPU runs in 64bit mode CS.L = 1 CS.D = 0,
 	 * and someone has loaded an identity mapped page table
@@ -88,6 +89,7 @@ startup_64:
 	addq	$(early_top_pgt - __START_KERNEL_map), %rax
 	jmp 1f
 ENTRY(secondary_startup_64)
+	UNWIND_HINT_EMPTY
 	/*
 	 * At this point the CPU runs in 64bit mode CS.L = 1 CS.D = 0,
 	 * and someone has loaded a mapped page table.
@@ -132,6 +134,7 @@ ENTRY(secondary_startup_64)
 	movq	$1f, %rax
 	jmp	*%rax
 1:
+	UNWIND_HINT_EMPTY
 
 	/* Check if nx is implemented */
 	movl	$0x80000001, %eax
@@ -246,6 +249,7 @@ END(secondary_startup_64)
  */
 ENTRY(start_cpu0)
 	movq	initial_stack(%rip), %rsp
+	UNWIND_HINT_EMPTY
 	jmp	.Ljump_to_C_code
 ENDPROC(start_cpu0)
 #endif
@@ -270,13 +274,18 @@ ENTRY(early_idt_handler_array)
 	i = 0
 	.rept NUM_EXCEPTION_VECTORS
 	.ifeq (EXCEPTION_ERRCODE_MASK >> i) & 1
-	pushq $0		# Dummy error code, to make stack frame uniform
+		UNWIND_HINT_IRET_REGS
+		pushq $0	# Dummy error code, to make stack frame uniform
+	.else
+		UNWIND_HINT_IRET_REGS offset=8
 	.endif
 	pushq $i		# 72(%rsp) Vector number
 	jmp early_idt_handler_common
+	UNWIND_HINT_IRET_REGS
 	i = i + 1
 	.fill early_idt_handler_array + i*EARLY_IDT_HANDLER_SIZE - ., 1, 0xcc
 	.endr
+	UNWIND_HINT_IRET_REGS offset=16
 END(early_idt_handler_array)
 
 early_idt_handler_common:
@@ -305,6 +314,7 @@ early_idt_handler_common:
 	pushq %r13				/* pt_regs->r13 */
 	pushq %r14				/* pt_regs->r14 */
 	pushq %r15				/* pt_regs->r15 */
+	UNWIND_HINT_REGS
 
 	cmpq $14,%rsi		/* Page fault? */
 	jnz 10f
@@ -427,7 +437,7 @@ ENTRY(phys_base)
 EXPORT_SYMBOL(phys_base)
 
 #include "../../x86/xen/xen-head.S"
-	
+
 	__PAGE_ALIGNED_BSS
 NEXT_PAGE(empty_zero_page)
 	.skip PAGE_SIZE