diff options
author | Vivek Goyal <vgoyal@in.ibm.com> | 2007-05-02 13:27:07 -0400 |
---|---|---|
committer | Andi Kleen <andi@basil.nowhere.org> | 2007-05-02 13:27:07 -0400 |
commit | cfd243d4af7c7f8f52f5cb99d3932d9074b039ff (patch) | |
tree | ae9b25a414117d0d39b535e5701d5a1b3f907558 | |
parent | bdb96a6614cfaba24e23dd9de4040c068c3af19b (diff) |
[PATCH] x86-64: Remove the identity mapping as early as possible
With the rewrite of the SMP trampoline and the early page
allocator there is nothing that needs identity mapped pages,
once we start executing C code.
So add zap_identity_mappings into head64.c and remove
zap_low_mappings() from much later in the code. The functions
are subtly different thus the name change.
This also kills boot_level4_pgt which was from an earlier
attempt to move the identity mappings as early as possible,
and is now no longer needed. Essentially I have replaced
boot_level4_pgt with trampoline_level4_pgt in trampoline.S
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
Signed-off-by: Vivek Goyal <vgoyal@in.ibm.com>
Signed-off-by: Andi Kleen <ak@suse.de>
-rw-r--r-- | arch/x86_64/kernel/head.S | 39 | ||||
-rw-r--r-- | arch/x86_64/kernel/head64.c | 17 | ||||
-rw-r--r-- | arch/x86_64/kernel/setup.c | 2 | ||||
-rw-r--r-- | arch/x86_64/kernel/setup64.c | 1 | ||||
-rw-r--r-- | arch/x86_64/mm/init.c | 24 | ||||
-rw-r--r-- | include/asm-x86_64/pgtable.h | 1 | ||||
-rw-r--r-- | include/asm-x86_64/proto.h | 2 |
7 files changed, 25 insertions, 61 deletions
diff --git a/arch/x86_64/kernel/head.S b/arch/x86_64/kernel/head.S index 926aa2197aaa..c211e52f1333 100644 --- a/arch/x86_64/kernel/head.S +++ b/arch/x86_64/kernel/head.S | |||
@@ -71,7 +71,7 @@ startup_32: | |||
71 | movl %eax, %cr4 | 71 | movl %eax, %cr4 |
72 | 72 | ||
73 | /* Setup early boot stage 4 level pagetables */ | 73 | /* Setup early boot stage 4 level pagetables */ |
74 | movl $(boot_level4_pgt - __START_KERNEL_map), %eax | 74 | movl $(init_level4_pgt - __START_KERNEL_map), %eax |
75 | movl %eax, %cr3 | 75 | movl %eax, %cr3 |
76 | 76 | ||
77 | /* Setup EFER (Extended Feature Enable Register) */ | 77 | /* Setup EFER (Extended Feature Enable Register) */ |
@@ -115,7 +115,7 @@ ENTRY(secondary_startup_64) | |||
115 | movq %rax, %cr4 | 115 | movq %rax, %cr4 |
116 | 116 | ||
117 | /* Setup early boot stage 4 level pagetables. */ | 117 | /* Setup early boot stage 4 level pagetables. */ |
118 | movq $(boot_level4_pgt - __START_KERNEL_map), %rax | 118 | movq $(init_level4_pgt - __START_KERNEL_map), %rax |
119 | movq %rax, %cr3 | 119 | movq %rax, %cr3 |
120 | 120 | ||
121 | /* Check if nx is implemented */ | 121 | /* Check if nx is implemented */ |
@@ -274,9 +274,19 @@ ENTRY(name) | |||
274 | i = i + 1 ; \ | 274 | i = i + 1 ; \ |
275 | .endr | 275 | .endr |
276 | 276 | ||
277 | /* | ||
278 | * This default setting generates an ident mapping at address 0x100000 | ||
279 | * and a mapping for the kernel that precisely maps virtual address | ||
280 | * 0xffffffff80000000 to physical address 0x000000. (always using | ||
281 | * 2Mbyte large pages provided by PAE mode) | ||
282 | */ | ||
277 | NEXT_PAGE(init_level4_pgt) | 283 | NEXT_PAGE(init_level4_pgt) |
278 | /* This gets initialized in x86_64_start_kernel */ | 284 | .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE |
279 | .fill 512,8,0 | 285 | .fill 257,8,0 |
286 | .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE | ||
287 | .fill 252,8,0 | ||
288 | /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */ | ||
289 | .quad level3_kernel_pgt - __START_KERNEL_map + _PAGE_TABLE | ||
280 | 290 | ||
281 | NEXT_PAGE(level3_ident_pgt) | 291 | NEXT_PAGE(level3_ident_pgt) |
282 | .quad level2_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE | 292 | .quad level2_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE |
@@ -307,27 +317,6 @@ NEXT_PAGE(level2_kernel_pgt) | |||
307 | #undef NEXT_PAGE | 317 | #undef NEXT_PAGE |
308 | 318 | ||
309 | .data | 319 | .data |
310 | |||
311 | #ifndef CONFIG_HOTPLUG_CPU | ||
312 | __INITDATA | ||
313 | #endif | ||
314 | /* | ||
315 | * This default setting generates an ident mapping at address 0x100000 | ||
316 | * and a mapping for the kernel that precisely maps virtual address | ||
317 | * 0xffffffff80000000 to physical address 0x000000. (always using | ||
318 | * 2Mbyte large pages provided by PAE mode) | ||
319 | */ | ||
320 | .align PAGE_SIZE | ||
321 | ENTRY(boot_level4_pgt) | ||
322 | .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE | ||
323 | .fill 257,8,0 | ||
324 | .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE | ||
325 | .fill 252,8,0 | ||
326 | /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */ | ||
327 | .quad level3_kernel_pgt - __START_KERNEL_map + _PAGE_TABLE | ||
328 | |||
329 | .data | ||
330 | |||
331 | .align 16 | 320 | .align 16 |
332 | .globl cpu_gdt_descr | 321 | .globl cpu_gdt_descr |
333 | cpu_gdt_descr: | 322 | cpu_gdt_descr: |
diff --git a/arch/x86_64/kernel/head64.c b/arch/x86_64/kernel/head64.c index 5c529c1e3d6c..6c34bdd22e26 100644 --- a/arch/x86_64/kernel/head64.c +++ b/arch/x86_64/kernel/head64.c | |||
@@ -18,8 +18,16 @@ | |||
18 | #include <asm/setup.h> | 18 | #include <asm/setup.h> |
19 | #include <asm/desc.h> | 19 | #include <asm/desc.h> |
20 | #include <asm/pgtable.h> | 20 | #include <asm/pgtable.h> |
21 | #include <asm/tlbflush.h> | ||
21 | #include <asm/sections.h> | 22 | #include <asm/sections.h> |
22 | 23 | ||
24 | static void __init zap_identity_mappings(void) | ||
25 | { | ||
26 | pgd_t *pgd = pgd_offset_k(0UL); | ||
27 | pgd_clear(pgd); | ||
28 | __flush_tlb(); | ||
29 | } | ||
30 | |||
23 | /* Don't add a printk in there. printk relies on the PDA which is not initialized | 31 | /* Don't add a printk in there. printk relies on the PDA which is not initialized |
24 | yet. */ | 32 | yet. */ |
25 | static void __init clear_bss(void) | 33 | static void __init clear_bss(void) |
@@ -57,18 +65,15 @@ void __init x86_64_start_kernel(char * real_mode_data) | |||
57 | /* clear bss before set_intr_gate with early_idt_handler */ | 65 | /* clear bss before set_intr_gate with early_idt_handler */ |
58 | clear_bss(); | 66 | clear_bss(); |
59 | 67 | ||
68 | /* Make NULL pointers segfault */ | ||
69 | zap_identity_mappings(); | ||
70 | |||
60 | for (i = 0; i < IDT_ENTRIES; i++) | 71 | for (i = 0; i < IDT_ENTRIES; i++) |
61 | set_intr_gate(i, early_idt_handler); | 72 | set_intr_gate(i, early_idt_handler); |
62 | asm volatile("lidt %0" :: "m" (idt_descr)); | 73 | asm volatile("lidt %0" :: "m" (idt_descr)); |
63 | 74 | ||
64 | early_printk("Kernel alive\n"); | 75 | early_printk("Kernel alive\n"); |
65 | 76 | ||
66 | /* | ||
67 | * switch to init_level4_pgt from boot_level4_pgt | ||
68 | */ | ||
69 | memcpy(init_level4_pgt, boot_level4_pgt, PTRS_PER_PGD*sizeof(pgd_t)); | ||
70 | asm volatile("movq %0,%%cr3" :: "r" (__pa_symbol(&init_level4_pgt))); | ||
71 | |||
72 | for (i = 0; i < NR_CPUS; i++) | 77 | for (i = 0; i < NR_CPUS; i++) |
73 | cpu_pda(i) = &boot_cpu_pda[i]; | 78 | cpu_pda(i) = &boot_cpu_pda[i]; |
74 | 79 | ||
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c index 65e2bc551a2b..0e2b8df0ea64 100644 --- a/arch/x86_64/kernel/setup.c +++ b/arch/x86_64/kernel/setup.c | |||
@@ -274,8 +274,6 @@ void __init setup_arch(char **cmdline_p) | |||
274 | 274 | ||
275 | dmi_scan_machine(); | 275 | dmi_scan_machine(); |
276 | 276 | ||
277 | zap_low_mappings(0); | ||
278 | |||
279 | #ifdef CONFIG_ACPI | 277 | #ifdef CONFIG_ACPI |
280 | /* | 278 | /* |
281 | * Initialize the ACPI boot-time table parser (gets the RSDP and SDT). | 279 | * Initialize the ACPI boot-time table parser (gets the RSDP and SDT). |
diff --git a/arch/x86_64/kernel/setup64.c b/arch/x86_64/kernel/setup64.c index 6a70b55f719d..53064a9a365f 100644 --- a/arch/x86_64/kernel/setup64.c +++ b/arch/x86_64/kernel/setup64.c | |||
@@ -201,7 +201,6 @@ void __cpuinit cpu_init (void) | |||
201 | /* CPU 0 is initialised in head64.c */ | 201 | /* CPU 0 is initialised in head64.c */ |
202 | if (cpu != 0) { | 202 | if (cpu != 0) { |
203 | pda_init(cpu); | 203 | pda_init(cpu); |
204 | zap_low_mappings(cpu); | ||
205 | } else | 204 | } else |
206 | estacks = boot_exception_stacks; | 205 | estacks = boot_exception_stacks; |
207 | 206 | ||
diff --git a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c index 4ab3d40aac90..b0a607892183 100644 --- a/arch/x86_64/mm/init.c +++ b/arch/x86_64/mm/init.c | |||
@@ -378,21 +378,6 @@ void __meminit init_memory_mapping(unsigned long start, unsigned long end) | |||
378 | __flush_tlb_all(); | 378 | __flush_tlb_all(); |
379 | } | 379 | } |
380 | 380 | ||
381 | void __cpuinit zap_low_mappings(int cpu) | ||
382 | { | ||
383 | if (cpu == 0) { | ||
384 | pgd_t *pgd = pgd_offset_k(0UL); | ||
385 | pgd_clear(pgd); | ||
386 | } else { | ||
387 | /* | ||
388 | * For AP's, zap the low identity mappings by changing the cr3 | ||
389 | * to init_level4_pgt and doing local flush tlb all | ||
390 | */ | ||
391 | asm volatile("movq %0,%%cr3" :: "r" (__pa_symbol(&init_level4_pgt))); | ||
392 | } | ||
393 | __flush_tlb_all(); | ||
394 | } | ||
395 | |||
396 | #ifndef CONFIG_NUMA | 381 | #ifndef CONFIG_NUMA |
397 | void __init paging_init(void) | 382 | void __init paging_init(void) |
398 | { | 383 | { |
@@ -569,15 +554,6 @@ void __init mem_init(void) | |||
569 | reservedpages << (PAGE_SHIFT-10), | 554 | reservedpages << (PAGE_SHIFT-10), |
570 | datasize >> 10, | 555 | datasize >> 10, |
571 | initsize >> 10); | 556 | initsize >> 10); |
572 | |||
573 | #ifdef CONFIG_SMP | ||
574 | /* | ||
575 | * Sync boot_level4_pgt mappings with the init_level4_pgt | ||
576 | * except for the low identity mappings which are already zapped | ||
577 | * in init_level4_pgt. This sync-up is essential for AP's bringup | ||
578 | */ | ||
579 | memcpy(boot_level4_pgt+1, init_level4_pgt+1, (PTRS_PER_PGD-1)*sizeof(pgd_t)); | ||
580 | #endif | ||
581 | } | 557 | } |
582 | 558 | ||
583 | void free_init_pages(char *what, unsigned long begin, unsigned long end) | 559 | void free_init_pages(char *what, unsigned long begin, unsigned long end) |
diff --git a/include/asm-x86_64/pgtable.h b/include/asm-x86_64/pgtable.h index 5a5d43b3ef5d..703f0243f27a 100644 --- a/include/asm-x86_64/pgtable.h +++ b/include/asm-x86_64/pgtable.h | |||
@@ -17,7 +17,6 @@ extern pud_t level3_kernel_pgt[512]; | |||
17 | extern pud_t level3_ident_pgt[512]; | 17 | extern pud_t level3_ident_pgt[512]; |
18 | extern pmd_t level2_kernel_pgt[512]; | 18 | extern pmd_t level2_kernel_pgt[512]; |
19 | extern pgd_t init_level4_pgt[]; | 19 | extern pgd_t init_level4_pgt[]; |
20 | extern pgd_t boot_level4_pgt[]; | ||
21 | extern unsigned long __supported_pte_mask; | 20 | extern unsigned long __supported_pte_mask; |
22 | 21 | ||
23 | #define swapper_pg_dir init_level4_pgt | 22 | #define swapper_pg_dir init_level4_pgt |
diff --git a/include/asm-x86_64/proto.h b/include/asm-x86_64/proto.h index 78427021d94a..3f8f285138d2 100644 --- a/include/asm-x86_64/proto.h +++ b/include/asm-x86_64/proto.h | |||
@@ -11,8 +11,6 @@ struct pt_regs; | |||
11 | extern void start_kernel(void); | 11 | extern void start_kernel(void); |
12 | extern void pda_init(int); | 12 | extern void pda_init(int); |
13 | 13 | ||
14 | extern void zap_low_mappings(int cpu); | ||
15 | |||
16 | extern void early_idt_handler(void); | 14 | extern void early_idt_handler(void); |
17 | 15 | ||
18 | extern void mcheck_init(struct cpuinfo_x86 *c); | 16 | extern void mcheck_init(struct cpuinfo_x86 *c); |