diff options
-rw-r--r-- | arch/x86/include/asm/realmode.h | 5 | ||||
-rw-r--r-- | arch/x86/kernel/acpi/sleep.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/realmode.c | 57 | ||||
-rw-r--r-- | arch/x86/kernel/reboot.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/smpboot.c | 4 | ||||
-rw-r--r-- | arch/x86/kernel/tboot.c | 2 | ||||
-rw-r--r-- | arch/x86/realmode/rm/header.S | 1 | ||||
-rw-r--r-- | arch/x86/realmode/rm/realmode.lds.S | 1 | ||||
-rw-r--r-- | arch/x86/realmode/rmpiggy.S | 2 | ||||
-rw-r--r-- | drivers/acpi/sleep.c | 2 |
10 files changed, 35 insertions, 43 deletions
diff --git a/arch/x86/include/asm/realmode.h b/arch/x86/include/asm/realmode.h index 1bfc74d213a4..d3ae49f4c3ef 100644 --- a/arch/x86/include/asm/realmode.h +++ b/arch/x86/include/asm/realmode.h | |||
@@ -8,7 +8,6 @@ | |||
8 | struct real_mode_header { | 8 | struct real_mode_header { |
9 | u32 text_start; | 9 | u32 text_start; |
10 | u32 ro_end; | 10 | u32 ro_end; |
11 | u32 end; | ||
12 | /* reboot */ | 11 | /* reboot */ |
13 | #ifdef CONFIG_X86_32 | 12 | #ifdef CONFIG_X86_32 |
14 | u32 machine_real_restart_asm; | 13 | u32 machine_real_restart_asm; |
@@ -30,8 +29,8 @@ struct real_mode_header { | |||
30 | #endif | 29 | #endif |
31 | } __attribute__((__packed__)); | 30 | } __attribute__((__packed__)); |
32 | 31 | ||
33 | extern struct real_mode_header real_mode_header; | 32 | extern struct real_mode_header *real_mode_header; |
34 | extern unsigned char *real_mode_base; | 33 | extern unsigned char real_mode_blob_end[]; |
35 | 34 | ||
36 | extern unsigned long init_rsp; | 35 | extern unsigned long init_rsp; |
37 | extern unsigned long initial_code; | 36 | extern unsigned long initial_code; |
diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c index d941b62da4b6..6ca3f54ebe7d 100644 --- a/arch/x86/kernel/acpi/sleep.c +++ b/arch/x86/kernel/acpi/sleep.c | |||
@@ -38,7 +38,7 @@ asmlinkage void acpi_enter_s3(void) | |||
38 | int acpi_suspend_lowlevel(void) | 38 | int acpi_suspend_lowlevel(void) |
39 | { | 39 | { |
40 | struct wakeup_header *header = | 40 | struct wakeup_header *header = |
41 | (struct wakeup_header *) __va(real_mode_header.wakeup_header); | 41 | (struct wakeup_header *) __va(real_mode_header->wakeup_header); |
42 | 42 | ||
43 | if (header->signature != WAKEUP_HEADER_SIGNATURE) { | 43 | if (header->signature != WAKEUP_HEADER_SIGNATURE) { |
44 | printk(KERN_ERR "wakeup header does not match\n"); | 44 | printk(KERN_ERR "wakeup header does not match\n"); |
diff --git a/arch/x86/kernel/realmode.c b/arch/x86/kernel/realmode.c index e7bf82a409bf..632c810ec8ea 100644 --- a/arch/x86/kernel/realmode.c +++ b/arch/x86/kernel/realmode.c | |||
@@ -5,8 +5,7 @@ | |||
5 | #include <asm/pgtable.h> | 5 | #include <asm/pgtable.h> |
6 | #include <asm/realmode.h> | 6 | #include <asm/realmode.h> |
7 | 7 | ||
8 | unsigned char *real_mode_base; | 8 | struct real_mode_header *real_mode_header; |
9 | struct real_mode_header real_mode_header; | ||
10 | 9 | ||
11 | void __init setup_real_mode(void) | 10 | void __init setup_real_mode(void) |
12 | { | 11 | { |
@@ -17,33 +16,32 @@ void __init setup_real_mode(void) | |||
17 | u32 *ptr; | 16 | u32 *ptr; |
18 | u16 *seg; | 17 | u16 *seg; |
19 | int i; | 18 | int i; |
19 | unsigned char *base; | ||
20 | 20 | ||
21 | struct real_mode_header *header = | 21 | size_t size = PAGE_ALIGN(real_mode_blob_end - real_mode_blob); |
22 | (struct real_mode_header *) real_mode_blob; | ||
23 | |||
24 | size_t size = PAGE_ALIGN(header->end); | ||
25 | 22 | ||
26 | /* Has to be in very low memory so we can execute real-mode AP code. */ | 23 | /* Has to be in very low memory so we can execute real-mode AP code. */ |
27 | mem = memblock_find_in_range(0, 1<<20, size, PAGE_SIZE); | 24 | mem = memblock_find_in_range(0, 1<<20, size, PAGE_SIZE); |
28 | if (!mem) | 25 | if (!mem) |
29 | panic("Cannot allocate trampoline\n"); | 26 | panic("Cannot allocate trampoline\n"); |
30 | 27 | ||
31 | real_mode_base = __va(mem); | 28 | base = __va(mem); |
32 | memblock_reserve(mem, size); | 29 | memblock_reserve(mem, size); |
30 | real_mode_header = (struct real_mode_header *) base; | ||
33 | 31 | ||
34 | printk(KERN_DEBUG "Base memory trampoline at [%p] %llx size %zu\n", | 32 | printk(KERN_DEBUG "Base memory trampoline at [%p] %llx size %zu\n", |
35 | real_mode_base, (unsigned long long)mem, size); | 33 | base, (unsigned long long)mem, size); |
36 | 34 | ||
37 | memcpy(real_mode_base, real_mode_blob, size); | 35 | memcpy(base, real_mode_blob, size); |
38 | 36 | ||
39 | real_mode_seg = __pa(real_mode_base) >> 4; | 37 | real_mode_seg = __pa(base) >> 4; |
40 | rel = (u32 *) real_mode_relocs; | 38 | rel = (u32 *) real_mode_relocs; |
41 | 39 | ||
42 | /* 16-bit segment relocations. */ | 40 | /* 16-bit segment relocations. */ |
43 | count = rel[0]; | 41 | count = rel[0]; |
44 | rel = &rel[1]; | 42 | rel = &rel[1]; |
45 | for (i = 0; i < count; i++) { | 43 | for (i = 0; i < count; i++) { |
46 | seg = (u16 *) (real_mode_base + rel[i]); | 44 | seg = (u16 *) (base + rel[i]); |
47 | *seg = real_mode_seg; | 45 | *seg = real_mode_seg; |
48 | } | 46 | } |
49 | 47 | ||
@@ -51,25 +49,21 @@ void __init setup_real_mode(void) | |||
51 | count = rel[i]; | 49 | count = rel[i]; |
52 | rel = &rel[i + 1]; | 50 | rel = &rel[i + 1]; |
53 | for (i = 0; i < count; i++) { | 51 | for (i = 0; i < count; i++) { |
54 | ptr = (u32 *) (real_mode_base + rel[i]); | 52 | ptr = (u32 *) (base + rel[i]); |
55 | *ptr += __pa(real_mode_base); | 53 | *ptr += __pa(base); |
56 | } | 54 | } |
57 | 55 | ||
58 | /* Copied header will contain relocated physical addresses. */ | ||
59 | memcpy(&real_mode_header, real_mode_base, | ||
60 | sizeof(struct real_mode_header)); | ||
61 | |||
62 | #ifdef CONFIG_X86_32 | 56 | #ifdef CONFIG_X86_32 |
63 | *((u32 *)__va(real_mode_header.startup_32_smp)) = __pa(startup_32_smp); | 57 | *((u32 *)__va(real_mode_header->startup_32_smp)) = __pa(startup_32_smp); |
64 | *((u32 *)__va(real_mode_header.boot_gdt)) = __pa(boot_gdt); | 58 | *((u32 *)__va(real_mode_header->boot_gdt)) = __pa(boot_gdt); |
65 | #else | 59 | #else |
66 | *((u64 *) __va(real_mode_header.startup_64_smp)) = | 60 | *((u64 *) __va(real_mode_header->startup_64_smp)) = |
67 | (u64)secondary_startup_64; | 61 | (u64)secondary_startup_64; |
68 | 62 | ||
69 | *((u64 *) __va(real_mode_header.level3_ident_pgt)) = | 63 | *((u64 *) __va(real_mode_header->level3_ident_pgt)) = |
70 | __pa(level3_ident_pgt) + _KERNPG_TABLE; | 64 | __pa(level3_ident_pgt) + _KERNPG_TABLE; |
71 | 65 | ||
72 | *((u64 *) __va(real_mode_header.level3_kernel_pgt)) = | 66 | *((u64 *) __va(real_mode_header->level3_kernel_pgt)) = |
73 | __pa(level3_kernel_pgt) + _KERNPG_TABLE; | 67 | __pa(level3_kernel_pgt) + _KERNPG_TABLE; |
74 | #endif | 68 | #endif |
75 | } | 69 | } |
@@ -82,23 +76,22 @@ void __init setup_real_mode(void) | |||
82 | */ | 76 | */ |
83 | static int __init set_real_mode_permissions(void) | 77 | static int __init set_real_mode_permissions(void) |
84 | { | 78 | { |
85 | size_t all_size = | 79 | unsigned char *base = (unsigned char *) real_mode_header; |
86 | PAGE_ALIGN(real_mode_header.end) - | 80 | size_t size = PAGE_ALIGN(real_mode_blob_end - real_mode_blob); |
87 | __pa(real_mode_base); | ||
88 | 81 | ||
89 | size_t ro_size = | 82 | size_t ro_size = |
90 | PAGE_ALIGN(real_mode_header.ro_end) - | 83 | PAGE_ALIGN(real_mode_header->ro_end) - |
91 | __pa(real_mode_base); | 84 | __pa(base); |
92 | 85 | ||
93 | size_t text_size = | 86 | size_t text_size = |
94 | PAGE_ALIGN(real_mode_header.ro_end) - | 87 | PAGE_ALIGN(real_mode_header->ro_end) - |
95 | real_mode_header.text_start; | 88 | real_mode_header->text_start; |
96 | 89 | ||
97 | unsigned long text_start = | 90 | unsigned long text_start = |
98 | (unsigned long) __va(real_mode_header.text_start); | 91 | (unsigned long) __va(real_mode_header->text_start); |
99 | 92 | ||
100 | set_memory_nx((unsigned long) real_mode_base, all_size >> PAGE_SHIFT); | 93 | set_memory_nx((unsigned long) base, size >> PAGE_SHIFT); |
101 | set_memory_ro((unsigned long) real_mode_base, ro_size >> PAGE_SHIFT); | 94 | set_memory_ro((unsigned long) base, ro_size >> PAGE_SHIFT); |
102 | set_memory_x((unsigned long) text_start, text_size >> PAGE_SHIFT); | 95 | set_memory_x((unsigned long) text_start, text_size >> PAGE_SHIFT); |
103 | 96 | ||
104 | return 0; | 97 | return 0; |
diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c index 050eff29a4bb..658f856f09a3 100644 --- a/arch/x86/kernel/reboot.c +++ b/arch/x86/kernel/reboot.c | |||
@@ -336,7 +336,7 @@ core_initcall(reboot_init); | |||
336 | void machine_real_restart(unsigned int type) | 336 | void machine_real_restart(unsigned int type) |
337 | { | 337 | { |
338 | void (*restart_lowmem)(unsigned int) = (void (*)(unsigned int)) | 338 | void (*restart_lowmem)(unsigned int) = (void (*)(unsigned int)) |
339 | real_mode_header.machine_real_restart_asm; | 339 | real_mode_header->machine_real_restart_asm; |
340 | 340 | ||
341 | local_irq_disable(); | 341 | local_irq_disable(); |
342 | 342 | ||
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index c7971ea74bd0..b8c0661e2341 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c | |||
@@ -665,9 +665,9 @@ static void __cpuinit announce_cpu(int cpu, int apicid) | |||
665 | static int __cpuinit do_boot_cpu(int apicid, int cpu) | 665 | static int __cpuinit do_boot_cpu(int apicid, int cpu) |
666 | { | 666 | { |
667 | volatile u32 *trampoline_status = | 667 | volatile u32 *trampoline_status = |
668 | (volatile u32 *) __va(real_mode_header.trampoline_status); | 668 | (volatile u32 *) __va(real_mode_header->trampoline_status); |
669 | /* start_ip had better be page-aligned! */ | 669 | /* start_ip had better be page-aligned! */ |
670 | unsigned long start_ip = real_mode_header.trampoline_data; | 670 | unsigned long start_ip = real_mode_header->trampoline_data; |
671 | 671 | ||
672 | unsigned long boot_error = 0; | 672 | unsigned long boot_error = 0; |
673 | int timeout; | 673 | int timeout; |
diff --git a/arch/x86/kernel/tboot.c b/arch/x86/kernel/tboot.c index c136e2325062..65adda4fde93 100644 --- a/arch/x86/kernel/tboot.c +++ b/arch/x86/kernel/tboot.c | |||
@@ -202,7 +202,7 @@ static int tboot_setup_sleep(void) | |||
202 | } | 202 | } |
203 | 203 | ||
204 | tboot->acpi_sinfo.kernel_s3_resume_vector = | 204 | tboot->acpi_sinfo.kernel_s3_resume_vector = |
205 | real_mode_header.wakeup_start; | 205 | real_mode_header->wakeup_start; |
206 | 206 | ||
207 | return 0; | 207 | return 0; |
208 | } | 208 | } |
diff --git a/arch/x86/realmode/rm/header.S b/arch/x86/realmode/rm/header.S index a91ec8f6b15f..c83005c4d455 100644 --- a/arch/x86/realmode/rm/header.S +++ b/arch/x86/realmode/rm/header.S | |||
@@ -12,7 +12,6 @@ | |||
12 | GLOBAL(real_mode_header) | 12 | GLOBAL(real_mode_header) |
13 | .long pa_text_start | 13 | .long pa_text_start |
14 | .long pa_ro_end | 14 | .long pa_ro_end |
15 | .long pa_end | ||
16 | #ifdef CONFIG_X86_32 | 15 | #ifdef CONFIG_X86_32 |
17 | .long pa_machine_real_restart_asm | 16 | .long pa_machine_real_restart_asm |
18 | #endif | 17 | #endif |
diff --git a/arch/x86/realmode/rm/realmode.lds.S b/arch/x86/realmode/rm/realmode.lds.S index 4d4afcaf5f02..86b2e8d6b1f1 100644 --- a/arch/x86/realmode/rm/realmode.lds.S +++ b/arch/x86/realmode/rm/realmode.lds.S | |||
@@ -65,7 +65,6 @@ SECTIONS | |||
65 | .signature : { | 65 | .signature : { |
66 | *(.signature) | 66 | *(.signature) |
67 | } | 67 | } |
68 | pa_end = .; | ||
69 | 68 | ||
70 | /DISCARD/ : { | 69 | /DISCARD/ : { |
71 | *(.note*) | 70 | *(.note*) |
diff --git a/arch/x86/realmode/rmpiggy.S b/arch/x86/realmode/rmpiggy.S index fd72a99d12ae..204c6ece0e97 100644 --- a/arch/x86/realmode/rmpiggy.S +++ b/arch/x86/realmode/rmpiggy.S | |||
@@ -13,6 +13,8 @@ GLOBAL(real_mode_blob) | |||
13 | .incbin "arch/x86/realmode/rm/realmode.bin" | 13 | .incbin "arch/x86/realmode/rm/realmode.bin" |
14 | END(real_mode_blob) | 14 | END(real_mode_blob) |
15 | 15 | ||
16 | GLOBAL(real_mode_blob_end); | ||
17 | |||
16 | GLOBAL(real_mode_relocs) | 18 | GLOBAL(real_mode_relocs) |
17 | .incbin "arch/x86/realmode/rm/realmode.relocs" | 19 | .incbin "arch/x86/realmode/rm/realmode.relocs" |
18 | END(real_mode_relocs) | 20 | END(real_mode_relocs) |
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index e77aa4a1c9f6..06139005c4dd 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c | |||
@@ -93,7 +93,7 @@ static struct notifier_block tts_notifier = { | |||
93 | static int acpi_sleep_prepare(u32 acpi_state) | 93 | static int acpi_sleep_prepare(u32 acpi_state) |
94 | { | 94 | { |
95 | #ifdef CONFIG_ACPI_SLEEP | 95 | #ifdef CONFIG_ACPI_SLEEP |
96 | unsigned long wakeup_pa = real_mode_header.wakeup_start; | 96 | unsigned long wakeup_pa = real_mode_header->wakeup_start; |
97 | /* do we have a wakeup address for S2 and S3? */ | 97 | /* do we have a wakeup address for S2 and S3? */ |
98 | if (acpi_state == ACPI_STATE_S3) { | 98 | if (acpi_state == ACPI_STATE_S3) { |
99 | if (!wakeup_pa) | 99 | if (!wakeup_pa) |