x86/asm: Add unwind hint annotations to head code
Subsystems (3)
cover x86/asm: Add unwind hint annotations to head code
Add some annotations to allow objtool to understand the head code.
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 | 10 +++++++--- tools/objtool/check.c | 7 +++++-- 5 files changed, 29 insertions(+), 19 deletions(-)
Signature · 1 line
2.13.5
PATCH 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
@@ -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
PATCH 2/8 x86/head: Remove confusing comment
In reply to Josh PoimboeufThis 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
@@ -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
PATCH 3/8 x86/head: Remove unused 'bad_address' code
In reply to Josh PoimboeufIt'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
@@ -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
PATCH 4/8 x86/head: Fix head ELF function annotations
In reply to Josh PoimboeufThese 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
@@ -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
PATCH 5/8 x86/boot: Annotate verify_cpu() as a callable function
In reply to Josh Poimboeufverify_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
@@ -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
PATCH 6/8 x86/xen: Fix xen head ELF annotations
In reply to Josh PoimboeufMark 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
@@ -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
PATCH 7/8 x86/xen: Add unwind hint annotations
In reply to Josh PoimboeufAdd 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 | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
arch/x86/xen/xen-head.S +5 -1
@@ -19,6 +19,7 @@ #ifdef CONFIG_XEN_PV __INIT ENTRY(startup_xen) + UNWIND_HINT_EMPTY cld /* Clear .bss */
@@ -40,7 +41,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
Re: [PATCH 7/8] x86/xen: Add unwind hint annotations
Quoted 2 lines · Josh Poimboeuf
Add unwind hint annotations to the xen head code so the ORC unwinder can read head_64.o.
xen-head.S is included also in head_32.S, so we see:arch/x86/kernel/../../x86/xen/xen-head.S:47: Error: no such instruction:
`unwind_hint_empty'scripts/Makefile.build:413: recipe for target 'arch/x86/kernel/head_32.o' failed
To fix this, I use:
arch/x86/kernel/head_32.S +1 -0
@@ -25,6 +25,7 @@ #include <asm/bootparam.h> #include <asm/export.h> #include <asm/pgtable_32.h> +#include "../entry/calling.h" /* Physical address */ #define pa(X) ((X) - __PAGE_OFFSET)
Quoted 33 lines
hypercall_pageneeds empty annotations at 32-byte intervals to match the 'xen_hypercall_*' ELF functions at those locations.Signed-off-by Josh Poimboeuf <[email protected]>--- arch/x86/xen/xen-head.S | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)arch/x86/xen/xen-head.S +5
-1@@ -19,6 +19,7 @@ #ifdef CONFIG_XEN_PV __INIT ENTRY(startup_xen) + UNWIND_HINT_EMPTY cld /* Clear .bss */@@ -40,7 +41,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 · 2 lines
js suse labs
Re: [PATCH 7/8] x86/xen: Add unwind hint annotations
Quoted 15 lines · Jiri Slaby
Quoted 2 lines · Josh Poimboeuf
Add unwind hint annotations to the xen head code so the ORC unwinder can read head_64.o.
xen-head.Sis included also inhead_32.S, so we see:arch/x86/kernel/../../x86/xen/xen-head.S:47: Error: no such instruction:
`unwind_hint_empty'scripts/Makefile.build:413: recipe for target 'arch/x86/kernel/head_32.o' failedTo fix this, I use:
arch/x86/kernel/head_32.S line 31
Quoted 7 lines
arch/x86/kernel/head_32.S +1
-0@@ -25,6 +25,7 @@ #include <asm/bootparam.h> #include <asm/export.h> #include <asm/pgtable_32.h> +#include "../entry/calling.h" /* Physical address */ #define pa(X) ((X) - __PAGE_OFFSET)
Thanks. 0-day reported this as well. Will fix this in v2.
Signature · 1 line
Josh
PATCH 8/8 x86/head: Add unwind hint annotations
In reply to Josh PoimboeufJiri 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/0xa0The 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
@@ -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
@@ -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