diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2025-09-30 13:40:35 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2025-09-30 13:40:35 -0700 |
| commit | 22bdd6e68bbe270a916233ec5f34a13ae5e80ed9 (patch) | |
| tree | 0d94e506ca828acd9939e83d1bbe8a3c8594e7a1 /tools/objtool | |
| parent | Merge tag 'x86_cache_for_v6.18_rc1' of git://git.kernel.org/pub/scm/linux/ker... (diff) | |
| parent | x86/boot: Drop erroneous __init annotation from early_set_pages_state() (diff) | |
| download | linux-22bdd6e68bbe270a916233ec5f34a13ae5e80ed9.tar.gz linux-22bdd6e68bbe270a916233ec5f34a13ae5e80ed9.zip | |
Merge tag 'x86_apic_for_v6.18_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 SEV and apic updates from Borislav Petkov:
- Add functionality to provide runtime firmware updates for the non-x86
parts of an AMD platform like the security processor (ASP) firmware,
modules etc, for example. The intent being that these updates are
interim, live fixups before a proper BIOS update can be attempted
- Add guest support for AMD's Secure AVIC feature which gives encrypted
guests the needed protection against a malicious hypervisor
generating unexpected interrupts and injecting them into such guest,
thus interfering with its operation in an unexpected and negative
manner.
The advantage of this scheme is that the guest determines which
interrupts and when to accept them vs leaving that to the benevolence
(or not) of the hypervisor
- Strictly separate the startup code from the rest of the kernel where
former is executed from the initial 1:1 mapping of memory.
The problem was that the toolchain-generated version of the code was
being executed from a different mapping of memory than what was
"assumed" during code generation, needing an ever-growing pile of
fixups for absolute memory references which are invalid in the early,
1:1 memory mapping during boot.
The major advantage of this is that there's no need to check the 1:1
mapping portion of the code for absolute relocations anymore and get
rid of the RIP_REL_REF() macro sprinkling all over the place.
For more info, see Ard's very detailed writeup on this [1]
- The usual cleanups and fixes
Link: https://lore.kernel.org/r/CAMj1kXEzKEuePEiHB%2BHxvfQbFz0sTiHdn4B%2B%2BzVBJ2mhkPkQ4Q@mail.gmail.com [1]
* tag 'x86_apic_for_v6.18_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (49 commits)
x86/boot: Drop erroneous __init annotation from early_set_pages_state()
crypto: ccp - Add AMD Seamless Firmware Servicing (SFS) driver
crypto: ccp - Add new HV-Fixed page allocation/free API
x86/sev: Add new dump_rmp parameter to snp_leak_pages() API
x86/startup/sev: Document the CPUID flow in the boot #VC handler
objtool: Ignore __pi___cfi_ prefixed symbols
x86/sev: Zap snp_abort()
x86/apic/savic: Do not use snp_abort()
x86/boot: Get rid of the .head.text section
x86/boot: Move startup code out of __head section
efistub/x86: Remap inittext read-execute when needed
x86/boot: Create a confined code area for startup code
x86/kbuild: Incorporate boot/startup/ via Kbuild makefile
x86/boot: Revert "Reject absolute references in .head.text"
x86/boot: Check startup code for absence of absolute relocations
objtool: Add action to check for absence of absolute relocations
x86/sev: Export startup routines for later use
x86/sev: Move __sev_[get|put]_ghcb() into separate noinstr object
x86/sev: Provide PIC aliases for SEV related data objects
x86/boot: Provide PIC aliases for 5-level paging related constants
...
Diffstat (limited to 'tools/objtool')
| -rw-r--r-- | tools/objtool/arch/x86/decode.c | 12 | ||||
| -rw-r--r-- | tools/objtool/builtin-check.c | 2 | ||||
| -rw-r--r-- | tools/objtool/check.c | 48 | ||||
| -rw-r--r-- | tools/objtool/include/objtool/arch.h | 1 | ||||
| -rw-r--r-- | tools/objtool/include/objtool/builtin.h | 1 | ||||
| -rw-r--r-- | tools/objtool/noreturns.h | 1 |
6 files changed, 63 insertions, 2 deletions
diff --git a/tools/objtool/arch/x86/decode.c b/tools/objtool/arch/x86/decode.c index 98c4713c1b09..0ad5cc70ecbe 100644 --- a/tools/objtool/arch/x86/decode.c +++ b/tools/objtool/arch/x86/decode.c @@ -880,3 +880,15 @@ unsigned int arch_reloc_size(struct reloc *reloc) return 8; } } + +bool arch_absolute_reloc(struct elf *elf, struct reloc *reloc) +{ + switch (reloc_type(reloc)) { + case R_X86_64_32: + case R_X86_64_32S: + case R_X86_64_64: + return true; + default: + return false; + } +} diff --git a/tools/objtool/builtin-check.c b/tools/objtool/builtin-check.c index 80239843e9f0..0f6b197cfcb0 100644 --- a/tools/objtool/builtin-check.c +++ b/tools/objtool/builtin-check.c @@ -87,6 +87,7 @@ static const struct option check_options[] = { OPT_BOOLEAN('t', "static-call", &opts.static_call, "annotate static calls"), OPT_BOOLEAN('u', "uaccess", &opts.uaccess, "validate uaccess rules for SMAP"), OPT_BOOLEAN(0 , "cfi", &opts.cfi, "annotate kernel control flow integrity (kCFI) function preambles"), + OPT_BOOLEAN(0 , "noabs", &opts.noabs, "reject absolute references in allocatable sections"), OPT_CALLBACK_OPTARG(0, "dump", NULL, NULL, "orc", "dump metadata", parse_dump), OPT_GROUP("Options:"), @@ -162,6 +163,7 @@ static bool opts_valid(void) opts.hack_noinstr || opts.ibt || opts.mcount || + opts.noabs || opts.noinstr || opts.orc || opts.retpoline || diff --git a/tools/objtool/check.c b/tools/objtool/check.c index d14f20ef1db1..093fcd01dd6e 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -3564,7 +3564,9 @@ static int validate_branch(struct objtool_file *file, struct symbol *func, if (func && insn_func(insn) && func != insn_func(insn)->pfunc) { /* Ignore KCFI type preambles, which always fall through */ if (!strncmp(func->name, "__cfi_", 6) || - !strncmp(func->name, "__pfx_", 6)) + !strncmp(func->name, "__pfx_", 6) || + !strncmp(func->name, "__pi___cfi_", 11) || + !strncmp(func->name, "__pi___pfx_", 11)) return 0; if (file->ignore_unreachables) @@ -4644,6 +4646,47 @@ static void disas_warned_funcs(struct objtool_file *file) disas_funcs(funcs); } +__weak bool arch_absolute_reloc(struct elf *elf, struct reloc *reloc) +{ + unsigned int type = reloc_type(reloc); + size_t sz = elf_addr_size(elf); + + return (sz == 8) ? (type == R_ABS64) : (type == R_ABS32); +} + +static int check_abs_references(struct objtool_file *file) +{ + struct section *sec; + struct reloc *reloc; + int ret = 0; + + for_each_sec(file, sec) { + /* absolute references in non-loadable sections are fine */ + if (!(sec->sh.sh_flags & SHF_ALLOC)) + continue; + + /* section must have an associated .rela section */ + if (!sec->rsec) + continue; + + /* + * Special case for compiler generated metadata that is not + * consumed until after boot. + */ + if (!strcmp(sec->name, "__patchable_function_entries")) + continue; + + for_each_reloc(sec->rsec, reloc) { + if (arch_absolute_reloc(file->elf, reloc)) { + WARN("section %s has absolute relocation at offset 0x%lx", + sec->name, reloc_offset(reloc)); + ret++; + } + } + } + return ret; +} + struct insn_chunk { void *addr; struct insn_chunk *next; @@ -4777,6 +4820,9 @@ int check(struct objtool_file *file) goto out; } + if (opts.noabs) + warnings += check_abs_references(file); + if (opts.orc && nr_insns) { ret = orc_create(file); if (ret) diff --git a/tools/objtool/include/objtool/arch.h b/tools/objtool/include/objtool/arch.h index 01ef6f415adf..be33c7b43180 100644 --- a/tools/objtool/include/objtool/arch.h +++ b/tools/objtool/include/objtool/arch.h @@ -97,6 +97,7 @@ bool arch_is_embedded_insn(struct symbol *sym); int arch_rewrite_retpolines(struct objtool_file *file); bool arch_pc_relative_reloc(struct reloc *reloc); +bool arch_absolute_reloc(struct elf *elf, struct reloc *reloc); unsigned int arch_reloc_size(struct reloc *reloc); unsigned long arch_jump_table_sym_offset(struct reloc *reloc, struct reloc *table); diff --git a/tools/objtool/include/objtool/builtin.h b/tools/objtool/include/objtool/builtin.h index 6b08666fa69d..ab22673862e1 100644 --- a/tools/objtool/include/objtool/builtin.h +++ b/tools/objtool/include/objtool/builtin.h @@ -26,6 +26,7 @@ struct opts { bool uaccess; int prefix; bool cfi; + bool noabs; /* options: */ bool backtrace; diff --git a/tools/objtool/noreturns.h b/tools/objtool/noreturns.h index 6a922d046b8e..802895fae3ca 100644 --- a/tools/objtool/noreturns.h +++ b/tools/objtool/noreturns.h @@ -45,7 +45,6 @@ NORETURN(rewind_stack_and_make_dead) NORETURN(rust_begin_unwind) NORETURN(rust_helper_BUG) NORETURN(sev_es_terminate) -NORETURN(snp_abort) NORETURN(start_kernel) NORETURN(stop_this_cpu) NORETURN(usercopy_abort) |
