Commit de55bbbff21ce8e11271c3032086b082af815864

Authored by Linus Torvalds

Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 fixes from Ingo Molnar:
 "Microcode fixes, a Xen fix and a KASLR boot loading fix with certain
  memory layouts"

* 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86, microcode, AMD: Fix ucode patch stashing on 32-bit
  x86/core, x86/xen/smp: Use 'die_complete' completion when taking CPU down
  x86, microcode: Fix accessing dis_ucode_ldr on 32-bit
  x86, kaslr: Prevent .bss from overlaping initrd
  x86, microcode, AMD: Fix early ucode loading on 32-bit

Showing 11 changed files Side-by-side Diff

arch/x86/boot/compressed/Makefile
... ... @@ -76,8 +76,10 @@
76 76 suffix-$(CONFIG_KERNEL_LZO) := lzo
77 77 suffix-$(CONFIG_KERNEL_LZ4) := lz4
78 78  
  79 +RUN_SIZE = $(shell objdump -h vmlinux | \
  80 + perl $(srctree)/arch/x86/tools/calc_run_size.pl)
79 81 quiet_cmd_mkpiggy = MKPIGGY $@
80   - cmd_mkpiggy = $(obj)/mkpiggy $< > $@ || ( rm -f $@ ; false )
  82 + cmd_mkpiggy = $(obj)/mkpiggy $< $(RUN_SIZE) > $@ || ( rm -f $@ ; false )
81 83  
82 84 targets += piggy.S
83 85 $(obj)/piggy.S: $(obj)/vmlinux.bin.$(suffix-y) $(obj)/mkpiggy FORCE
arch/x86/boot/compressed/head_32.S
... ... @@ -207,7 +207,8 @@
207 207 * Do the decompression, and jump to the new kernel..
208 208 */
209 209 /* push arguments for decompress_kernel: */
210   - pushl $z_output_len /* decompressed length */
  210 + pushl $z_run_size /* size of kernel with .bss and .brk */
  211 + pushl $z_output_len /* decompressed length, end of relocs */
211 212 leal z_extract_offset_negative(%ebx), %ebp
212 213 pushl %ebp /* output address */
213 214 pushl $z_input_len /* input_len */
... ... @@ -217,7 +218,7 @@
217 218 pushl %eax /* heap area */
218 219 pushl %esi /* real mode pointer */
219 220 call decompress_kernel /* returns kernel location in %eax */
220   - addl $24, %esp
  221 + addl $28, %esp
221 222  
222 223 /*
223 224 * Jump to the decompressed kernel.
arch/x86/boot/compressed/head_64.S
... ... @@ -402,13 +402,16 @@
402 402 * Do the decompression, and jump to the new kernel..
403 403 */
404 404 pushq %rsi /* Save the real mode argument */
  405 + movq $z_run_size, %r9 /* size of kernel with .bss and .brk */
  406 + pushq %r9
405 407 movq %rsi, %rdi /* real mode address */
406 408 leaq boot_heap(%rip), %rsi /* malloc area for uncompression */
407 409 leaq input_data(%rip), %rdx /* input_data */
408 410 movl $z_input_len, %ecx /* input_len */
409 411 movq %rbp, %r8 /* output target address */
410   - movq $z_output_len, %r9 /* decompressed length */
  412 + movq $z_output_len, %r9 /* decompressed length, end of relocs */
411 413 call decompress_kernel /* returns kernel location in %rax */
  414 + popq %r9
412 415 popq %rsi
413 416  
414 417 /*
arch/x86/boot/compressed/misc.c
... ... @@ -358,7 +358,8 @@
358 358 unsigned char *input_data,
359 359 unsigned long input_len,
360 360 unsigned char *output,
361   - unsigned long output_len)
  361 + unsigned long output_len,
  362 + unsigned long run_size)
362 363 {
363 364 real_mode = rmode;
364 365  
... ... @@ -381,8 +382,14 @@
381 382 free_mem_ptr = heap; /* Heap */
382 383 free_mem_end_ptr = heap + BOOT_HEAP_SIZE;
383 384  
384   - output = choose_kernel_location(input_data, input_len,
385   - output, output_len);
  385 + /*
  386 + * The memory hole needed for the kernel is the larger of either
  387 + * the entire decompressed kernel plus relocation table, or the
  388 + * entire decompressed kernel plus .bss and .brk sections.
  389 + */
  390 + output = choose_kernel_location(input_data, input_len, output,
  391 + output_len > run_size ? output_len
  392 + : run_size);
