提交 be3fd3cc 编写于 作者: L Linus Torvalds

Merge branch 'x86-fixes-for-linus' of...

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
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/start_kernel.h> #include <linux/start_kernel.h>
#include <linux/mm.h>
#include <asm/setup.h> #include <asm/setup.h>
#include <asm/sections.h> #include <asm/sections.h>
...@@ -44,9 +45,10 @@ void __init i386_start_kernel(void) ...@@ -44,9 +45,10 @@ void __init i386_start_kernel(void)
#ifdef CONFIG_BLK_DEV_INITRD #ifdef CONFIG_BLK_DEV_INITRD
/* Reserve INITRD */ /* Reserve INITRD */
if (boot_params.hdr.type_of_loader && boot_params.hdr.ramdisk_image) { if (boot_params.hdr.type_of_loader && boot_params.hdr.ramdisk_image) {
/* Assume only end is not page aligned */
u64 ramdisk_image = boot_params.hdr.ramdisk_image; u64 ramdisk_image = boot_params.hdr.ramdisk_image;
u64 ramdisk_size = boot_params.hdr.ramdisk_size; u64 ramdisk_size = boot_params.hdr.ramdisk_size;
u64 ramdisk_end = ramdisk_image + ramdisk_size; u64 ramdisk_end = PAGE_ALIGN(ramdisk_image + ramdisk_size);
reserve_early(ramdisk_image, ramdisk_end, "RAMDISK"); reserve_early(ramdisk_image, ramdisk_end, "RAMDISK");
} }
#endif #endif
......
...@@ -103,9 +103,10 @@ void __init x86_64_start_reservations(char *real_mode_data) ...@@ -103,9 +103,10 @@ void __init x86_64_start_reservations(char *real_mode_data)
#ifdef CONFIG_BLK_DEV_INITRD #ifdef CONFIG_BLK_DEV_INITRD
/* Reserve INITRD */ /* Reserve INITRD */
if (boot_params.hdr.type_of_loader && boot_params.hdr.ramdisk_image) { if (boot_params.hdr.type_of_loader && boot_params.hdr.ramdisk_image) {
/* Assume only end is not page aligned */
unsigned long ramdisk_image = boot_params.hdr.ramdisk_image; unsigned long ramdisk_image = boot_params.hdr.ramdisk_image;
unsigned long ramdisk_size = boot_params.hdr.ramdisk_size; unsigned long ramdisk_size = boot_params.hdr.ramdisk_size;
unsigned long ramdisk_end = ramdisk_image + ramdisk_size; unsigned long ramdisk_end = PAGE_ALIGN(ramdisk_image + ramdisk_size);
reserve_early(ramdisk_image, ramdisk_end, "RAMDISK"); reserve_early(ramdisk_image, ramdisk_end, "RAMDISK");
} }
#endif #endif
......
...@@ -314,16 +314,17 @@ static void __init reserve_brk(void) ...@@ -314,16 +314,17 @@ static void __init reserve_brk(void)
#define MAX_MAP_CHUNK (NR_FIX_BTMAPS << PAGE_SHIFT) #define MAX_MAP_CHUNK (NR_FIX_BTMAPS << PAGE_SHIFT)
static void __init relocate_initrd(void) static void __init relocate_initrd(void)
{ {
/* Assume only end is not page aligned */
u64 ramdisk_image = boot_params.hdr.ramdisk_image; u64 ramdisk_image = boot_params.hdr.ramdisk_image;
u64 ramdisk_size = boot_params.hdr.ramdisk_size; u64 ramdisk_size = boot_params.hdr.ramdisk_size;
u64 area_size = PAGE_ALIGN(ramdisk_size);
u64 end_of_lowmem = max_low_pfn_mapped << PAGE_SHIFT; u64 end_of_lowmem = max_low_pfn_mapped << PAGE_SHIFT;
u64 ramdisk_here; u64 ramdisk_here;
unsigned long slop, clen, mapaddr; unsigned long slop, clen, mapaddr;
char *p, *q; char *p, *q;
/* We need to move the initrd down into lowmem */ /* We need to move the initrd down into lowmem */
ramdisk_here = find_e820_area(0, end_of_lowmem, ramdisk_size, ramdisk_here = find_e820_area(0, end_of_lowmem, area_size,
PAGE_SIZE); PAGE_SIZE);
if (ramdisk_here == -1ULL) if (ramdisk_here == -1ULL)
...@@ -332,7 +333,7 @@ static void __init relocate_initrd(void) ...@@ -332,7 +333,7 @@ static void __init relocate_initrd(void)
/* Note: this includes all the lowmem currently occupied by /* Note: this includes all the lowmem currently occupied by
the initrd, we rely on that fact to keep the data intact. */ the initrd, we rely on that fact to keep the data intact. */
reserve_early(ramdisk_here, ramdisk_here + ramdisk_size, reserve_early(ramdisk_here, ramdisk_here + area_size,
"NEW RAMDISK"); "NEW RAMDISK");
initrd_start = ramdisk_here + PAGE_OFFSET; initrd_start = ramdisk_here + PAGE_OFFSET;
initrd_end = initrd_start + ramdisk_size; initrd_end = initrd_start + ramdisk_size;
...@@ -376,9 +377,10 @@ static void __init relocate_initrd(void) ...@@ -376,9 +377,10 @@ static void __init relocate_initrd(void)
static void __init reserve_initrd(void) static void __init reserve_initrd(void)
{ {
/* Assume only end is not page aligned */
u64 ramdisk_image = boot_params.hdr.ramdisk_image; u64 ramdisk_image = boot_params.hdr.ramdisk_image;
u64 ramdisk_size = boot_params.hdr.ramdisk_size; u64 ramdisk_size = boot_params.hdr.ramdisk_size;
u64 ramdisk_end = ramdisk_image + ramdisk_size; u64 ramdisk_end = PAGE_ALIGN(ramdisk_image + ramdisk_size);
u64 end_of_lowmem = max_low_pfn_mapped << PAGE_SHIFT; u64 end_of_lowmem = max_low_pfn_mapped << PAGE_SHIFT;
if (!boot_params.hdr.type_of_loader || if (!boot_params.hdr.type_of_loader ||
......
...@@ -291,8 +291,8 @@ SECTIONS ...@@ -291,8 +291,8 @@ SECTIONS
.smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) { .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
__smp_locks = .; __smp_locks = .;
*(.smp_locks) *(.smp_locks)
__smp_locks_end = .;
. = ALIGN(PAGE_SIZE); . = ALIGN(PAGE_SIZE);
__smp_locks_end = .;
} }
#ifdef CONFIG_X86_64 #ifdef CONFIG_X86_64
......
...@@ -331,11 +331,23 @@ int devmem_is_allowed(unsigned long pagenr) ...@@ -331,11 +331,23 @@ int devmem_is_allowed(unsigned long pagenr)
void free_init_pages(char *what, unsigned long begin, unsigned long end) void free_init_pages(char *what, unsigned long begin, unsigned long end)
{ {
unsigned long addr = begin; unsigned long addr;
unsigned long begin_aligned, end_aligned;
if (addr >= end) /* Make sure boundaries are page aligned */
begin_aligned = PAGE_ALIGN(begin);
end_aligned = end & PAGE_MASK;
if (WARN_ON(begin_aligned != begin || end_aligned != end)) {
begin = begin_aligned;
end = end_aligned;
}
if (begin >= end)
return; return;
addr = begin;
/* /*
* If debugging page accesses then do not free this memory but * If debugging page accesses then do not free this memory but
* mark them not present - any buggy init-section access will * 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,7 +355,7 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end)
*/ */
#ifdef CONFIG_DEBUG_PAGEALLOC #ifdef CONFIG_DEBUG_PAGEALLOC
printk(KERN_INFO "debug: unmapping init memory %08lx..%08lx\n", printk(KERN_INFO "debug: unmapping init memory %08lx..%08lx\n",
begin, PAGE_ALIGN(end)); begin, end);
set_memory_np(begin, (end - begin) >> PAGE_SHIFT); set_memory_np(begin, (end - begin) >> PAGE_SHIFT);
#else #else
/* /*
...@@ -358,8 +370,7 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end) ...@@ -358,8 +370,7 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end)
for (; addr < end; addr += PAGE_SIZE) { for (; addr < end; addr += PAGE_SIZE) {
ClearPageReserved(virt_to_page(addr)); ClearPageReserved(virt_to_page(addr));
init_page_count(virt_to_page(addr)); init_page_count(virt_to_page(addr));
memset((void *)(addr & ~(PAGE_SIZE-1)), memset((void *)addr, POISON_FREE_INITMEM, PAGE_SIZE);
POISON_FREE_INITMEM, PAGE_SIZE);
free_page(addr); free_page(addr);
totalram_pages++; totalram_pages++;
} }
...@@ -376,6 +387,15 @@ void free_initmem(void) ...@@ -376,6 +387,15 @@ void free_initmem(void)
#ifdef CONFIG_BLK_DEV_INITRD #ifdef CONFIG_BLK_DEV_INITRD
void free_initrd_mem(unsigned long start, unsigned long end) void free_initrd_mem(unsigned long start, unsigned long end)
{ {
free_init_pages("initrd memory", start, end); /*
* end could be not aligned, and We can not align that,
* decompresser could be confused by aligned initrd_end
* We already reserve the end partial page before in
* - i386_start_kernel()
* - x86_64_start_kernel()
* - relocate_initrd()
* So here We can do PAGE_ALIGN() safely to get partial page to be freed
*/
free_init_pages("initrd memory", start, PAGE_ALIGN(end));
} }
#endif #endif
...@@ -333,6 +333,12 @@ void __init free_early_partial(u64 start, u64 end) ...@@ -333,6 +333,12 @@ void __init free_early_partial(u64 start, u64 end)
struct early_res *r; struct early_res *r;
int i; int i;
if (start == end)
return;
if (WARN_ONCE(start > end, " wrong range [%#llx, %#llx]\n", start, end))
return;
try_next: try_next:
i = find_overlapped_early(start, end); i = find_overlapped_early(start, end);
if (i >= max_early_res) if (i >= max_early_res)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册