aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYinghai Lu <yinghai@kernel.org>2009-11-10 21:27:23 -0500
committerIngo Molnar <mingo@elte.hu>2009-11-11 14:14:32 -0500
commit196cf0d67acad70ebb2572da489d5cc7066cdd05 (patch)
treeba475e8afc56aeb6392d146a7cb9bdae7ff65279
parent0420101c075530c65ba00b6fe7291b126fbfc5d2 (diff)
x86: Make sure wakeup trampoline code is below 1MB
Instead of using bootmem, try find_e820_area()/reserve_early(), and call acpi_reserve_memory() early, to allocate the wakeup trampoline code area below 1M. This is more reliable, and it also removes a dependency on bootmem. -v2: change function name to acpi_reserve_wakeup_memory(), as suggested by Rafael. Signed-off-by: Yinghai Lu <yinghai@kernel.org> Acked-by: H. Peter Anvin <hpa@zytor.com> Acked-by: Rafael J. Wysocki <rjw@sisk.pl> Cc: pm list <linux-pm@lists.linux-foundation.org> Cc: Len Brown <lenb@kernel.org> Cc: Linus Torvalds <torvalds@linux-foundation.org> LKML-Reference: <4AFA210B.3020207@kernel.org> Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r--arch/x86/include/asm/acpi.h2
-rw-r--r--arch/x86/kernel/acpi/sleep.c15
-rw-r--r--arch/x86/kernel/setup.c13
3 files changed, 17 insertions, 13 deletions
diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h
index e3d4a0daff57..60d2b2db0bc5 100644
--- a/arch/x86/include/asm/acpi.h
+++ b/arch/x86/include/asm/acpi.h
@@ -118,7 +118,7 @@ extern void acpi_restore_state_mem(void);
118extern unsigned long acpi_wakeup_address; 118extern unsigned long acpi_wakeup_address;
119 119
120/* early initialization routine */ 120/* early initialization routine */
121extern void acpi_reserve_bootmem(void); 121extern void acpi_reserve_wakeup_memory(void);
122 122
123/* 123/*
124 * Check if the CPU can handle C2 and deeper 124 * Check if the CPU can handle C2 and deeper
diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c
index ca93638ba430..4a411450dfa0 100644
--- a/arch/x86/kernel/acpi/sleep.c
+++ b/arch/x86/kernel/acpi/sleep.c
@@ -119,29 +119,32 @@ void acpi_restore_state_mem(void)
119 119
120 120
121/** 121/**
122 * acpi_reserve_bootmem - do _very_ early ACPI initialisation 122 * acpi_reserve_wakeup_memory - do _very_ early ACPI initialisation
123 * 123 *
124 * We allocate a page from the first 1MB of memory for the wakeup 124 * We allocate a page from the first 1MB of memory for the wakeup
125 * routine for when we come back from a sleep state. The 125 * routine for when we come back from a sleep state. The
126 * runtime allocator allows specification of <16MB pages, but not 126 * runtime allocator allows specification of <16MB pages, but not
127 * <1MB pages. 127 * <1MB pages.
128 */ 128 */
129void __init acpi_reserve_bootmem(void) 129void __init acpi_reserve_wakeup_memory(void)
130{ 130{
131 unsigned long mem;
132
131 if ((&wakeup_code_end - &wakeup_code_start) > WAKEUP_SIZE) { 133 if ((&wakeup_code_end - &wakeup_code_start) > WAKEUP_SIZE) {
132 printk(KERN_ERR 134 printk(KERN_ERR
133 "ACPI: Wakeup code way too big, S3 disabled.\n"); 135 "ACPI: Wakeup code way too big, S3 disabled.\n");
134 return; 136 return;
135 } 137 }
136 138
137 acpi_realmode = (unsigned long)alloc_bootmem_low(WAKEUP_SIZE); 139 mem = find_e820_area(0, 1<<20, WAKEUP_SIZE, PAGE_SIZE);
138 140
139 if (!acpi_realmode) { 141 if (mem == -1L) {
140 printk(KERN_ERR "ACPI: Cannot allocate lowmem, S3 disabled.\n"); 142 printk(KERN_ERR "ACPI: Cannot allocate lowmem, S3 disabled.\n");
141 return; 143 return;
142 } 144 }
143 145 acpi_realmode = (unsigned long) phys_to_virt(mem);
144 acpi_wakeup_address = virt_to_phys((void *)acpi_realmode); 146 acpi_wakeup_address = mem;
147 reserve_early(mem, mem + WAKEUP_SIZE, "ACPI WAKEUP");
145} 148}
146 149
147 150
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index f89141982702..0a6e94ab8339 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -897,6 +897,13 @@ void __init setup_arch(char **cmdline_p)
897 897
898 reserve_brk(); 898 reserve_brk();
899 899
900#ifdef CONFIG_ACPI_SLEEP
901 /*
902 * Reserve low memory region for sleep support.
903 * even before init_memory_mapping
904 */
905 acpi_reserve_wakeup_memory();
906#endif
900 init_gbpages(); 907 init_gbpages();
901 908
902 /* max_pfn_mapped is updated here */ 909 /* max_pfn_mapped is updated here */
@@ -948,12 +955,6 @@ void __init setup_arch(char **cmdline_p)
948 955
949 initmem_init(0, max_pfn, acpi, k8); 956 initmem_init(0, max_pfn, acpi, k8);
950 957
951#ifdef CONFIG_ACPI_SLEEP
952 /*
953 * Reserve low memory region for sleep support.
954 */
955 acpi_reserve_bootmem();
956#endif
957 /* 958 /*
958 * Find and reserve possible boot-time SMP configuration: 959 * Find and reserve possible boot-time SMP configuration:
959 */ 960 */