386 393  
387 394 /* Validate memory location choices. */
388 395 if ((unsigned long)output & (MIN_KERNEL_ALIGN - 1))
arch/x86/boot/compressed/mkpiggy.c
... ... @@ -36,11 +36,13 @@
36 36 uint32_t olen;
37 37 long ilen;
38 38 unsigned long offs;
  39 + unsigned long run_size;
39 40 FILE *f = NULL;
40 41 int retval = 1;
41 42  
42   - if (argc < 2) {
43   - fprintf(stderr, "Usage: %s compressed_file\n", argv[0]);
  43 + if (argc < 3) {
  44 + fprintf(stderr, "Usage: %s compressed_file run_size\n",
  45 + argv[0]);
44 46 goto bail;
45 47 }
46 48  
... ... @@ -74,6 +76,7 @@
74 76 offs += olen >> 12; /* Add 8 bytes for each 32K block */
75 77 offs += 64*1024 + 128; /* Add 64K + 128 bytes slack */
76 78 offs = (offs+4095) & ~4095; /* Round to a 4K boundary */
  79 + run_size = atoi(argv[2]);
77 80  
78 81 printf(".section \".rodata..compressed\",\"a\",@progbits\n");
79 82 printf(".globl z_input_len\n");
... ... @@ -85,6 +88,8 @@
85 88 /* z_extract_offset_negative allows simplification of head_32.S */
86 89 printf(".globl z_extract_offset_negative\n");
87 90 printf("z_extract_offset_negative = -0x%lx\n", offs);
  91 + printf(".globl z_run_size\n");
  92 + printf("z_run_size = %lu\n", run_size);
88 93  
89 94 printf(".globl input_data, input_data_end\n");
90 95 printf("input_data:\n");
arch/x86/include/asm/smp.h
... ... @@ -150,6 +150,7 @@
150 150 }
151 151  
152 152 void cpu_disable_common(void);
  153 +void cpu_die_common(unsigned int cpu);
153 154 void native_smp_prepare_boot_cpu(void);
154 155 void native_smp_prepare_cpus(unsigned int max_cpus);
155 156 void native_smp_cpus_done(unsigned int max_cpus);
arch/x86/kernel/cpu/microcode/amd_early.c
... ... @@ -108,12 +108,13 @@
108 108 * load_microcode_amd() to save equivalent cpu table and microcode patches in
109 109 * kernel heap memory.
110 110 */
111   -static void apply_ucode_in_initrd(void *ucode, size_t size)
  111 +static void apply_ucode_in_initrd(void *ucode, size_t size, bool save_patch)
112 112 {
113 113 struct equiv_cpu_entry *eq;
114 114 size_t *cont_sz;
115 115 u32 *header;
116 116 u8 *data, **cont;
  117 + u8 (*patch)[PATCH_MAX_SIZE];
117 118 u16 eq_id = 0;
118 119 int offset, left;
119 120 u32 rev, eax, ebx, ecx, edx;
120 121  
... ... @@ -123,10 +124,12 @@
123 124 new_rev = (u32 *)__pa_nodebug(&ucode_new_rev);
124 125 cont_sz = (size_t *)__pa_nodebug(&container_size);
125 126 cont = (u8 **)__pa_nodebug(&container);
  127 + patch = (u8 (*)[PATCH_MAX_SIZE])__pa_nodebug(&amd_ucode_patch);
126 128 #else
127 129 new_rev = &ucode_new_rev;
128 130 cont_sz = &container_size;
129 131 cont = &container;
  132 + patch = &amd_ucode_patch;
130 133 #endif
131 134  
132 135 data = ucode;
... ... @@ -213,9 +216,9 @@
213 216 rev = mc->hdr.patch_id;
214 217 *new_rev = rev;
215 218  
216   - /* save ucode patch */
217   - memcpy(amd_ucode_patch, mc,
218   - min_t(u32, header[1], PATCH_MAX_SIZE));
  219 + if (save_patch)
  220 + memcpy(patch, mc,
  221 + min_t(u32, header[1], PATCH_MAX_SIZE));
219 222 }
220 223 }
221 224  
... ... @@ -246,7 +249,7 @@
246 249 *data = cp.data;
247 250 *size = cp.size;
248 251  
249   - apply_ucode_in_initrd(cp.data, cp.size);
  252 + apply_ucode_in_initrd(cp.data, cp.size, true);
