Skip to content

Commit 54a012b

Browse files
committed
Merge tag 'objtool-urgent-2025-04-10' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull misc objtool fixes from Ingo Molnar: - Remove the recently introduced ANNOTATE_IGNORE_ALTERNATIVE noise from clac()/stac() code to make .s files more readable - Fix INSN_SYSCALL / INSN_SYSRET semantics - Fix various false-positive warnings * tag 'objtool-urgent-2025-04-10' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: objtool: Fix false-positive "ignoring unreachables" warning objtool: Remove ANNOTATE_IGNORE_ALTERNATIVE from CLAC/STAC objtool, xen: Fix INSN_SYSCALL / INSN_SYSRET semantics objtool: Stop UNRET validation on UD2 objtool: Split INSN_CONTEXT_SWITCH into INSN_SYSCALL and INSN_SYSRET objtool: Fix INSN_CONTEXT_SWITCH handling in validate_unret()
2 parents ab59a86 + 87cb582 commit 54a012b

File tree

6 files changed

+72
-26
lines changed

6 files changed

+72
-26
lines changed

arch/x86/include/asm/smap.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,23 +16,23 @@
1616
#ifdef __ASSEMBLER__
1717

1818
#define ASM_CLAC \
19-
ALTERNATIVE __stringify(ANNOTATE_IGNORE_ALTERNATIVE), "clac", X86_FEATURE_SMAP
19+
ALTERNATIVE "", "clac", X86_FEATURE_SMAP
2020

2121
#define ASM_STAC \
22-
ALTERNATIVE __stringify(ANNOTATE_IGNORE_ALTERNATIVE), "stac", X86_FEATURE_SMAP
22+
ALTERNATIVE "", "stac", X86_FEATURE_SMAP
2323

2424
#else /* __ASSEMBLER__ */
2525

2626
static __always_inline void clac(void)
2727
{
2828
/* Note: a barrier is implicit in alternative() */
29-
alternative(ANNOTATE_IGNORE_ALTERNATIVE "", "clac", X86_FEATURE_SMAP);
29+
alternative("", "clac", X86_FEATURE_SMAP);
3030
}
3131

3232
static __always_inline void stac(void)
3333
{
3434
/* Note: a barrier is implicit in alternative() */
35-
alternative(ANNOTATE_IGNORE_ALTERNATIVE "", "stac", X86_FEATURE_SMAP);
35+
alternative("", "stac", X86_FEATURE_SMAP);
3636
}
3737

3838
static __always_inline unsigned long smap_save(void)
@@ -59,9 +59,9 @@ static __always_inline void smap_restore(unsigned long flags)
5959

6060
/* These macros can be used in asm() statements */
6161
#define ASM_CLAC \
62-
ALTERNATIVE(ANNOTATE_IGNORE_ALTERNATIVE "", "clac", X86_FEATURE_SMAP)
62+
ALTERNATIVE("", "clac", X86_FEATURE_SMAP)
6363
#define ASM_STAC \
64-
ALTERNATIVE(ANNOTATE_IGNORE_ALTERNATIVE "", "stac", X86_FEATURE_SMAP)
64+
ALTERNATIVE("", "stac", X86_FEATURE_SMAP)
6565

6666
#define ASM_CLAC_UNSAFE \
6767
ALTERNATIVE("", ANNOTATE_IGNORE_ALTERNATIVE "clac", X86_FEATURE_SMAP)

arch/x86/xen/xen-asm.S

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -226,9 +226,7 @@ SYM_CODE_END(xen_early_idt_handler_array)
226226
push %rax
227227
mov $__HYPERVISOR_iret, %eax
228228
syscall /* Do the IRET. */
229-
#ifdef CONFIG_MITIGATION_SLS
230-
int3
231-
#endif
229+
ud2 /* The SYSCALL should never return. */
232230
.endm
233231

234232
SYM_CODE_START(xen_iret)

