diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-03-30 10:22:38 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-03-30 10:22:38 -0400 |
| commit | be3fd3cc7c2142c46d5dcfec05e6031990d1f2ca (patch) | |
| tree | 606074b5c60ef823ad86174e408904c563eab38d | |
| parent | 9623e5a23724d09283c238960946ec6f65733afe (diff) | |
| parent | eed63519e3e74d515d2007ecd895338d0ba2a85c (diff) | |
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
| -rw-r--r-- | arch/x86/kernel/head32.c | 4 | ||||
| -rw-r--r-- | arch/x86/kernel/head64.c | 3 | ||||
| -rw-r--r-- | arch/x86/kernel/setup.c | 10 | ||||
| -rw-r--r-- | arch/x86/kernel/vmlinux.lds.S | 2 | ||||
| -rw-r--r-- | arch/x86/mm/init.c | 32 | ||||
| -rw-r--r-- | kernel/early_res.c | 6 |
6 files changed, 44 insertions, 13 deletions
diff --git a/arch/x86/kernel/head32.c b/arch/x86/kernel/head32.c index adedeef1dedc..b2e246037392 100644 --- a/arch/x86/kernel/head32.c +++ b/arch/x86/kernel/head32.c | |||
| @@ -7,6 +7,7 @@ | |||
| 7 | 7 | ||
| 8 | #include <linux/init.h> | 8 | #include <linux/init.h> |
| 9 | #include <linux/start_kernel.h> | 9 | #include <linux/start_kernel.h> |
| 10 | #include <linux/mm.h> | ||
| 10 | 11 | ||
| 11 | #include <asm/setup.h> | 12 | #include <asm/setup.h> |
| 12 | #include <asm/sections.h> | 13 | #include <asm/sections.h> |
| @@ -44,9 +45,10 @@ void __init i386_start_kernel(void) | |||
| 44 | #ifdef CONFIG_BLK_DEV_INITRD | 45 | #ifdef CONFIG_BLK_DEV_INITRD |
| 45 | /* Reserve INITRD */ | 46 | /* Reserve INITRD */ |
| 46 | if (boot_params.hdr.type_of_loader && boot_params.hdr.ramdisk_image) { | 47 | if (boot_params.hdr.type_of_loader && boot_params.hdr.ramdisk_image) { |
| 48 | /* Assume only end is not page aligned */ | ||
| 47 | u64 ramdisk_image = boot_params.hdr.ramdisk_image; | 49 | u64 ramdisk_image = boot_params.hdr.ramdisk_image; |
| 48 | u64 ramdisk_size = boot_params.hdr.ramdisk_size; | 50 | u64 ramdisk_size = boot_params.hdr.ramdisk_size; |
| 49 | u64 ramdisk_end = ramdisk_image + ramdisk_size; | 51 | u64 ramdisk_end = PAGE_ALIGN(ramdisk_image + ramdisk_size); |
| 50 | reserve_early(ramdisk_image, ramdisk_end, "RAMDISK"); | 52 | reserve_early(ramdisk_image, ramdisk_end, "RAMDISK"); |
| 51 | } | 53 | } |
| 52 | #endif | 54 | #endif |
diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c index b5a9896ca1e7..7147143fd614 100644 --- a/arch/x86/kernel/head64.c +++ b/arch/x86/kernel/head64.c | |||
| @@ -103,9 +103,10 @@ void __init x86_64_start_reservations(char *real_mode_data) | |||
| 103 | #ifdef CONFIG_BLK_DEV_INITRD | 103 | #ifdef CONFIG_BLK_DEV_INITRD |
| 104 | /* Reserve INITRD */ | 104 | /* Reserve INITRD */ |
| 105 | if (boot_params.hdr.type_of_loader && boot_params.hdr.ramdisk_image) { | 105 | if (boot_params.hdr.type_of_loader && boot_params.hdr.ramdisk_image) { |
| 106 | /* Assume only end is not page aligned */ | ||
| 106 | unsigned long ramdisk_image = boot_params.hdr.ramdisk_image; | 107 | unsigned long ramdisk_image = boot_params.hdr.ramdisk_image; |
| 107 | unsigned long ramdisk_size = boot_params.hdr.ramdisk_size; | 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 | reserve_early(ramdisk_image, ramdisk_end, "RAMDISK"); | 110 | reserve_early(ramdisk_image, ramdisk_end, "RAMDISK"); |
| 110 | } | 111 | } |
| 111 | #endif | 112 | #endif |
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 5d7ba1a449bd..d76e18570c60 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c | |||
| @@ -314,16 +314,17 @@ static void __init reserve_brk(void) | |||
| 314 | #define MAX_MAP_CHUNK (NR_FIX_BTMAPS << PAGE_SHIFT) | 314 | #define MAX_MAP_CHUNK (NR_FIX_BTMAPS << PAGE_SHIFT) |
| 315 | static void __init relocate_initrd(void) | 315 | static void __init relocate_initrd(void) |
| 316 | { | 316 | { |
| 317 | 317 | /* Assume only end is not page aligned */ | |
| 318 | u64 ramdisk_image = boot_params.hdr.ramdisk_image; | 318 | u64 ramdisk_image = boot_params.hdr.ramdisk_image; |
| 319 | u64 ramdisk_size = boot_params.hdr.ramdisk_size; | 319 | u64 ramdisk_size = boot_params.hdr.ramdisk_size; |
| 320 | u64 area_size = PAGE_ALIGN(ramdisk_size); | ||
| 320 | u64 end_of_lowmem = max_low_pfn_mapped << PAGE_SHIFT; | 321 | u64 end_of_lowmem = max_low_pfn_mapped << PAGE_SHIFT; |
| 321 | u64 ramdisk_here; | 322 | u64 ramdisk_here; |
| 322 | unsigned long slop, clen, mapaddr; | 323 | unsigned long slop, clen, mapaddr; |
| 323 | char *p, *q; | 324 | char *p, *q; |
| 324 | 325 | ||
| 325 | /* We need to move the initrd down into lowmem */ | 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 | PAGE_SIZE); | 328 | PAGE_SIZE); |
| 328 | 329 | ||
| 329 | if (ramdisk_here == -1ULL) | 330 | if (ramdisk_here == -1ULL) |
| @@ -332,7 +333,7 @@ static void __init relocate_initrd(void) | |||
| 332 | 333 | ||
| 333 | /* Note: this includes all the lowmem currently occupied by | 334 | /* Note: this includes all the lowmem currently occupied by |
| 334 | the initrd, we rely on that fact to keep the data intact. */ | 335 | the initrd, we rely on that fact to keep the data intact. */ |
| 335 | reserve_early(ramdisk_here, ramdisk_here + ramdisk_size, | 336 | reserve_early(ramdisk_here, ramdisk_here + area_size, |
| 336 | "NEW RAMDISK"); | 337 | "NEW RAMDISK"); |
| 337 | initrd_start = ramdisk_here + PAGE_OFFSET; | 338 | initrd_start = ramdisk_here + PAGE_OFFSET; |
| 338 | initrd_end = initrd_start + ramdisk_size; | 339 | initrd_end = initrd_start + ramdisk_size; |
| @@ -376,9 +377,10 @@ static void __init relocate_initrd(void) | |||
| 376 | 377 | ||
| 377 | static void __init reserve_initrd(void) | 378 | static void __init reserve_initrd(void) |
| 378 | { | 379 | { |
| 380 | /* Assume only end is not page aligned */ | ||
| 379 | u64 ramdisk_image = boot_params.hdr.ramdisk_image; | 381 | u64 ramdisk_image = boot_params.hdr.ramdisk_image; |
| 380 | u64 ramdisk_size = boot_params.hdr.ramdisk_size; | 382 | u64 ramdisk_size = boot_params.hdr.ramdisk_size; |
| 381 | u64 ramdisk_end = ramdisk_image + ramdisk_size; | 383 | u64 ramdisk_end = PAGE_ALIGN(ramdisk_image + ramdisk_size); |
| 382 | u64 end_of_lowmem = max_low_pfn_mapped << PAGE_SHIFT; | 384 | u64 end_of_lowmem = max_low_pfn_mapped << PAGE_SHIFT; |
| 383 | 385 | ||
| 384 | if (!boot_params.hdr.type_of_loader || | 386 | if (!boot_params.hdr.type_of_loader || |
diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S index 44879df55696..2cc249718c46 100644 --- a/arch/x86/kernel/vmlinux.lds.S +++ b/arch/x86/kernel/vmlinux.lds.S | |||
| @@ -291,8 +291,8 @@ SECTIONS | |||
| 291 | .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) { | 291 | .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) { |
| 292 | __smp_locks = .; | 292 | __smp_locks = .; |
| 293 | *(.smp_locks) | 293 | *(.smp_locks) |
| 294 | __smp_locks_end = .; | ||
| 295 | . = ALIGN(PAGE_SIZE); | 294 | . = ALIGN(PAGE_SIZE); |
| 295 | __smp_locks_end = .; | ||
| 296 | } | 296 | } |
| 297 | 297 | ||
| 298 | #ifdef CONFIG_X86_64 | 298 | #ifdef CONFIG_X86_64 |
diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c index e71c5cbc8f35..452ee5b8f309 100644 --- a/arch/x86/mm/init.c +++ b/arch/x86/mm/init.c | |||
| @@ -331,11 +331,23 @@ int devmem_is_allowed(unsigned long pagenr) | |||
| 331 | 331 | ||
| 332 | void free_init_pages(char *what, unsigned long begin, unsigned long end) | 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 | return; | 347 | return; |
| 338 | 348 | ||
| 349 | addr = begin; | ||
| 350 | |||
| 339 | /* | 351 | /* |
| 340 | * If debugging page accesses then do not free this memory but | 352 | * If debugging page accesses then do not free this memory but |
| 341 | * mark them not present - any buggy init-section access will | 353 | * mark them not present - any buggy init-section access will |
| @@ -343,7 +355,7 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end) | |||
| 343 | */ | 355 | */ |
| 344 | #ifdef CONFIG_DEBUG_PAGEALLOC | 356 | #ifdef CONFIG_DEBUG_PAGEALLOC |
| 345 | printk(KERN_INFO "debug: unmapping init memory %08lx..%08lx\n", | 357 | printk(KERN_INFO "debug: unmapping init memory %08lx..%08lx\n", |
| 346 | begin, PAGE_ALIGN(end)); | 358 | begin, end); |
| 347 | set_memory_np(begin, (end - begin) >> PAGE_SHIFT); | 359 | set_memory_np(begin, (end - begin) >> PAGE_SHIFT); |
| 348 | #else | 360 | #else |
| 349 | /* | 361 | /* |
| @@ -358,8 +370,7 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end) | |||
| 358 | for (; addr < end; addr += PAGE_SIZE) { | 370 | for (; addr < end; addr += PAGE_SIZE) { |
| 359 | ClearPageReserved(virt_to_page(addr)); | 371 | ClearPageReserved(virt_to_page(addr)); |
| 360 | init_page_count(virt_to_page(addr)); | 372 | init_page_count(virt_to_page(addr)); |
| 361 | memset((void *)(addr & ~(PAGE_SIZE-1)), | 373 | memset((void *)addr, POISON_FREE_INITMEM, PAGE_SIZE); |
| 362 | POISON_FREE_INITMEM, PAGE_SIZE); | ||
| 363 | free_page(addr); | 374 | free_page(addr); |
| 364 | totalram_pages++; | 375 | totalram_pages++; |
| 365 | } | 376 | } |
| @@ -376,6 +387,15 @@ void free_initmem(void) | |||
| 376 | #ifdef CONFIG_BLK_DEV_INITRD | 387 | #ifdef CONFIG_BLK_DEV_INITRD |
| 377 | void free_initrd_mem(unsigned long start, unsigned long end) | 388 | void free_initrd_mem(unsigned long start, unsigned long end) |
| 378 | { | 389 | { |
| 379 | free_init_pages("initrd memory", start, end); | 390 | /* |
| 391 | * end could be not aligned, and We can not align that, | ||
| 392 | * decompresser could be confused by aligned initrd_end | ||
| 393 | * We already reserve the end partial page before in | ||
| 394 | * - i386_start_kernel() | ||
| 395 | * - x86_64_start_kernel() | ||
| 396 | * - relocate_initrd() | ||
| 397 | * So here We can do PAGE_ALIGN() safely to get partial page to be freed | ||
| 398 | */ | ||
| 399 | free_init_pages("initrd memory", start, PAGE_ALIGN(end)); | ||
| 380 | } | 400 | } |
| 381 | #endif | 401 | #endif |
diff --git a/kernel/early_res.c b/kernel/early_res.c index 3cb2c661bb78..31aa9332ef3f 100644 --- a/kernel/early_res.c +++ b/kernel/early_res.c | |||
| @@ -333,6 +333,12 @@ void __init free_early_partial(u64 start, u64 end) | |||
| 333 | struct early_res *r; | 333 | struct early_res *r; |
| 334 | int i; | 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 | try_next: | 342 | try_next: |
| 337 | i = find_overlapped_early(start, end); | 343 | i = find_overlapped_early(start, end); |
| 338 | if (i >= max_early_res) | 344 | if (i >= max_early_res) |
