aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/boot
diff options
context:
space:
mode:
authorJan Beulich <JBeulich@suse.com>2014-11-04 03:50:18 -0500
committerThomas Gleixner <tglx@linutronix.de>2014-11-04 14:43:14 -0500
commit6d24c5f72dfb26e5fa7f02fa9266dfdbae41adba (patch)
tree02a65c8228a6a6bfc0e0c89c6c749e491b2bda8b /arch/x86/boot
parent2c773dd31fbacbbb6425f8a9d3f97e0010272368 (diff)
x86-64: Handle PC-relative relocations on per-CPU data
This is in preparation of using RIP-relative addressing in many of the per-CPU accesses. Signed-off-by: Jan Beulich <jbeulich@suse.com> Link: http://lkml.kernel.org/r/5458A15A0200007800044A9A@mail.emea.novell.com Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'arch/x86/boot')
-rw-r--r--arch/x86/boot/compressed/misc.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c
index 57ab74df7eea..644abd767c12 100644
--- a/arch/x86/boot/compressed/misc.c
+++ b/arch/x86/boot/compressed/misc.c
@@ -260,7 +260,7 @@ static void handle_relocations(void *output, unsigned long output_len)
260 260
261 /* 261 /*
262 * Process relocations: 32 bit relocations first then 64 bit after. 262 * Process relocations: 32 bit relocations first then 64 bit after.
263 * Two sets of binary relocations are added to the end of the kernel 263 * Three sets of binary relocations are added to the end of the kernel
264 * before compression. Each relocation table entry is the kernel 264 * before compression. Each relocation table entry is the kernel
265 * address of the location which needs to be updated stored as a 265 * address of the location which needs to be updated stored as a
266 * 32-bit value which is sign extended to 64 bits. 266 * 32-bit value which is sign extended to 64 bits.
@@ -270,6 +270,8 @@ static void handle_relocations(void *output, unsigned long output_len)
270 * kernel bits... 270 * kernel bits...
271 * 0 - zero terminator for 64 bit relocations 271 * 0 - zero terminator for 64 bit relocations
272 * 64 bit relocation repeated 272 * 64 bit relocation repeated
273 * 0 - zero terminator for inverse 32 bit relocations
274 * 32 bit inverse relocation repeated
273 * 0 - zero terminator for 32 bit relocations 275 * 0 - zero terminator for 32 bit relocations
274 * 32 bit relocation repeated 276 * 32 bit relocation repeated
275 * 277 *
@@ -286,6 +288,16 @@ static void handle_relocations(void *output, unsigned long output_len)
286 *(uint32_t *)ptr += delta; 288 *(uint32_t *)ptr += delta;
287 } 289 }
288#ifdef CONFIG_X86_64 290#ifdef CONFIG_X86_64
291 while (*--reloc) {
292 long extended = *reloc;
293 extended += map;
294
295 ptr = (unsigned long)extended;
296 if (ptr < min_addr || ptr > max_addr)
297 error("inverse 32-bit relocation outside of kernel!\n");
298
299 *(int32_t *)ptr -= delta;
300 }
289 for (reloc--; *reloc; reloc--) { 301 for (reloc--; *reloc; reloc--) {
290 long extended = *reloc; 302 long extended = *reloc;
291 extended += map; 303 extended += map;