History

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 ACPI: fix resume from suspend to RAM on uniprocessor x86-64 x86 ACPI: normalize segment descriptor register on resume

Linus Torvalds committed 18 years ago

Commit 537388b2 parents 20cbc97 a1716d55 files · +60 −6Browse files

Unified · Split

5 files
  1. arch/x86/kernel/acpi/realmode/wakeup.S +37 −1
  2. arch/x86/kernel/acpi/realmode/wakeup.h +5 −0
  3. arch/x86/kernel/acpi/sleep.c +15 −1
  4. arch/x86/kernel/head_64.S +1 −1
  5. drivers/acpi/sleep/main.c +2 −3
arch/x86/kernel/acpi/realmode/wakeup.S+37−1
@@ -5,6 +5,7 @@ · 4 unmodified lines
5#include <asm/msr-index.h>5#include <asm/msr-index.h>
6#include <asm/page.h>6#include <asm/page.h>
7#include <asm/pgtable.h>7#include <asm/pgtable.h>
8#include <asm/processor-flags.h>
8 9
9 .code1610 .code16
10 .section ".header", "a"11 .section ".header", "a"
@@ -24,6 +25,11 @@ pmode_gdt: .quad 0 · 13 unmodified lines
24realmode_flags: .long 025realmode_flags: .long 0
25real_magic: .long 026real_magic: .long 0
26trampoline_segment: .word 027trampoline_segment: .word 0
28_pad1: .byte 0
29wakeup_jmp: .byte 0xea /* ljmpw */
30wakeup_jmp_off: .word 3f
31wakeup_jmp_seg: .word 0
32wakeup_gdt: .quad 0, 0, 0
27signature: .long 0x51ee111133signature: .long 0x51ee1111
28 34
29 .text35 .text
@@ -34,11 +40,34 @@ _start: · 4 unmodified lines
34 cli40 cli
35 cld41 cld
36 42
43 /* Apparently some dimwit BIOS programmers don't know how to
44 program a PM to RM transition, and we might end up here with
45 junk in the data segment descriptor registers. The only way
46 to repair that is to go into PM and fix it ourselves... */
47 movw $16, %cx
48 lgdtl %cs:wakeup_gdt
49 movl %cr0, %eax
50 orb $X86_CR0_PE, %al
51 movl %eax, %cr0
52 jmp 1f
531: ljmpw $8, $2f
542:
55 movw %cx, %ds
56 movw %cx, %es
57 movw %cx, %ss
58 movw %cx, %fs
59 movw %cx, %gs
60
61 andb $~X86_CR0_PE, %al
62 movl %eax, %cr0
63 jmp wakeup_jmp
643:
37 /* Set up segments */65 /* Set up segments */
38 movw %cs, %ax66 movw %cs, %ax
39 movw %ax, %ds67 movw %ax, %ds
40 movw %ax, %es68 movw %ax, %es
41 movw %ax, %ss69 movw %ax, %ss
70 lidtl wakeup_idt
42 71
43 movl $wakeup_stack_end, %esp72 movl $wakeup_stack_end, %esp
44 73
@@ -98,7 +127,14 @@ bogus_real_magic: · 53 unmodified lines
98 jmp 1b127 jmp 1b
99 128
100 .data129 .data
101 .balign 4130 .balign 8
131
132 /* This is the standard real-mode IDT */
133wakeup_idt:
134 .word 0xffff /* limit */
135 .long 0 /* address */
136 .word 0
137
102 .globl HEAP, heap_end138 .globl HEAP, heap_end
103HEAP:139HEAP:
104 .long wakeup_heap140 .long wakeup_heap
arch/x86/kernel/acpi/realmode/wakeup.h+5−0
@@ -24,6 +24,11 @@ struct wakeup_header { · 23 unmodified lines
24 u32 realmode_flags;24 u32 realmode_flags;
25 u32 real_magic;25 u32 real_magic;
26 u16 trampoline_segment; /* segment with trampoline code, 64-bit only */26 u16 trampoline_segment; /* segment with trampoline code, 64-bit only */
27 u8 _pad1;
28 u8 wakeup_jmp;
29 u16 wakeup_jmp_off;
30 u16 wakeup_jmp_seg;
31 u64 wakeup_gdt[3];
27 u32 signature; /* To check we have correct structure */32 u32 signature; /* To check we have correct structure */
28} __attribute__((__packed__));33} __attribute__((__packed__));
29 34
arch/x86/kernel/acpi/sleep.c+15−1
@@ -50,6 +50,20 @@ int acpi_save_state_mem(void) · 49 unmodified lines
50 50
51 header->video_mode = saved_video_mode;51 header->video_mode = saved_video_mode;
52 52
53 header->wakeup_jmp_seg = acpi_wakeup_address >> 4;
54 /* GDT[0]: GDT self-pointer */
55 header->wakeup_gdt[0] =
56 (u64)(sizeof(header->wakeup_gdt) - 1) +
57 ((u64)(acpi_wakeup_address +
58 ((char *)&header->wakeup_gdt - (char *)acpi_realmode))
59 << 16);
60 /* GDT[1]: real-mode-like code segment */
61 header->wakeup_gdt[1] = (0x009bULL << 40) +
62 ((u64)acpi_wakeup_address << 16) + 0xffff;
63 /* GDT[2]: real-mode-like data segment */
64 header->wakeup_gdt[2] = (0x0093ULL << 40) +
65 ((u64)acpi_wakeup_address << 16) + 0xffff;
66
53#ifndef CONFIG_64BIT67#ifndef CONFIG_64BIT
54 store_gdt((struct desc_ptr *)&header->pmode_gdt);68 store_gdt((struct desc_ptr *)&header->pmode_gdt);
55 69
@@ -111,7 +125,7 @@ void __init acpi_reserve_bootmem(void) · 55 unmodified lines
111 return;125 return;
112 }126 }
113 127
114 acpi_wakeup_address = acpi_realmode;128 acpi_wakeup_address = virt_to_phys((void *)acpi_realmode);
115}129}
116 130
117 131
arch/x86/kernel/head_64.S+1−1
@@ -128,7 +128,7 @@ ident_complete: · 127 unmodified lines
128 /* Fixup phys_base */128 /* Fixup phys_base */
129 addq %rbp, phys_base(%rip)129 addq %rbp, phys_base(%rip)
130 130
131#ifdef CONFIG_SMP131#ifdef CONFIG_X86_TRAMPOLINE
132 addq %rbp, trampoline_level4_pgt + 0(%rip)132 addq %rbp, trampoline_level4_pgt + 0(%rip)
133 addq %rbp, trampoline_level4_pgt + (511*8)(%rip)133 addq %rbp, trampoline_level4_pgt + (511*8)(%rip)
134#endif134#endif
drivers/acpi/sleep/main.c+2−3
@@ -36,9 +36,8 @@ static int acpi_sleep_prepare(u32 acpi_state) · 35 unmodified lines
36 if (!acpi_wakeup_address) {36 if (!acpi_wakeup_address) {
37 return -EFAULT;37 return -EFAULT;
38 }38 }
39 acpi_set_firmware_waking_vector((acpi_physical_address)39 acpi_set_firmware_waking_vector(
40 virt_to_phys((void *)40 (acpi_physical_address)acpi_wakeup_address);
41 acpi_wakeup_address));
42 41
43 }42 }
44 ACPI_FLUSH_CPU_CACHE();43 ACPI_FLUSH_CPU_CACHE();