From: Brian Gerst <brgerst@gmail.com>
To: linux-kernel@vger.kernel.org, x86@kernel.org
Cc: Ingo Molnar <mingo@kernel.org>,
Thomas Gleixner <tglx@linutronix.de>,
Borislav Petkov <bp@alien8.de>, "H . Peter Anvin" <hpa@zytor.com>,
Uros Bizjak <ubizjak@gmail.com>,
David.Laight@aculab.com, Brian Gerst <brgerst@gmail.com>
Subject: [PATCH v4 11/16] x86/boot/64: Remove inverse relocations
Date: Fri, 22 Mar 2024 12:52:28 -0400 [thread overview]
Message-ID: <20240322165233.71698-12-brgerst@gmail.com> (raw)
In-Reply-To: <20240322165233.71698-1-brgerst@gmail.com>
Inverse relocations were needed to offset the effects of relocation for
RIP-relative accesses to zero-based percpu data. Now that the percpu
section is linked normally as part of the kernel image, they are no
longer needed.
Signed-off-by: Brian Gerst <brgerst@gmail.com>
---
arch/x86/boot/compressed/misc.c | 14 +---
arch/x86/tools/relocs.c | 126 +-------------------------------
2 files changed, 2 insertions(+), 138 deletions(-)
diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c
index b70e4a21c15f..371288202268 100644
--- a/arch/x86/boot/compressed/misc.c
+++ b/arch/x86/boot/compressed/misc.c
@@ -235,7 +235,7 @@ static void handle_relocations(void *output, unsigned long output_len,
/*
* Process relocations: 32 bit relocations first then 64 bit after.
- * Three sets of binary relocations are added to the end of the kernel
+ * Two sets of binary relocations are added to the end of the kernel
* before compression. Each relocation table entry is the kernel
* address of the location which needs to be updated stored as a
* 32-bit value which is sign extended to 64 bits.
@@ -245,8 +245,6 @@ static void handle_relocations(void *output, unsigned long output_len,
* kernel bits...
* 0 - zero terminator for 64 bit relocations
* 64 bit relocation repeated
- * 0 - zero terminator for inverse 32 bit relocations
- * 32 bit inverse relocation repeated
* 0 - zero terminator for 32 bit relocations
* 32 bit relocation repeated
*
@@ -263,16 +261,6 @@ static void handle_relocations(void *output, unsigned long output_len,
*(uint32_t *)ptr += delta;
}
#ifdef CONFIG_X86_64
- while (*--reloc) {
- long extended = *reloc;
- extended += map;
-
- ptr = (unsigned long)extended;
- if (ptr < min_addr || ptr > max_addr)
- error("inverse 32-bit relocation outside of kernel!\n");
-
- *(int32_t *)ptr -= delta;
- }
for (reloc--; *reloc; reloc--) {
long extended = *reloc;
extended += map;
diff --git a/arch/x86/tools/relocs.c b/arch/x86/tools/relocs.c
index 65e6f3d6d890..e490297a486b 100644
--- a/arch/x86/tools/relocs.c
+++ b/arch/x86/tools/relocs.c
@@ -28,7 +28,6 @@ struct relocs {
static struct relocs relocs16;
static struct relocs relocs32;
#if ELF_BITS == 64
-static struct relocs relocs32neg;
static struct relocs relocs64;
#define FMT PRIu64
@@ -89,7 +88,6 @@ static const char * const sym_regex_kernel[S_NSYMTYPES] = {
"__initramfs_start|"
"(jiffies|jiffies_64)|"
#if ELF_BITS == 64
- "__per_cpu_load|"
"init_per_cpu__.*|"
"__end_rodata_hpage_align|"
#endif
@@ -287,33 +285,6 @@ static const char *sym_name(const char *sym_strtab, Elf_Sym *sym)
return name;
}
-static Elf_Sym *sym_lookup(const char *symname)
-{
- int i;
- for (i = 0; i < shnum; i++) {
- struct section *sec = &secs[i];
- long nsyms;
- char *strtab;
- Elf_Sym *symtab;
- Elf_Sym *sym;
-
- if (sec->shdr.sh_type != SHT_SYMTAB)
- continue;
-
- nsyms = sec->shdr.sh_size/sizeof(Elf_Sym);
- symtab = sec->symtab;
- strtab = sec->link->strtab;
-
- for (sym = symtab; --nsyms >= 0; sym++) {
- if (!sym->st_name)
- continue;
- if (strcmp(symname, strtab + sym->st_name) == 0)
- return sym;
- }
- }
- return 0;
-}
-
#if BYTE_ORDER == LITTLE_ENDIAN
#define le16_to_cpu(val) (val)
#define le32_to_cpu(val) (val)
@@ -773,75 +744,8 @@ static void walk_relocs(int (*process)(struct section *sec, Elf_Rel *rel,
}
}
-/*
- * The .data..percpu section is a special case for x86_64 SMP kernels.
- * It is used to initialize the actual per_cpu areas and to provide
- * definitions for the per_cpu variables that correspond to their offsets
- * within the percpu area. Since the values of all of the symbols need
- * to be offsets from the start of the per_cpu area the virtual address
- * (sh_addr) of .data..percpu is 0 in SMP kernels.
- *
- * This means that:
- *
- * Relocations that reference symbols in the per_cpu area do not
- * need further relocation (since the value is an offset relative
- * to the start of the per_cpu area that does not change).
- *
- * Relocations that apply to the per_cpu area need to have their
- * offset adjusted by by the value of __per_cpu_load to make them
- * point to the correct place in the loaded image (because the
- * virtual address of .data..percpu is 0).
- *
- * For non SMP kernels .data..percpu is linked as part of the normal
- * kernel data and does not require special treatment.
- *
- */
-static int per_cpu_shndx = -1;
-static Elf_Addr per_cpu_load_addr;
-
-static void percpu_init(void)
-{
- int i;
- for (i = 0; i < shnum; i++) {
- ElfW(Sym) *sym;
- if (strcmp(sec_name(i), ".data..percpu"))
- continue;
-
- if (secs[i].shdr.sh_addr != 0) /* non SMP kernel */
- return;
-
- sym = sym_lookup("__per_cpu_load");
- if (!sym)
- die("can't find __per_cpu_load\n");
-
- per_cpu_shndx = i;
- per_cpu_load_addr = sym->st_value;
- return;
- }
-}
-
#if ELF_BITS == 64
-/*
- * Check to see if a symbol lies in the .data..percpu section.
- *
- * The linker incorrectly associates some symbols with the
- * .data..percpu section so we also need to check the symbol
- * name to make sure that we classify the symbol correctly.
- *
- * The GNU linker incorrectly associates:
- * __init_begin
- * __per_cpu_load
- *
- * The "gold" linker incorrectly associates:
- * init_per_cpu__gdt_page
- */
-static int is_percpu_sym(ElfW(Sym) *sym, const char *symname)
-{
- return 0;
-}
-
-
static int do_reloc64(struct section *sec, Elf_Rel *rel, ElfW(Sym) *sym,
const char *symname)
{
@@ -852,12 +756,6 @@ static int do_reloc64(struct section *sec, Elf_Rel *rel, ElfW(Sym) *sym,
if (sym->st_shndx == SHN_UNDEF)
return 0;
- /*
- * Adjust the offset if this reloc applies to the percpu section.
- */
- if (sec->shdr.sh_info == per_cpu_shndx)
- offset += per_cpu_load_addr;
-
switch (r_type) {
case R_X86_64_NONE:
/* NONE can be ignored. */
@@ -867,33 +765,21 @@ static int do_reloc64(struct section *sec, Elf_Rel *rel, ElfW(Sym) *sym,
case R_X86_64_PLT32:
case R_X86_64_REX_GOTPCRELX:
/*
- * PC relative relocations don't need to be adjusted unless
- * referencing a percpu symbol.
+ * PC relative relocations don't need to be adjusted.
*
* NB: R_X86_64_PLT32 can be treated as R_X86_64_PC32.
*/
- if (is_percpu_sym(sym, symname))
- add_reloc(&relocs32neg, offset);
break;
case R_X86_64_PC64:
/*
* Only used by jump labels
*/
- if (is_percpu_sym(sym, symname))
- die("Invalid R_X86_64_PC64 relocation against per-CPU symbol %s\n",
- symname);
break;
case R_X86_64_32:
case R_X86_64_32S:
case R_X86_64_64:
- /*
- * References to the percpu area don't need to be adjusted.
- */
- if (is_percpu_sym(sym, symname))
- break;
-
if (shn_abs) {
/*
* Whitelisted absolute symbols do not require
@@ -1107,7 +993,6 @@ static void emit_relocs(int as_text, int use_real_mode)
/* Order the relocations for more efficient processing */
sort_relocs(&relocs32);
#if ELF_BITS == 64
- sort_relocs(&relocs32neg);
sort_relocs(&relocs64);
#else
sort_relocs(&relocs16);
@@ -1139,13 +1024,6 @@ static void emit_relocs(int as_text, int use_real_mode)
/* Now print each relocation */
for (i = 0; i < relocs64.count; i++)
write_reloc(relocs64.offset[i], stdout);
-
- /* Print a stop */
- write_reloc(0, stdout);
-
- /* Now print each inverse 32-bit relocation */
- for (i = 0; i < relocs32neg.count; i++)
- write_reloc(relocs32neg.offset[i], stdout);
#endif
/* Print a stop */
@@ -1196,8 +1074,6 @@ void process(FILE *fp, int use_real_mode, int as_text,
read_strtabs(fp);
read_symtabs(fp);
read_relocs(fp);
- if (ELF_BITS == 64)
- percpu_init();
if (show_absolute_syms) {
print_absolute_symbols();
return;
--
2.44.0
next prev parent reply other threads:[~2024-03-22 16:53 UTC|newest]
Thread overview: 42+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-03-22 16:52 [PATCH v4 00/16] x86-64: Stack protector and percpu improvements Brian Gerst
2024-03-22 16:52 ` [PATCH v4 01/16] x86/stackprotector/32: Remove stack protector test script Brian Gerst
2024-03-23 17:00 ` Uros Bizjak
2024-03-22 16:52 ` [PATCH v4 02/16] x86/stackprotector/64: " Brian Gerst
2024-03-23 17:01 ` Uros Bizjak
2024-03-22 16:52 ` [PATCH v4 03/16] x86/boot: Disable stack protector for early boot code Brian Gerst
2024-03-22 16:52 ` [PATCH v4 04/16] x86/pvh: Use fixed_percpu_data for early boot GSBASE Brian Gerst
2024-03-22 16:52 ` [PATCH v4 05/16] x86/relocs: Handle R_X86_64_REX_GOTPCRELX relocations Brian Gerst
2024-03-22 16:52 ` [PATCH v4 06/16] objtool: Allow adding relocations to an existing section Brian Gerst
2024-03-22 16:52 ` [PATCH v4 07/16] objtool: Convert fixed location stack protector accesses Brian Gerst
2024-03-22 16:52 ` [PATCH v4 08/16] x86/stackprotector/64: Convert to normal percpu variable Brian Gerst
2024-03-23 17:11 ` Uros Bizjak
2024-03-22 16:52 ` [PATCH v4 09/16] x86/percpu/64: Use relative percpu offsets Brian Gerst
2024-03-23 17:14 ` Uros Bizjak
2024-03-22 16:52 ` [PATCH v4 10/16] x86/percpu/64: Remove fixed_percpu_data Brian Gerst
2024-03-23 17:14 ` Uros Bizjak
2024-03-22 16:52 ` Brian Gerst [this message]
2024-03-22 16:52 ` [PATCH v4 12/16] x86/percpu/64: Remove INIT_PER_CPU macros Brian Gerst
2024-03-23 17:15 ` Uros Bizjak
2024-03-22 16:52 ` [PATCH v4 13/16] percpu: Remove PER_CPU_FIRST_SECTION Brian Gerst
2024-03-23 17:17 ` Uros Bizjak
2024-03-22 16:52 ` [PATCH v4 14/16] percpu: Remove PERCPU_VADDR() Brian Gerst
2024-03-22 16:52 ` [PATCH v4 15/16] percpu: Remove __per_cpu_load Brian Gerst
2024-03-22 16:52 ` [PATCH v4 16/16] kallsyms: Remove KALLSYMS_ABSOLUTE_PERCPU Brian Gerst
2024-03-23 11:39 ` [PATCH v4 00/16] x86-64: Stack protector and percpu improvements Uros Bizjak
2024-03-23 13:22 ` Brian Gerst
2024-03-23 16:16 ` Linus Torvalds
2024-03-23 17:06 ` Linus Torvalds
2024-03-24 19:09 ` David Laight
2024-03-25 14:51 ` Arnd Bergmann
2024-03-25 15:26 ` Takashi Iwai
2024-03-25 18:08 ` Arnd Bergmann
2024-03-26 7:02 ` Uros Bizjak
2024-03-23 22:55 ` Arnd Bergmann
2024-03-25 15:14 ` Ard Biesheuvel
2024-03-24 2:25 ` Ingo Molnar
2024-03-24 3:51 ` Brian Gerst
2024-03-24 4:05 ` Ingo Molnar
2024-03-24 5:43 ` Brian Gerst
2024-03-24 10:53 ` Ingo Molnar
2024-03-24 12:34 ` Brian Gerst
2024-03-24 18:14 ` Ingo Molnar
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240322165233.71698-12-brgerst@gmail.com \
--to=brgerst@gmail.com \
--cc=David.Laight@aculab.com \
--cc=bp@alien8.de \
--cc=hpa@zytor.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@kernel.org \
--cc=tglx@linutronix.de \
--cc=ubizjak@gmail.com \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.