tools/objtool/arch/x86/decode.c

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -522,7 +522,7 @@ int arch_decode_instruction(struct objtool_file *file, const struct section *sec
522522
case INAT_PFX_REPNE:
523523
if (modrm == 0xca)
524524
/* eretu/erets */
525-
insn->type = INSN_CONTEXT_SWITCH;
525+
insn->type = INSN_SYSRET;
526526
break;
527527
default:
528528
if (modrm == 0xca)
@@ -535,11 +535,15 @@ int arch_decode_instruction(struct objtool_file *file, const struct section *sec
535535

536536
insn->type = INSN_JUMP_CONDITIONAL;
537537

538-
} else if (op2 == 0x05 || op2 == 0x07 || op2 == 0x34 ||
539-
op2 == 0x35) {
538+
} else if (op2 == 0x05 || op2 == 0x34) {
540539

541-
/* sysenter, sysret */
542-
insn->type = INSN_CONTEXT_SWITCH;
540+
/* syscall, sysenter */
541+
insn->type = INSN_SYSCALL;
542+
543+
} else if (op2 == 0x07 || op2 == 0x35) {
544+
545+
/* sysret, sysexit */
546+
insn->type = INSN_SYSRET;
543547

544548
} else if (op2 == 0x0b || op2 == 0xb9) {
545549

@@ -676,7 +680,7 @@ int arch_decode_instruction(struct objtool_file *file, const struct section *sec
676680

677681
case 0xca: /* retf */
678682
case 0xcb: /* retf */
679-
insn->type = INSN_CONTEXT_SWITCH;
683+
insn->type = INSN_SYSRET;
680684
break;
681685

682686
case 0xe0: /* loopne */
@@ -721,7 +725,7 @@ int arch_decode_instruction(struct objtool_file *file, const struct section *sec
721725
} else if (modrm_reg == 5) {
722726

723727
/* jmpf */
724-
insn->type = INSN_CONTEXT_SWITCH;
728+
insn->type = INSN_SYSRET;
725729

726730
} else if (modrm_reg == 6) {
727731

tools/objtool/arch/x86/special.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ struct reloc *arch_find_switch_table(struct objtool_file *file,
126126
* indicates a rare GCC quirk/bug which can leave dead
127127
* code behind.
128128
*/
129-
if (reloc_type(text_reloc) == R_X86_64_PC32) {
129+
if (!file->ignore_unreachables && reloc_type(text_reloc) == R_X86_64_PC32) {
130130
WARN_INSN(insn, "ignoring unreachables due to jump table quirk");
131131
file->ignore_unreachables = true;
132132
}

tools/objtool/check.c

Lines changed: 51 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3505,6 +3505,34 @@ static struct instruction *next_insn_to_validate(struct objtool_file *file,
35053505
return next_insn_same_sec(file, alt_group->orig_group->last_insn);
35063506
}
35073507

3508+
static bool skip_alt_group(struct instruction *insn)
3509+
{
3510+
struct instruction *alt_insn = insn->alts ? insn->alts->insn : NULL;
3511+
3512+
/* ANNOTATE_IGNORE_ALTERNATIVE */
3513+
if (insn->alt_group && insn->alt_group->ignore)
3514+
return true;
3515+
3516+
/*
3517+
* For NOP patched with CLAC/STAC, only follow the latter to avoid
3518+
* impossible code paths combining patched CLAC with unpatched STAC
3519+
* or vice versa.
3520+
*
3521+
* ANNOTATE_IGNORE_ALTERNATIVE could have been used here, but Linus
3522+
* requested not to do that to avoid hurting .s file readability
3523+
* around CLAC/STAC alternative sites.
3524+
*/
3525+
3526+
if (!alt_insn)
3527+
return false;
3528+
3529+
/* Don't override ASM_{CLAC,STAC}_UNSAFE */
3530+
if (alt_insn->alt_group && alt_insn->alt_group->ignore)
3531+
return false;
3532+
3533+
return alt_insn->type == INSN_CLAC || alt_insn->type == INSN_STAC;
3534+
}
3535+
35083536
/*
35093537
* Follow the branch starting at the given instruction, and recursively follow
35103538
* any other branches (jumps). Meanwhile, track the frame pointer state at
@@ -3625,7 +3653,7 @@ static int validate_branch(struct objtool_file *file, struct symbol *func,
36253653
}
36263654
}
36273655

3628-
if (insn->alt_group && insn->alt_group->ignore)
3656+
if (skip_alt_group(insn))
36293657
return 0;
36303658

36313659
if (handle_insn_ops(insn, next_insn, &state))
@@ -3684,14 +3712,20 @@ static int validate_branch(struct objtool_file *file, struct symbol *func,
36843712

36853713
break;
36863714

3687-
case INSN_CONTEXT_SWITCH:
3688-
if (func) {
3689-
if (!next_insn || !next_insn->hint) {
3690-
WARN_INSN(insn, "unsupported instruction in callable function");
3691-
return 1;
3692-
}
3693-
break;
3715+
case INSN_SYSCALL:
3716+
if (func && (!next_insn || !next_insn->hint)) {
3717+
WARN_INSN(insn, "unsupported instruction in callable function");
3718+
return 1;
3719+
}
3720+
3721+
break;
3722+
3723+
case INSN_SYSRET:
3724+
if (func && (!next_insn || !next_insn->hint)) {
3725+
WARN_INSN(insn, "unsupported instruction in callable function");
3726+
return 1;
36943727
}
3728+
36953729
return 0;
36963730

36973731
case INSN_STAC:
@@ -3886,6 +3920,12 @@ static int validate_unret(struct objtool_file *file, struct instruction *insn)
38863920
WARN_INSN(insn, "RET before UNTRAIN");
38873921
return 1;
38883922

3923+
case INSN_SYSCALL:
3924+
break;
3925+
3926+
case INSN_SYSRET:
3927+
return 0;
3928+
38893929
case INSN_NOP:
38903930
if (insn->retpoline_safe)
38913931
return 0;
@@ -3895,6 +3935,9 @@ static int validate_unret(struct objtool_file *file, struct instruction *insn)
38953935
break;
38963936
}
38973937

3938+
if (insn->dead_end)
3939+
return 0;
3940+
38983941
if (!next) {
38993942
WARN_INSN(insn, "teh end!");
39003943
return 1;

tools/objtool/include/objtool/arch.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ enum insn_type {
1919
INSN_CALL,
2020
INSN_CALL_DYNAMIC,
2121
INSN_RETURN,
22-
INSN_CONTEXT_SWITCH,
22+
INSN_SYSCALL,
23+
INSN_SYSRET,
2324
INSN_BUG,
2425
INSN_NOP,
2526
INSN_STAC,

0 commit comments

Comments
 (0)