aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/boot/compressed/misc.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-12-10 15:10:24 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-12-10 15:10:24 -0500
commitb6444bd0a18eb47343e16749ce80a6ebd521f124 (patch)
tree989881a237552dbe3fb36df45b4eda6dbd5fc09f /arch/x86/boot/compressed/misc.c
parent9d0cf6f56454c8a71e0aa2c3b9c6cbe470eb2788 (diff)
parent97b67ae559947f1e208439a1bf6a734da3087006 (diff)
Merge branch 'x86-boot-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 boot and percpu updates from Ingo Molnar: "This tree contains a bootable images documentation update plus three slightly misplaced x86/asm percpu changes/optimizations" * 'x86-boot-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86-64: Use RIP-relative addressing for most per-CPU accesses x86-64: Handle PC-relative relocations on per-CPU data x86: Convert a few more per-CPU items to read-mostly ones x86, boot: Document intermediates more clearly
Diffstat (limited to 'arch/x86/boot/compressed/misc.c')
-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 30dd59a9f0b4..dcc1c536cc21 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;