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

* 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
x86: Do not free zero sized per cpu areas
x86: Make sure free_init_pages() frees pages on page boundary
x86: Make smp_locks end with page alignment

+44 -13
+3 -1
arch/x86/kernel/head32.c
··· 7 7 8 8 #include <linux/init.h> 9 9 #include <linux/start_kernel.h> 10 + #include <linux/mm.h> 10 11 11 12 #include <asm/setup.h> 12 13 #include <asm/sections.h> ··· 45 44 #ifdef CONFIG_BLK_DEV_INITRD 46 45 /* Reserve INITRD */ 47 46 if (boot_params.hdr.type_of_loader && boot_params.hdr.ramdisk_image) { 47 + /* Assume only end is not page aligned */ 48 48 u64 ramdisk_image = boot_params.hdr.ramdisk_image; 49 49 u64 ramdisk_size = boot_params.hdr.ramdisk_size; 50 - u64 ramdisk_end = ramdisk_image + ramdisk_size; 50 + u64 ramdisk_end = PAGE_ALIGN(ramdisk_image + ramdisk_size); 51 51 reserve_early(ramdisk_image, ramdisk_end, "RAMDISK"); 52 52 } 53 53 #endif
+2 -1
arch/x86/kernel/head64.c
··· 103 103 #ifdef CONFIG_BLK_DEV_INITRD 104 104 /* Reserve INITRD */ 105 105 if (boot_params.hdr.type_of_loader && boot_params.hdr.ramdisk_image) { 106 + /* Assume only end is not page aligned */ 106 107 unsigned long ramdisk_image = boot_params.hdr.ramdisk_image; 107 108 unsigned long ramdisk_size = boot_params.hdr.ramdisk_size; 108 - unsigned long ramdisk_end = ramdisk_image + ramdisk_size; 109 + unsigned long ramdisk_end = PAGE_ALIGN(ramdisk_image + ramdisk_size); 109 110 reserve_early(ramdisk_image, ramdisk_end, "RAMDISK"); 110 111 } 111 112 #endif
+6 -4
arch/x86/kernel/setup.c
··· 314 314 #define MAX_MAP_CHUNK (NR_FIX_BTMAPS << PAGE_SHIFT) 315 315 static void __init relocate_initrd(void) 316 316 { 317 - 317 + /* Assume only end is not page aligned */ 318 318 u64 ramdisk_image = boot_params.hdr.ramdisk_image; 319 319 u64 ramdisk_size = boot_params.hdr.ramdisk_size; 320 + u64 area_size = PAGE_ALIGN(ramdisk_size); 320 321 u64 end_of_lowmem = max_low_pfn_mapped << PAGE_SHIFT; 321 322 u64 ramdisk_here; 322 323 unsigned long slop, clen, mapaddr; 323 324 char *p, *q; 324 325 325 326 /* We need to move the initrd down into lowmem */ 326 - ramdisk_here = find_e820_area(0, end_of_lowmem, ramdisk_size, 327 + ramdisk_here = find_e820_area(0, end_of_lowmem, area_size, 327 328 PAGE_SIZE); 328 329 329 330 if (ramdisk_here == -1ULL) ··· 333 332 334 333 /* Note: this includes all the lowmem currently occupied by 335 334 the initrd, we rely on that fact to keep the data intact. */ 336 - reserve_early(ramdisk_here, ramdisk_here + ramdisk_size, 335 + reserve_early(ramdisk_here, ramdisk_here + area_size, 337 336 "NEW RAMDISK"); 338 337 initrd_start = ramdisk_here + PAGE_OFFSET; 339 338 initrd_end = initrd_start + ramdisk_size; ··· 377 376 378 377 static void __init reserve_initrd(void) 379 378 { 379 + /* Assume only end is not page aligned */ 380 380 u64 ramdisk_image = boot_params.hdr.ramdisk_image; 381 381 u64 ramdisk_size = boot_params.hdr.ramdisk_size; 382 - u64 ramdisk_end = ramdisk_image + ramdisk_size; 382 + u64 ramdisk_end = PAGE_ALIGN(ramdisk_image + ramdisk_size); 383 383 u64 end_of_lowmem = max_low_pfn_mapped << PAGE_SHIFT; 384 384 385 385 if (!boot_params.hdr.type_of_loader ||
+1 -1
arch/x86/kernel/vmlinux.lds.S
··· 291 291 .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) { 292 292 __smp_locks = .; 293 293 *(.smp_locks) 294 - __smp_locks_end = .; 295 294 . = ALIGN(PAGE_SIZE); 295 + __smp_locks_end = .; 296 296 } 297 297 298 298 #ifdef CONFIG_X86_64
+26 -6
arch/x86/mm/init.c
··· 331 331 332 332 void free_init_pages(char *what, unsigned long begin, unsigned long end) 333 333 { 334 - unsigned long addr = begin; 334 + unsigned long addr; 335 + unsigned long begin_aligned, end_aligned; 335 336 336 - if (addr >= end) 337 + /* Make sure boundaries are page aligned */ 338 + begin_aligned = PAGE_ALIGN(begin); 339 + end_aligned = end & PAGE_MASK; 340 + 341 + if (WARN_ON(begin_aligned != begin || end_aligned != end)) { 342 + begin = begin_aligned; 343 + end = end_aligned; 344 + } 345 + 346 + if (begin >= end) 337 347 return; 348 + 349 + addr = begin; 338 350 339 351 /* 340 352 * If debugging page accesses then do not free this memory but ··· 355 343 */ 356 344 #ifdef CONFIG_DEBUG_PAGEALLOC 357 345 printk(KERN_INFO "debug: unmapping init memory %08lx..%08lx\n", 358 - begin, PAGE_ALIGN(end)); 346 + begin, end); 359 347 set_memory_np(begin, (end - begin) >> PAGE_SHIFT); 360 348 #else 361 349 /* ··· 370 358 for (; addr < end; addr += PAGE_SIZE) { 371 359 ClearPageReserved(virt_to_page(addr)); 372 360 init_page_count(virt_to_page(addr)); 373 - memset((void *)(addr & ~(PAGE_SIZE-1)), 374 - POISON_FREE_INITMEM, PAGE_SIZE); 361 + memset((void *)addr, POISON_FREE_INITMEM, PAGE_SIZE); 375 362 free_page(addr); 376 363 totalram_pages++; 377 364 } ··· 387 376 #ifdef CONFIG_BLK_DEV_INITRD 388 377 void free_initrd_mem(unsigned long start, unsigned long end) 389 378 { 390 - free_init_pages("initrd memory", start, end); 379 + /* 380 + * end could be not aligned, and We can not align that, 381 + * decompresser could be confused by aligned initrd_end 382 + * We already reserve the end partial page before in 383 + * - i386_start_kernel() 384 + * - x86_64_start_kernel() 385 + * - relocate_initrd() 386 + * So here We can do PAGE_ALIGN() safely to get partial page to be freed 387 + */ 388 + free_init_pages("initrd memory", start, PAGE_ALIGN(end)); 391 389 } 392 390 #endif
+6
kernel/early_res.c
··· 333 333 struct early_res *r; 334 334 int i; 335 335 336 + if (start == end) 337 + return; 338 + 339 + if (WARN_ONCE(start > end, " wrong range [%#llx, %#llx]\n", start, end)) 340 + return; 341 + 336 342 try_next: 337 343 i = find_overlapped_early(start, end); 338 344 if (i >= max_early_res)