Patch "x86-64: Handle PC-relative relocations on per-CPU data" has been added to the 3.18-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
x86-64: Handle PC-relative relocations on per-CPU data
to the 3.18-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
x86-64-handle-pc-relative-relocations-on-per-cpu-data.patch
and it can be found in the queue-3.18 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
6d24c5f72dfb26e5fa7f02fa9266dfdbae41adbaMon Sep 17 00:00:00 2001
From: Jan Beulich <[email protected]>
Date: Tue, 4 Nov 2014 08:50:18 +0000
Subject: x86-64: Handle PC-relative relocations on per-CPU data
From: Jan Beulich <[email protected]>
commit 6d24c5f72dfb26e5fa7f02fa9266dfdbae41adba upstream.
This is in preparation of using RIP-relative addressing in many of the per-CPU accesses.
--- arch/x86/boot/compressed/misc.c | 14 +++++++++++++- arch/x86/tools/relocs.c | 38 ++++++++++++++++++++++++++++---------- 2 files changed, 41 insertions(+), 11 deletions(-)
arch/x86/boot/compressed/misc.c +13 -1
@@ -260,7 +260,7 @@ static void handle_relocations(void *out/* * Process relocations: 32 bit relocations first then 64 bit after. -* Two sets of binary relocations are added to the end of the kernel +* Three 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.
@@ -270,6 +270,8 @@ static void handle_relocations(void *out* 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 *
@@ -286,6 +288,16 @@ static void handle_relocations(void *out *(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;
arch/x86/tools/relocs.c +28 -10
@@ -20,7 +20,10 @@ struct relocs {static struct relocs relocs16;static struct relocs relocs32; +#if ELF_BITS ==64 +static struct relocs relocs32neg;static struct relocs relocs64; +#endif struct section {Elf_Shdr shdr;
@@ -762,11 +765,16 @@ static int do_reloc64(struct section *seswitch (r_type) {case R_X86_64_NONE : +/* NONE can be ignored. */ +break ; +case R_X86_64_PC32 :/* -* NONE can be ignored and PC relative relocations don't -* need to be adjusted. +* PC relative relocations don't need to be adjusted unless +* referencing a percpu symbol. */ +if (is_percpu_sym (sym, symname)) +add_reloc (&relocs32neg, offset);break ;case R_X86_64_32 :
@@ -986,7 +994,10 @@ static void emit_relocs(int as_text, int/* Order the relocations for more efficient processing */ sort_relocs (&relocs16);sort_relocs (&relocs32); +#if ELF_BITS ==64 +sort_relocs (&relocs32neg);sort_relocs (&relocs64); +#endif /* Print the relocations */ if (as_text) {
@@ -1007,14 +1018,21 @@ static void emit_relocs(int as_text, intfor (i =0 ; i < relocs32.count; i++)write_reloc (relocs32.offset[i], stdout); }else { -if (ELF_BITS ==64 ) { -/* Print a stop */ -write_reloc (0 , stdout); - -/* Now print each relocation */ -for (i =0 ; i < relocs64.count; i++) -write_reloc (relocs64.offset[i], stdout); - } +#if ELF_BITS ==64 +/* Print a stop */ +write_reloc (0 , stdout); + +/* 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 */ write_reloc (0 , stdout);
Patches currently in stable-queue which might be from [email protected] are
queue-3.18/x86-64-handle-pc-relative-relocations-on-per-cpu-data.patch