diff options
author | Jarkko Sakkinen <jarkko.sakkinen@intel.com> | 2012-05-08 14:22:46 -0400 |
---|---|---|
committer | H. Peter Anvin <hpa@linux.intel.com> | 2012-05-08 18:04:27 -0400 |
commit | cda846f101fb1396b6924f1d9b68ac3d42de5403 (patch) | |
tree | 1fa8716c308b8e10156a1caf51d8ff6c98eceea9 /arch/x86/realmode | |
parent | bf8b88e97716feb750c3d34492f00d9c085e1183 (diff) |
x86, realmode: read cr4 and EFER from kernel for 64-bit trampoline
This patch changes 64-bit trampoline so that CR4 and
EFER are provided by the kernel instead of using fixed
values.
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@intel.com>
Link: http://lkml.kernel.org/r/1336501366-28617-24-git-send-email-jarkko.sakkinen@intel.com
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Diffstat (limited to 'arch/x86/realmode')
-rw-r--r-- | arch/x86/realmode/rm/header.S | 1 | ||||
-rw-r--r-- | arch/x86/realmode/rm/trampoline_64.S | 32 | ||||
-rw-r--r-- | arch/x86/realmode/rm/trampoline_common.S | 19 |
3 files changed, 27 insertions, 25 deletions
diff --git a/arch/x86/realmode/rm/header.S b/arch/x86/realmode/rm/header.S index b4c32632bf16..4612d5382791 100644 --- a/arch/x86/realmode/rm/header.S +++ b/arch/x86/realmode/rm/header.S | |||
@@ -9,6 +9,7 @@ | |||
9 | 9 | ||
10 | .section ".header", "a" | 10 | .section ".header", "a" |
11 | 11 | ||
12 | .balign 16 | ||
12 | GLOBAL(real_mode_header) | 13 | GLOBAL(real_mode_header) |
13 | .long pa_text_start | 14 | .long pa_text_start |
14 | .long pa_ro_end | 15 | .long pa_ro_end |
diff --git a/arch/x86/realmode/rm/trampoline_64.S b/arch/x86/realmode/rm/trampoline_64.S index 3f7293239365..66e26f088288 100644 --- a/arch/x86/realmode/rm/trampoline_64.S +++ b/arch/x86/realmode/rm/trampoline_64.S | |||
@@ -34,9 +34,9 @@ | |||
34 | #include "realmode.h" | 34 | #include "realmode.h" |
35 | 35 | ||
36 | .text | 36 | .text |
37 | .balign PAGE_SIZE | ||
38 | .code16 | 37 | .code16 |
39 | 38 | ||
39 | .balign PAGE_SIZE | ||
40 | ENTRY(trampoline_start) | 40 | ENTRY(trampoline_start) |
41 | cli # We should be safe anyway | 41 | cli # We should be safe anyway |
42 | wbinvd | 42 | wbinvd |
@@ -65,8 +65,8 @@ ENTRY(trampoline_start) | |||
65 | * to 32 bit. | 65 | * to 32 bit. |
66 | */ | 66 | */ |
67 | 67 | ||
68 | lidtl tidt # load idt with 0, 0 | 68 | lidtl tr_idt # load idt with 0, 0 |
69 | lgdtl tgdt # load gdt with whatever is appropriate | 69 | lgdtl tr_gdt # load gdt with whatever is appropriate |
70 | 70 | ||
71 | movw $__KERNEL_DS, %dx # Data segment descriptor | 71 | movw $__KERNEL_DS, %dx # Data segment descriptor |
72 | 72 | ||
@@ -93,16 +93,17 @@ ENTRY(startup_32) | |||
93 | movl %edx, %fs | 93 | movl %edx, %fs |
94 | movl %edx, %gs | 94 | movl %edx, %gs |
95 | 95 | ||
96 | movl $X86_CR4_PAE, %eax | 96 | movl pa_tr_cr4, %eax |
97 | movl %eax, %cr4 # Enable PAE mode | 97 | movl %eax, %cr4 # Enable PAE mode |
98 | 98 | ||
99 | # Setup trampoline 4 level pagetables | 99 | # Setup trampoline 4 level pagetables |
100 | movl $pa_trampoline_pgd, %eax | 100 | movl $pa_trampoline_pgd, %eax |
101 | movl %eax, %cr3 | 101 | movl %eax, %cr3 |
102 | 102 | ||
103 | # Set up EFER | ||
104 | movl pa_tr_efer, %eax | ||
105 | movl pa_tr_efer + 4, %edx | ||
103 | movl $MSR_EFER, %ecx | 106 | movl $MSR_EFER, %ecx |
104 | movl $((1 << _EFER_LME) | (1 << _EFER_NX)), %eax # Enable Long Mode | ||
105 | xorl %edx, %edx | ||
106 | wrmsr | 107 | wrmsr |
107 | 108 | ||
108 | # Enable paging and in turn activate Long Mode | 109 | # Enable paging and in turn activate Long Mode |
@@ -124,23 +125,4 @@ ENTRY(startup_64) | |||
124 | # Now jump into the kernel using virtual addresses | 125 | # Now jump into the kernel using virtual addresses |
125 | jmpq *tr_start(%rip) | 126 | jmpq *tr_start(%rip) |
126 | 127 | ||
127 | .section ".rodata","a" | ||
128 | .balign 16 | ||
129 | tidt: | ||
130 | .word 0 # idt limit = 0 | ||
131 | .word 0, 0 # idt base = 0L | ||
132 | |||
133 | # Duplicate the global descriptor table | ||
134 | # so the kernel can live anywhere | ||
135 | .balign 16 | ||
136 | .globl tgdt | ||
137 | tgdt: | ||
138 | .short tgdt_end - tgdt - 1 # gdt limit | ||
139 | .long pa_tgdt | ||
140 | .short 0 | ||
141 | .quad 0x00cf9b000000ffff # __KERNEL32_CS | ||
142 | .quad 0x00af9b000000ffff # __KERNEL_CS | ||
143 | .quad 0x00cf93000000ffff # __KERNEL_DS | ||
144 | tgdt_end: | ||
145 | |||
146 | #include "trampoline_common.S" | 128 | #include "trampoline_common.S" |
diff --git a/arch/x86/realmode/rm/trampoline_common.S b/arch/x86/realmode/rm/trampoline_common.S index c3f951c468c5..cac444b942f8 100644 --- a/arch/x86/realmode/rm/trampoline_common.S +++ b/arch/x86/realmode/rm/trampoline_common.S | |||
@@ -1,5 +1,20 @@ | |||
1 | .section ".rodata","a" | 1 | .section ".rodata","a" |
2 | 2 | ||
3 | #ifdef CONFIG_X86_64 | ||
4 | # Duplicate the global descriptor table | ||
5 | # so the kernel can live anywhere | ||
6 | .balign 16 | ||
7 | .globl tr_gdt | ||
8 | tr_gdt: | ||
9 | .short tr_gdt_end - tr_gdt - 1 # gdt limit | ||
10 | .long pa_tr_gdt | ||
11 | .short 0 | ||
12 | .quad 0x00cf9b000000ffff # __KERNEL32_CS | ||
13 | .quad 0x00af9b000000ffff # __KERNEL_CS | ||
14 | .quad 0x00cf93000000ffff # __KERNEL_DS | ||
15 | tr_gdt_end: | ||
16 | #endif | ||
17 | |||
3 | .balign 4 | 18 | .balign 4 |
4 | tr_idt: .fill 1, 6, 0 | 19 | tr_idt: .fill 1, 6, 0 |
5 | 20 | ||
@@ -8,12 +23,16 @@ tr_idt: .fill 1, 6, 0 | |||
8 | .balign 4 | 23 | .balign 4 |
9 | GLOBAL(trampoline_status) .space 4 | 24 | GLOBAL(trampoline_status) .space 4 |
10 | 25 | ||
26 | .balign 8 | ||
11 | GLOBAL(trampoline_header) | 27 | GLOBAL(trampoline_header) |
12 | #ifdef CONFIG_X86_32 | 28 | #ifdef CONFIG_X86_32 |
13 | tr_start: .space 4 | 29 | tr_start: .space 4 |
30 | tr_gdt_pad: .space 2 | ||
14 | tr_gdt: .space 6 | 31 | tr_gdt: .space 6 |
15 | #else | 32 | #else |
16 | tr_start: .space 8 | 33 | tr_start: .space 8 |
34 | GLOBAL(tr_cr4) .space 4 | ||
35 | GLOBAL(tr_efer) .space 8 | ||
17 | #endif | 36 | #endif |
18 | END(trampoline_header) | 37 | END(trampoline_header) |
19 | 38 | ||