diff options
author | Borislav Petkov <bp@alien8.de> | 2010-08-28 09:58:33 -0400 |
---|---|---|
committer | H. Peter Anvin <hpa@linux.intel.com> | 2010-10-20 17:23:55 -0400 |
commit | b40827fa7268fda8a62490728a61c2856f33830b (patch) | |
tree | ae16ce8206c3d72ca672a92a46dc0725faba1ced /arch/x86/kernel/head_32.S | |
parent | d25e6b0b326278a1096e8334584c3e64517057a3 (diff) |
x86-32, mm: Add an initial page table for core bootstrapping
This patch adds an initial page table with low mappings used exclusively
for booting APs/resuming after ACPI suspend/machine restart. After this,
there's no need to add low mappings to swapper_pg_dir and zap them later
or create own swsusp PGD page solely for ACPI sleep needs - we have
initial_page_table for that.
Signed-off-by: Borislav Petkov <bp@alien8.de>
LKML-Reference: <20101020070526.GA9588@liondog.tnic>
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Diffstat (limited to 'arch/x86/kernel/head_32.S')
-rw-r--r-- | arch/x86/kernel/head_32.S | 55 |
1 files changed, 25 insertions, 30 deletions
diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S index fa8c1b8e09fb..bcece91dd311 100644 --- a/arch/x86/kernel/head_32.S +++ b/arch/x86/kernel/head_32.S | |||
@@ -183,13 +183,12 @@ default_entry: | |||
183 | #ifdef CONFIG_X86_PAE | 183 | #ifdef CONFIG_X86_PAE |
184 | 184 | ||
185 | /* | 185 | /* |
186 | * In PAE mode swapper_pg_dir is statically defined to contain enough | 186 | * In PAE mode initial_page_table is statically defined to contain |
187 | * entries to cover the VMSPLIT option (that is the top 1, 2 or 3 | 187 | * enough entries to cover the VMSPLIT option (that is the top 1, 2 or 3 |
188 | * entries). The identity mapping is handled by pointing two PGD | 188 | * entries). The identity mapping is handled by pointing two PGD entries |
189 | * entries to the first kernel PMD. | 189 | * to the first kernel PMD. |
190 | * | 190 | * |
191 | * Note the upper half of each PMD or PTE are always zero at | 191 | * Note the upper half of each PMD or PTE are always zero at this stage. |
192 | * this stage. | ||
193 | */ | 192 | */ |
194 | 193 | ||
195 | #define KPMDS (((-__PAGE_OFFSET) >> 30) & 3) /* Number of kernel PMDs */ | 194 | #define KPMDS (((-__PAGE_OFFSET) >> 30) & 3) /* Number of kernel PMDs */ |
@@ -197,7 +196,7 @@ default_entry: | |||
197 | xorl %ebx,%ebx /* %ebx is kept at zero */ | 196 | xorl %ebx,%ebx /* %ebx is kept at zero */ |
198 | 197 | ||
199 | movl $pa(__brk_base), %edi | 198 | movl $pa(__brk_base), %edi |
200 | movl $pa(swapper_pg_pmd), %edx | 199 | movl $pa(initial_pg_pmd), %edx |
201 | movl $PTE_IDENT_ATTR, %eax | 200 | movl $PTE_IDENT_ATTR, %eax |
202 | 10: | 201 | 10: |
203 | leal PDE_IDENT_ATTR(%edi),%ecx /* Create PMD entry */ | 202 | leal PDE_IDENT_ATTR(%edi),%ecx /* Create PMD entry */ |
@@ -226,14 +225,14 @@ default_entry: | |||
226 | movl %eax, pa(max_pfn_mapped) | 225 | movl %eax, pa(max_pfn_mapped) |
227 | 226 | ||
228 | /* Do early initialization of the fixmap area */ | 227 | /* Do early initialization of the fixmap area */ |
229 | movl $pa(swapper_pg_fixmap)+PDE_IDENT_ATTR,%eax | 228 | movl $pa(initial_pg_fixmap)+PDE_IDENT_ATTR,%eax |
230 | movl %eax,pa(swapper_pg_pmd+0x1000*KPMDS-8) | 229 | movl %eax,pa(initial_pg_pmd+0x1000*KPMDS-8) |
231 | #else /* Not PAE */ | 230 | #else /* Not PAE */ |
232 | 231 | ||
233 | page_pde_offset = (__PAGE_OFFSET >> 20); | 232 | page_pde_offset = (__PAGE_OFFSET >> 20); |
234 | 233 | ||
235 | movl $pa(__brk_base), %edi | 234 | movl $pa(__brk_base), %edi |
236 | movl $pa(swapper_pg_dir), %edx | 235 | movl $pa(initial_page_table), %edx |
237 | movl $PTE_IDENT_ATTR, %eax | 236 | movl $PTE_IDENT_ATTR, %eax |
238 | 10: | 237 | 10: |
239 | leal PDE_IDENT_ATTR(%edi),%ecx /* Create PDE entry */ | 238 | leal PDE_IDENT_ATTR(%edi),%ecx /* Create PDE entry */ |
@@ -257,8 +256,8 @@ page_pde_offset = (__PAGE_OFFSET >> 20); | |||
257 | movl %eax, pa(max_pfn_mapped) | 256 | movl %eax, pa(max_pfn_mapped) |
258 | 257 | ||
259 | /* Do early initialization of the fixmap area */ | 258 | /* Do early initialization of the fixmap area */ |
260 | movl $pa(swapper_pg_fixmap)+PDE_IDENT_ATTR,%eax | 259 | movl $pa(initial_pg_fixmap)+PDE_IDENT_ATTR,%eax |
261 | movl %eax,pa(swapper_pg_dir+0xffc) | 260 | movl %eax,pa(initial_page_table+0xffc) |
262 | #endif | 261 | #endif |
263 | jmp 3f | 262 | jmp 3f |
264 | /* | 263 | /* |
@@ -334,7 +333,7 @@ ENTRY(startup_32_smp) | |||
334 | /* | 333 | /* |
335 | * Enable paging | 334 | * Enable paging |
336 | */ | 335 | */ |
337 | movl pa(initial_page_table), %eax | 336 | movl $pa(initial_page_table), %eax |
338 | movl %eax,%cr3 /* set the page table pointer.. */ | 337 | movl %eax,%cr3 /* set the page table pointer.. */ |
339 | movl %cr0,%eax | 338 | movl %cr0,%eax |
340 | orl $X86_CR0_PG,%eax | 339 | orl $X86_CR0_PG,%eax |
@@ -614,8 +613,6 @@ ignore_int: | |||
614 | .align 4 | 613 | .align 4 |
615 | ENTRY(initial_code) | 614 | ENTRY(initial_code) |
616 | .long i386_start_kernel | 615 | .long i386_start_kernel |
617 | ENTRY(initial_page_table) | ||
618 | .long pa(swapper_pg_dir) | ||
619 | 616 | ||
620 | /* | 617 | /* |
621 | * BSS section | 618 | * BSS section |
@@ -623,20 +620,18 @@ ENTRY(initial_page_table) | |||
623 | __PAGE_ALIGNED_BSS | 620 | __PAGE_ALIGNED_BSS |
624 | .align PAGE_SIZE_asm | 621 | .align PAGE_SIZE_asm |
625 | #ifdef CONFIG_X86_PAE | 622 | #ifdef CONFIG_X86_PAE |
626 | swapper_pg_pmd: | 623 | initial_pg_pmd: |
627 | .fill 1024*KPMDS,4,0 | 624 | .fill 1024*KPMDS,4,0 |
628 | #else | 625 | #else |
629 | ENTRY(swapper_pg_dir) | 626 | ENTRY(initial_page_table) |
630 | .fill 1024,4,0 | 627 | .fill 1024,4,0 |
631 | #endif | 628 | #endif |
632 | swapper_pg_fixmap: | 629 | initial_pg_fixmap: |
633 | .fill 1024,4,0 | 630 | .fill 1024,4,0 |
634 | #ifdef CONFIG_X86_TRAMPOLINE | ||
635 | ENTRY(trampoline_pg_dir) | ||
636 | .fill 1024,4,0 | ||
637 | #endif | ||
638 | ENTRY(empty_zero_page) | 631 | ENTRY(empty_zero_page) |
639 | .fill 4096,1,0 | 632 | .fill 4096,1,0 |
633 | ENTRY(swapper_pg_dir) | ||
634 | .fill 1024,4,0 | ||
640 | 635 | ||
641 | /* | 636 | /* |
642 | * This starts the data section. | 637 | * This starts the data section. |
@@ -645,20 +640,20 @@ ENTRY(empty_zero_page) | |||
645 | __PAGE_ALIGNED_DATA | 640 | __PAGE_ALIGNED_DATA |
646 | /* Page-aligned for the benefit of paravirt? */ | 641 | /* Page-aligned for the benefit of paravirt? */ |
647 | .align PAGE_SIZE_asm | 642 | .align PAGE_SIZE_asm |
648 | ENTRY(swapper_pg_dir) | 643 | ENTRY(initial_page_table) |
649 | .long pa(swapper_pg_pmd+PGD_IDENT_ATTR),0 /* low identity map */ | 644 | .long pa(initial_pg_pmd+PGD_IDENT_ATTR),0 /* low identity map */ |
650 | # if KPMDS == 3 | 645 | # if KPMDS == 3 |
651 | .long pa(swapper_pg_pmd+PGD_IDENT_ATTR),0 | 646 | .long pa(initial_pg_pmd+PGD_IDENT_ATTR),0 |
652 | .long pa(swapper_pg_pmd+PGD_IDENT_ATTR+0x1000),0 | 647 | .long pa(initial_pg_pmd+PGD_IDENT_ATTR+0x1000),0 |
653 | .long pa(swapper_pg_pmd+PGD_IDENT_ATTR+0x2000),0 | 648 | .long pa(initial_pg_pmd+PGD_IDENT_ATTR+0x2000),0 |
654 | # elif KPMDS == 2 | 649 | # elif KPMDS == 2 |
655 | .long 0,0 | 650 | .long 0,0 |
656 | .long pa(swapper_pg_pmd+PGD_IDENT_ATTR),0 | 651 | .long pa(initial_pg_pmd+PGD_IDENT_ATTR),0 |
657 | .long pa(swapper_pg_pmd+PGD_IDENT_ATTR+0x1000),0 | 652 | .long pa(initial_pg_pmd+PGD_IDENT_ATTR+0x1000),0 |
658 | # elif KPMDS == 1 | 653 | # elif KPMDS == 1 |
659 | .long 0,0 | 654 | .long 0,0 |
660 | .long 0,0 | 655 | .long 0,0 |
661 | .long pa(swapper_pg_pmd+PGD_IDENT_ATTR),0 | 656 | .long pa(initial_pg_pmd+PGD_IDENT_ATTR),0 |
662 | # else | 657 | # else |
663 | # error "Kernel PMDs should be 1, 2 or 3" | 658 | # error "Kernel PMDs should be 1, 2 or 3" |
664 | # endif | 659 | # endif |