diff options
-rw-r--r-- | arch/x86_64/kernel/acpi/sleep.c | 24 | ||||
-rw-r--r-- | arch/x86_64/kernel/acpi/wakeup.S | 59 | ||||
-rw-r--r-- | arch/x86_64/kernel/head.S | 9 |
3 files changed, 41 insertions, 51 deletions
diff --git a/arch/x86_64/kernel/acpi/sleep.c b/arch/x86_64/kernel/acpi/sleep.c index e1548fbe95ae..195b7034a148 100644 --- a/arch/x86_64/kernel/acpi/sleep.c +++ b/arch/x86_64/kernel/acpi/sleep.c | |||
@@ -60,19 +60,6 @@ extern char wakeup_start, wakeup_end; | |||
60 | 60 | ||
61 | extern unsigned long acpi_copy_wakeup_routine(unsigned long); | 61 | extern unsigned long acpi_copy_wakeup_routine(unsigned long); |
62 | 62 | ||
63 | static pgd_t low_ptr; | ||
64 | |||
65 | static void init_low_mapping(void) | ||
66 | { | ||
67 | pgd_t *slot0 = pgd_offset(current->mm, 0UL); | ||
68 | low_ptr = *slot0; | ||
69 | /* FIXME: We're playing with the current task's page tables here, which | ||
70 | * is potentially dangerous on SMP systems. | ||
71 | */ | ||
72 | set_pgd(slot0, *pgd_offset(current->mm, PAGE_OFFSET)); | ||
73 | local_flush_tlb(); | ||
74 | } | ||
75 | |||
76 | /** | 63 | /** |
77 | * acpi_save_state_mem - save kernel state | 64 | * acpi_save_state_mem - save kernel state |
78 | * | 65 | * |
@@ -81,8 +68,6 @@ static void init_low_mapping(void) | |||
81 | */ | 68 | */ |
82 | int acpi_save_state_mem(void) | 69 | int acpi_save_state_mem(void) |
83 | { | 70 | { |
84 | init_low_mapping(); | ||
85 | |||
86 | memcpy((void *)acpi_wakeup_address, &wakeup_start, | 71 | memcpy((void *)acpi_wakeup_address, &wakeup_start, |
87 | &wakeup_end - &wakeup_start); | 72 | &wakeup_end - &wakeup_start); |
88 | acpi_copy_wakeup_routine(acpi_wakeup_address); | 73 | acpi_copy_wakeup_routine(acpi_wakeup_address); |
@@ -95,8 +80,6 @@ int acpi_save_state_mem(void) | |||
95 | */ | 80 | */ |
96 | void acpi_restore_state_mem(void) | 81 | void acpi_restore_state_mem(void) |
97 | { | 82 | { |
98 | set_pgd(pgd_offset(current->mm, 0UL), low_ptr); | ||
99 | local_flush_tlb(); | ||
100 | } | 83 | } |
101 | 84 | ||
102 | /** | 85 | /** |
@@ -109,10 +92,11 @@ void acpi_restore_state_mem(void) | |||
109 | */ | 92 | */ |
110 | void __init acpi_reserve_bootmem(void) | 93 | void __init acpi_reserve_bootmem(void) |
111 | { | 94 | { |
112 | acpi_wakeup_address = (unsigned long)alloc_bootmem_low(PAGE_SIZE); | 95 | acpi_wakeup_address = (unsigned long)alloc_bootmem_low(PAGE_SIZE*2); |
113 | if ((&wakeup_end - &wakeup_start) > PAGE_SIZE) | 96 | if ((&wakeup_end - &wakeup_start) > (PAGE_SIZE*2)) |
114 | printk(KERN_CRIT | 97 | printk(KERN_CRIT |
115 | "ACPI: Wakeup code way too big, will crash on attempt to suspend\n"); | 98 | "ACPI: Wakeup code way too big, will crash on attempt" |
99 | " to suspend\n"); | ||
116 | } | 100 | } |
117 | 101 | ||
118 | static int __init acpi_sleep_setup(char *str) | 102 | static int __init acpi_sleep_setup(char *str) |
diff --git a/arch/x86_64/kernel/acpi/wakeup.S b/arch/x86_64/kernel/acpi/wakeup.S index bd4c6f1a6f32..766cfbcac1db 100644 --- a/arch/x86_64/kernel/acpi/wakeup.S +++ b/arch/x86_64/kernel/acpi/wakeup.S | |||
@@ -1,6 +1,7 @@ | |||
1 | .text | 1 | .text |
2 | #include <linux/linkage.h> | 2 | #include <linux/linkage.h> |
3 | #include <asm/segment.h> | 3 | #include <asm/segment.h> |
4 | #include <asm/pgtable.h> | ||
4 | #include <asm/page.h> | 5 | #include <asm/page.h> |
5 | #include <asm/msr.h> | 6 | #include <asm/msr.h> |
6 | 7 | ||
@@ -62,12 +63,15 @@ wakeup_code: | |||
62 | 63 | ||
63 | movb $0xa2, %al ; outb %al, $0x80 | 64 | movb $0xa2, %al ; outb %al, $0x80 |
64 | 65 | ||
65 | lidt %ds:idt_48a - wakeup_code | 66 | mov %ds, %ax # Find 32bit wakeup_code addr |
66 | xorl %eax, %eax | 67 | movzx %ax, %esi # (Convert %ds:gdt to a liner ptr) |
67 | movw %ds, %ax # (Convert %ds:gdt to a linear ptr) | 68 | shll $4, %esi |
68 | shll $4, %eax | 69 | # Fix up the vectors |
69 | addl $(gdta - wakeup_code), %eax | 70 | addl %esi, wakeup_32_vector - wakeup_code |
70 | movl %eax, gdt_48a +2 - wakeup_code | 71 | addl %esi, wakeup_long64_vector - wakeup_code |
72 | addl %esi, gdt_48a + 2 - wakeup_code # Fixup the gdt pointer | ||
73 | |||
74 | lidtl %ds:idt_48a - wakeup_code | ||
71 | lgdtl %ds:gdt_48a - wakeup_code # load gdt with whatever is | 75 | lgdtl %ds:gdt_48a - wakeup_code # load gdt with whatever is |
72 | # appropriate | 76 | # appropriate |
73 | 77 | ||
@@ -80,7 +84,7 @@ wakeup_code: | |||
80 | 84 | ||
81 | .balign 4 | 85 | .balign 4 |
82 | wakeup_32_vector: | 86 | wakeup_32_vector: |
83 | .long wakeup_32 - __START_KERNEL_map | 87 | .long wakeup_32 - wakeup_code |
84 | .word __KERNEL32_CS, 0 | 88 | .word __KERNEL32_CS, 0 |
85 | 89 | ||
86 | .code32 | 90 | .code32 |
@@ -103,10 +107,6 @@ wakeup_32: | |||
103 | movl $__KERNEL_DS, %eax | 107 | movl $__KERNEL_DS, %eax |
104 | movl %eax, %ds | 108 | movl %eax, %ds |
105 | 109 | ||
106 | movl saved_magic - __START_KERNEL_map, %eax | ||
107 | cmpl $0x9abcdef0, %eax | ||
108 | jne bogus_32_magic | ||
109 | |||
110 | movw $0x0e00 + 'i', %ds:(0xb8012) | 110 | movw $0x0e00 + 'i', %ds:(0xb8012) |
111 | movb $0xa8, %al ; outb %al, $0x80; | 111 | movb $0xa8, %al ; outb %al, $0x80; |
112 | 112 | ||
@@ -120,7 +120,7 @@ wakeup_32: | |||
120 | movl %eax, %cr4 | 120 | movl %eax, %cr4 |
121 | 121 | ||
122 | /* Setup early boot stage 4 level pagetables */ | 122 | /* Setup early boot stage 4 level pagetables */ |
123 | movl $(wakeup_level4_pgt - __START_KERNEL_map), %eax | 123 | leal (wakeup_level4_pgt - wakeup_code)(%esi), %eax |
124 | movl %eax, %cr3 | 124 | movl %eax, %cr3 |
125 | 125 | ||
126 | /* Enable Long Mode */ | 126 | /* Enable Long Mode */ |
@@ -159,11 +159,11 @@ wakeup_32: | |||
159 | */ | 159 | */ |
160 | 160 | ||
161 | /* Finally jump in 64bit mode */ | 161 | /* Finally jump in 64bit mode */ |
162 | ljmp *(wakeup_long64_vector - __START_KERNEL_map) | 162 | ljmp *(wakeup_long64_vector - wakeup_code)(%esi) |
163 | 163 | ||
164 | .balign 4 | 164 | .balign 4 |
165 | wakeup_long64_vector: | 165 | wakeup_long64_vector: |
166 | .long wakeup_long64 - __START_KERNEL_map | 166 | .long wakeup_long64 - wakeup_code |
167 | .word __KERNEL_CS, 0 | 167 | .word __KERNEL_CS, 0 |
168 | 168 | ||
169 | .code64 | 169 | .code64 |
@@ -178,11 +178,16 @@ wakeup_long64: | |||
178 | * addresses where we're currently running on. We have to do that here | 178 | * addresses where we're currently running on. We have to do that here |
179 | * because in 32bit we couldn't load a 64bit linear address. | 179 | * because in 32bit we couldn't load a 64bit linear address. |
180 | */ | 180 | */ |
181 | lgdt cpu_gdt_descr - __START_KERNEL_map | 181 | lgdt cpu_gdt_descr |
182 | 182 | ||
183 | movw $0x0e00 + 'n', %ds:(0xb8014) | 183 | movw $0x0e00 + 'n', %ds:(0xb8014) |
184 | movb $0xa9, %al ; outb %al, $0x80 | 184 | movb $0xa9, %al ; outb %al, $0x80 |
185 | 185 | ||
186 | movq saved_magic, %rax | ||
187 | movq $0x123456789abcdef0, %rdx | ||
188 | cmpq %rdx, %rax | ||
189 | jne bogus_64_magic | ||
190 | |||
186 | movw $0x0e00 + 'u', %ds:(0xb8016) | 191 | movw $0x0e00 + 'u', %ds:(0xb8016) |
187 | 192 | ||
188 | nop | 193 | nop |
@@ -223,20 +228,21 @@ idt_48a: | |||
223 | gdt_48a: | 228 | gdt_48a: |
224 | .word 0x800 # gdt limit=2048, | 229 | .word 0x800 # gdt limit=2048, |
225 | # 256 GDT entries | 230 | # 256 GDT entries |
226 | .word 0, 0 # gdt base (filled in later) | 231 | .long gdta - wakeup_code # gdt base (relocated in later) |
227 | |||
228 | 232 | ||
229 | real_magic: .quad 0 | 233 | real_magic: .quad 0 |
230 | video_mode: .quad 0 | 234 | video_mode: .quad 0 |
231 | video_flags: .quad 0 | 235 | video_flags: .quad 0 |
232 | 236 | ||
237 | .code16 | ||
233 | bogus_real_magic: | 238 | bogus_real_magic: |
234 | movb $0xba,%al ; outb %al,$0x80 | 239 | movb $0xba,%al ; outb %al,$0x80 |
235 | jmp bogus_real_magic | 240 | jmp bogus_real_magic |
236 | 241 | ||
237 | bogus_32_magic: | 242 | .code64 |
243 | bogus_64_magic: | ||
238 | movb $0xb3,%al ; outb %al,$0x80 | 244 | movb $0xb3,%al ; outb %al,$0x80 |
239 | jmp bogus_32_magic | 245 | jmp bogus_64_magic |
240 | 246 | ||
241 | bogus_cpu: | 247 | bogus_cpu: |
242 | movb $0xbc,%al ; outb %al,$0x80 | 248 | movb $0xbc,%al ; outb %al,$0x80 |
@@ -263,6 +269,7 @@ bogus_cpu: | |||
263 | #define VIDEO_FIRST_V7 0x0900 | 269 | #define VIDEO_FIRST_V7 0x0900 |
264 | 270 | ||
265 | # Setting of user mode (AX=mode ID) => CF=success | 271 | # Setting of user mode (AX=mode ID) => CF=success |
272 | .code16 | ||
266 | mode_seta: | 273 | mode_seta: |
267 | movw %ax, %bx | 274 | movw %ax, %bx |
268 | #if 0 | 275 | #if 0 |
@@ -313,6 +320,13 @@ wakeup_stack_begin: # Stack grows down | |||
313 | .org 0xff0 | 320 | .org 0xff0 |
314 | wakeup_stack: # Just below end of page | 321 | wakeup_stack: # Just below end of page |
315 | 322 | ||
323 | .org 0x1000 | ||
324 | ENTRY(wakeup_level4_pgt) | ||
325 | .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE | ||
326 | .fill 510,8,0 | ||
327 | /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */ | ||
328 | .quad level3_kernel_pgt - __START_KERNEL_map + _KERNPG_TABLE | ||
329 | |||
316 | ENTRY(wakeup_end) | 330 | ENTRY(wakeup_end) |
317 | 331 | ||
318 | ## | 332 | ## |
@@ -338,9 +352,10 @@ ENTRY(acpi_copy_wakeup_routine) | |||
338 | movq $0x123456789abcdef0, %rdx | 352 | movq $0x123456789abcdef0, %rdx |
339 | movq %rdx, saved_magic | 353 | movq %rdx, saved_magic |
340 | 354 | ||
341 | movl saved_magic - __START_KERNEL_map, %eax | 355 | movq saved_magic, %rax |
342 | cmpl $0x9abcdef0, %eax | 356 | movq $0x123456789abcdef0, %rdx |
343 | jne bogus_32_magic | 357 | cmpq %rdx, %rax |
358 | jne bogus_64_magic | ||
344 | 359 | ||
345 | # restore the regs we used | 360 | # restore the regs we used |
346 | popq %rdx | 361 | popq %rdx |
diff --git a/arch/x86_64/kernel/head.S b/arch/x86_64/kernel/head.S index 562d62fbd69f..926aa2197aaa 100644 --- a/arch/x86_64/kernel/head.S +++ b/arch/x86_64/kernel/head.S | |||
@@ -308,15 +308,6 @@ NEXT_PAGE(level2_kernel_pgt) | |||
308 | 308 | ||
309 | .data | 309 | .data |
310 | 310 | ||
311 | #ifdef CONFIG_ACPI_SLEEP | ||
312 | .align PAGE_SIZE | ||
313 | ENTRY(wakeup_level4_pgt) | ||
314 | .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE | ||
315 | .fill 510,8,0 | ||
316 | /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */ | ||
317 | .quad level3_kernel_pgt - __START_KERNEL_map + _KERNPG_TABLE | ||
318 | #endif | ||
319 | |||
320 | #ifndef CONFIG_HOTPLUG_CPU | 311 | #ifndef CONFIG_HOTPLUG_CPU |
321 | __INITDATA | 312 | __INITDATA |
322 | #endif | 313 | #endif |