250 253 }
251 254  
252 255 #ifdef CONFIG_X86_32
... ... @@ -263,7 +266,7 @@
263 266 size_t *usize;
264 267 void **ucode;
265 268  
266   - mc = (struct microcode_amd *)__pa(amd_ucode_patch);
  269 + mc = (struct microcode_amd *)__pa_nodebug(amd_ucode_patch);
267 270 if (mc->hdr.patch_id && mc->hdr.processor_rev_id) {
268 271 __apply_microcode_amd(mc);
269 272 return;
... ... @@ -275,7 +278,7 @@
275 278 if (!*ucode || !*usize)
276 279 return;
277 280  
278   - apply_ucode_in_initrd(*ucode, *usize);
  281 + apply_ucode_in_initrd(*ucode, *usize, false);
279 282 }
280 283  
281 284 static void __init collect_cpu_sig_on_bsp(void *arg)
... ... @@ -339,7 +342,7 @@
339 342 * AP has a different equivalence ID than BSP, looks like
340 343 * mixed-steppings silicon so go through the ucode blob anew.
341 344 */
342   - apply_ucode_in_initrd(ucode_cpio.data, ucode_cpio.size);
  345 + apply_ucode_in_initrd(ucode_cpio.data, ucode_cpio.size, false);
343 346 }
344 347 }
345 348 #endif
346 349  
... ... @@ -347,7 +350,9 @@
347 350 int __init save_microcode_in_initrd_amd(void)
348 351 {
349 352 unsigned long cont;
  353 + int retval = 0;
350 354 enum ucode_state ret;
  355 + u8 *cont_va;
351 356 u32 eax;
352 357  
353 358 if (!container)
354 359  
... ... @@ -355,13 +360,15 @@
355 360  
356 361 #ifdef CONFIG_X86_32
357 362 get_bsp_sig();
358   - cont = (unsigned long)container;
  363 + cont = (unsigned long)container;
  364 + cont_va = __va(container);
359 365 #else
360 366 /*
361 367 * We need the physical address of the container for both bitness since
362 368 * boot_params.hdr.ramdisk_image is a physical address.
363 369 */
364   - cont = __pa(container);
  370 + cont = __pa(container);
  371 + cont_va = container;
365 372 #endif
366 373  
367 374 /*
... ... @@ -372,6 +379,8 @@
372 379 if (relocated_ramdisk)
373 380 container = (u8 *)(__va(relocated_ramdisk) +
374 381 (cont - boot_params.hdr.ramdisk_image));
  382 + else
  383 + container = cont_va;
375 384  
376 385 if (ucode_new_rev)
377 386 pr_info("microcode: updated early to new patch_level=0x%08x\n",
... ... @@ -382,7 +391,7 @@
382 391  
383 392 ret = load_microcode_amd(eax, container, container_size);
384 393 if (ret != UCODE_OK)
385   - return -EINVAL;
  394 + retval = -EINVAL;
386 395  
387 396 /*
388 397 * This will be freed any msec now, stash patches for the current
... ... @@ -391,6 +400,6 @@
391 400 container = NULL;
392 401 container_size = 0;
393 402  
394   - return 0;
  403 + return retval;
395 404 }
arch/x86/kernel/cpu/microcode/core_early.c
... ... @@ -124,7 +124,7 @@
124 124 static bool check_loader_disabled_ap(void)
125 125 {
126 126 #ifdef CONFIG_X86_32
127   - return __pa_nodebug(dis_ucode_ldr);
  127 + return *((bool *)__pa_nodebug(&dis_ucode_ldr));
128 128 #else
129 129 return dis_ucode_ldr;
130 130 #endif
arch/x86/kernel/smpboot.c
... ... @@ -1303,10 +1303,14 @@
1303 1303 numa_remove_cpu(cpu);
1304 1304 }
1305 1305  
  1306 +static DEFINE_PER_CPU(struct completion, die_complete);
  1307 +
1306 1308 void cpu_disable_common(void)
1307 1309 {
1308 1310 int cpu = smp_processor_id();
1309 1311  
  1312 + init_completion(&per_cpu(die_complete, smp_processor_id()));
  1313 +
1310 1314 remove_siblinginfo(cpu);
1311 1315  
1312 1316 /* It's now safe to remove this processor from the online map */
... ... @@ -1316,8 +1320,6 @@
1316 1320 fixup_irqs();
1317 1321 }
1318 1322  
1319   -static DEFINE_PER_CPU(struct completion, die_complete);
1320   -
1321 1323 int native_cpu_disable(void)
1322 1324 {
1323 1325 int ret;
1324 1326  
1325 1327  
... ... @@ -1327,16 +1329,21 @@
1327 1329 return ret;
1328 1330  
1329 1331 clear_local_APIC();
1330   - init_completion(&per_cpu(die_complete, smp_processor_id()));
1331 1332 cpu_disable_common();
1332 1333  
1333 1334 return 0;
1334 1335 }
1335 1336  
  1337 +void cpu_die_common(unsigned int cpu)
  1338 +{
  1339 + wait_for_completion_timeout(&per_cpu(die_complete, cpu), HZ);
  1340 +}
  1341 +
