aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVivek Goyal <vgoyal@in.ibm.com>2007-05-02 13:27:07 -0400
committerAndi Kleen <andi@basil.nowhere.org>2007-05-02 13:27:07 -0400
commitcfd243d4af7c7f8f52f5cb99d3932d9074b039ff (patch)
treeae9b25a414117d0d39b535e5701d5a1b3f907558
parentbdb96a6614cfaba24e23dd9de4040c068c3af19b (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.S39
-rw-r--r--arch/x86_64/kernel/head64.c17
-rw-r--r--arch/x86_64/kernel/setup.c2
-rw-r--r--arch/x86_64/kernel/setup64.c1
-rw-r--r--arch/x86_64/mm/init.c24
-rw-r--r--include/asm-x86_64/pgtable.h1
-rw-r--r--include/asm-x86_64/proto.h2
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 */
277NEXT_PAGE(init_level4_pgt) 283NEXT_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
281NEXT_PAGE(level3_ident_pgt) 291NEXT_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
321ENTRY(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
333cpu_gdt_descr: 322cpu_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
24static 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. */
25static void __init clear_bss(void) 33static 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
381void __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
397void __init paging_init(void) 382void __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
583void free_init_pages(char *what, unsigned long begin, unsigned long end) 559void 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];
17extern pud_t level3_ident_pgt[512]; 17extern pud_t level3_ident_pgt[512];
18extern pmd_t level2_kernel_pgt[512]; 18extern pmd_t level2_kernel_pgt[512];
19extern pgd_t init_level4_pgt[]; 19extern pgd_t init_level4_pgt[];
20extern pgd_t boot_level4_pgt[];
21extern unsigned long __supported_pte_mask; 20extern 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;
11extern void start_kernel(void); 11extern void start_kernel(void);
12extern void pda_init(int); 12extern void pda_init(int);
13 13
14extern void zap_low_mappings(int cpu);
15
16extern void early_idt_handler(void); 14extern void early_idt_handler(void);
17 15
18extern void mcheck_init(struct cpuinfo_x86 *c); 16extern void mcheck_init(struct cpuinfo_x86 *c);