1336 1342 void native_cpu_die(unsigned int cpu)
1337 1343 {
1338 1344 /* We don't do anything here: idle task is faking death itself. */
1339   - wait_for_completion_timeout(&per_cpu(die_complete, cpu), HZ);
  1345 +
  1346 + cpu_die_common(cpu);
1340 1347  
1341 1348 /* They ack this in play_dead() by setting CPU_DEAD */
1342 1349 if (per_cpu(cpu_state, cpu) == CPU_DEAD) {
arch/x86/tools/calc_run_size.pl
  1 +#!/usr/bin/perl
  2 +#
  3 +# Calculate the amount of space needed to run the kernel, including room for
  4 +# the .bss and .brk sections.
  5 +#
  6 +# Usage:
  7 +# objdump -h a.out | perl calc_run_size.pl
  8 +use strict;
  9 +
  10 +my $mem_size = 0;
  11 +my $file_offset = 0;
  12 +
  13 +my $sections=" *[0-9]+ \.(?:bss|brk) +";
  14 +while (<>) {
  15 + if (/^$sections([0-9a-f]+) +(?:[0-9a-f]+ +){2}([0-9a-f]+)/) {
  16 + my $size = hex($1);
  17 + my $offset = hex($2);
  18 + $mem_size += $size;
  19 + if ($file_offset == 0) {
  20 + $file_offset = $offset;
  21 + } elsif ($file_offset != $offset) {
  22 + die ".bss and .brk lack common file offset\n";
  23 + }
  24 + }
  25 +}
  26 +
  27 +if ($file_offset == 0) {
  28 + die "Never found .bss or .brk file offset\n";
  29 +}
  30 +printf("%d\n", $mem_size + $file_offset);
... ... @@ -510,6 +510,9 @@
510 510 current->state = TASK_UNINTERRUPTIBLE;
511 511 schedule_timeout(HZ/10);
512 512 }
  513 +
  514 + cpu_die_common(cpu);
  515 +
513 516 xen_smp_intr_free(cpu);
514 517 xen_uninit_lock_cpu(cpu);
515 518 xen_teardown_timer(cpu);