Loading arch/x86/kernel/head_32.S +2 −2 Original line number Diff line number Diff line Loading @@ -620,13 +620,13 @@ ENTRY(initial_code) __PAGE_ALIGNED_BSS .align PAGE_SIZE_asm #ifdef CONFIG_X86_PAE initial_pg_pmd: ENTRY(initial_pg_pmd) .fill 1024*KPMDS,4,0 #else ENTRY(initial_page_table) .fill 1024,4,0 #endif initial_pg_fixmap: ENTRY(initial_pg_fixmap) .fill 1024,4,0 ENTRY(empty_zero_page) .fill 4096,1,0 Loading arch/x86/lguest/boot.c +8 −8 Original line number Diff line number Diff line Loading @@ -531,6 +531,9 @@ static void lguest_write_cr3(unsigned long cr3) { lguest_data.pgdir = cr3; lazy_hcall1(LHCALL_NEW_PGTABLE, cr3); /* These two page tables are simple, linear, and used during boot */ if (cr3 != __pa(swapper_pg_dir) && cr3 != __pa(initial_page_table)) cr3_changed = true; } Loading Loading @@ -703,9 +706,9 @@ static void lguest_set_pmd(pmd_t *pmdp, pmd_t pmdval) * to forget all of them. Fortunately, this is very rare. * * ... except in early boot when the kernel sets up the initial pagetables, * which makes booting astonishingly slow: 1.83 seconds! So we don't even tell * the Host anything changed until we've done the first page table switch, * which brings boot back to 0.25 seconds. * which makes booting astonishingly slow: 48 seconds! So we don't even tell * the Host anything changed until we've done the first real page table switch, * which brings boot back to 4.3 seconds. */ static void lguest_set_pte(pte_t *ptep, pte_t pteval) { Loading Loading @@ -1002,7 +1005,7 @@ static void lguest_time_init(void) clockevents_register_device(&lguest_clockevent); /* Finally, we unblock the timer interrupt. */ enable_lguest_irq(0); clear_bit(0, lguest_data.blocked_interrupts); } /* Loading Loading @@ -1349,9 +1352,6 @@ __init void lguest_init(void) */ switch_to_new_gdt(0); /* We actually boot with all memory mapped, but let's say 128MB. */ max_pfn_mapped = (128*1024*1024) >> PAGE_SHIFT; /* * The Host<->Guest Switcher lives at the top of our address space, and * the Host told us how big it is when we made LGUEST_INIT hypercall: Loading arch/x86/lguest/i386_head.S +105 −0 Original line number Diff line number Diff line Loading @@ -4,6 +4,7 @@ #include <asm/asm-offsets.h> #include <asm/thread_info.h> #include <asm/processor-flags.h> #include <asm/pgtable.h> /*G:020 * Our story starts with the kernel booting into startup_32 in Loading Loading @@ -37,9 +38,113 @@ ENTRY(lguest_entry) /* Set up the initial stack so we can run C code. */ movl $(init_thread_union+THREAD_SIZE),%esp call init_pagetables /* Jumps are relative: we're running __PAGE_OFFSET too low. */ jmp lguest_init+__PAGE_OFFSET /* * Initialize page tables. This creates a PDE and a set of page * tables, which are located immediately beyond __brk_base. The variable * _brk_end is set up to point to the first "safe" location. * Mappings are created both at virtual address 0 (identity mapping) * and PAGE_OFFSET for up to _end. * * FIXME: This code is taken verbatim from arch/x86/kernel/head_32.S: they * don't have a stack at this point, so we can't just use call and ret. */ init_pagetables: #if PTRS_PER_PMD > 1 #define PAGE_TABLE_SIZE(pages) (((pages) / PTRS_PER_PMD) + PTRS_PER_PGD) #else #define PAGE_TABLE_SIZE(pages) ((pages) / PTRS_PER_PGD) #endif #define pa(X) ((X) - __PAGE_OFFSET) /* Enough space to fit pagetables for the low memory linear map */ MAPPING_BEYOND_END = \ PAGE_TABLE_SIZE(((1<<32) - __PAGE_OFFSET) >> PAGE_SHIFT) << PAGE_SHIFT #ifdef CONFIG_X86_PAE /* * In PAE mode initial_page_table is statically defined to contain * enough entries to cover the VMSPLIT option (that is the top 1, 2 or 3 * entries). The identity mapping is handled by pointing two PGD entries * to the first kernel PMD. * * Note the upper half of each PMD or PTE are always zero at this stage. */ #define KPMDS (((-__PAGE_OFFSET) >> 30) & 3) /* Number of kernel PMDs */ xorl %ebx,%ebx /* %ebx is kept at zero */ movl $pa(__brk_base), %edi movl $pa(initial_pg_pmd), %edx movl $PTE_IDENT_ATTR, %eax 10: leal PDE_IDENT_ATTR(%edi),%ecx /* Create PMD entry */ movl %ecx,(%edx) /* Store PMD entry */ /* Upper half already zero */ addl $8,%edx movl $512,%ecx 11: stosl xchgl %eax,%ebx stosl xchgl %eax,%ebx addl $0x1000,%eax loop 11b /* * End condition: we must map up to the end + MAPPING_BEYOND_END. */ movl $pa(_end) + MAPPING_BEYOND_END + PTE_IDENT_ATTR, %ebp cmpl %ebp,%eax jb 10b 1: addl $__PAGE_OFFSET, %edi movl %edi, pa(_brk_end) shrl $12, %eax movl %eax, pa(max_pfn_mapped) /* Do early initialization of the fixmap area */ movl $pa(initial_pg_fixmap)+PDE_IDENT_ATTR,%eax movl %eax,pa(initial_pg_pmd+0x1000*KPMDS-8) #else /* Not PAE */ page_pde_offset = (__PAGE_OFFSET >> 20); movl $pa(__brk_base), %edi movl $pa(initial_page_table), %edx movl $PTE_IDENT_ATTR, %eax 10: leal PDE_IDENT_ATTR(%edi),%ecx /* Create PDE entry */ movl %ecx,(%edx) /* Store identity PDE entry */ movl %ecx,page_pde_offset(%edx) /* Store kernel PDE entry */ addl $4,%edx movl $1024, %ecx 11: stosl addl $0x1000,%eax loop 11b /* * End condition: we must map up to the end + MAPPING_BEYOND_END. */ movl $pa(_end) + MAPPING_BEYOND_END + PTE_IDENT_ATTR, %ebp cmpl %ebp,%eax jb 10b addl $__PAGE_OFFSET, %edi movl %edi, pa(_brk_end) shrl $12, %eax movl %eax, pa(max_pfn_mapped) /* Do early initialization of the fixmap area */ movl $pa(initial_pg_fixmap)+PDE_IDENT_ATTR,%eax movl %eax,pa(initial_page_table+0xffc) #endif ret /*G:055 * We create a macro which puts the assembler code between lgstart_ and lgend_ * markers. These templates are put in the .text section: they can't be Loading Loading
arch/x86/kernel/head_32.S +2 −2 Original line number Diff line number Diff line Loading @@ -620,13 +620,13 @@ ENTRY(initial_code) __PAGE_ALIGNED_BSS .align PAGE_SIZE_asm #ifdef CONFIG_X86_PAE initial_pg_pmd: ENTRY(initial_pg_pmd) .fill 1024*KPMDS,4,0 #else ENTRY(initial_page_table) .fill 1024,4,0 #endif initial_pg_fixmap: ENTRY(initial_pg_fixmap) .fill 1024,4,0 ENTRY(empty_zero_page) .fill 4096,1,0 Loading
arch/x86/lguest/boot.c +8 −8 Original line number Diff line number Diff line Loading @@ -531,6 +531,9 @@ static void lguest_write_cr3(unsigned long cr3) { lguest_data.pgdir = cr3; lazy_hcall1(LHCALL_NEW_PGTABLE, cr3); /* These two page tables are simple, linear, and used during boot */ if (cr3 != __pa(swapper_pg_dir) && cr3 != __pa(initial_page_table)) cr3_changed = true; } Loading Loading @@ -703,9 +706,9 @@ static void lguest_set_pmd(pmd_t *pmdp, pmd_t pmdval) * to forget all of them. Fortunately, this is very rare. * * ... except in early boot when the kernel sets up the initial pagetables, * which makes booting astonishingly slow: 1.83 seconds! So we don't even tell * the Host anything changed until we've done the first page table switch, * which brings boot back to 0.25 seconds. * which makes booting astonishingly slow: 48 seconds! So we don't even tell * the Host anything changed until we've done the first real page table switch, * which brings boot back to 4.3 seconds. */ static void lguest_set_pte(pte_t *ptep, pte_t pteval) { Loading Loading @@ -1002,7 +1005,7 @@ static void lguest_time_init(void) clockevents_register_device(&lguest_clockevent); /* Finally, we unblock the timer interrupt. */ enable_lguest_irq(0); clear_bit(0, lguest_data.blocked_interrupts); } /* Loading Loading @@ -1349,9 +1352,6 @@ __init void lguest_init(void) */ switch_to_new_gdt(0); /* We actually boot with all memory mapped, but let's say 128MB. */ max_pfn_mapped = (128*1024*1024) >> PAGE_SHIFT; /* * The Host<->Guest Switcher lives at the top of our address space, and * the Host told us how big it is when we made LGUEST_INIT hypercall: Loading
arch/x86/lguest/i386_head.S +105 −0 Original line number Diff line number Diff line Loading @@ -4,6 +4,7 @@ #include <asm/asm-offsets.h> #include <asm/thread_info.h> #include <asm/processor-flags.h> #include <asm/pgtable.h> /*G:020 * Our story starts with the kernel booting into startup_32 in Loading Loading @@ -37,9 +38,113 @@ ENTRY(lguest_entry) /* Set up the initial stack so we can run C code. */ movl $(init_thread_union+THREAD_SIZE),%esp call init_pagetables /* Jumps are relative: we're running __PAGE_OFFSET too low. */ jmp lguest_init+__PAGE_OFFSET /* * Initialize page tables. This creates a PDE and a set of page * tables, which are located immediately beyond __brk_base. The variable * _brk_end is set up to point to the first "safe" location. * Mappings are created both at virtual address 0 (identity mapping) * and PAGE_OFFSET for up to _end. * * FIXME: This code is taken verbatim from arch/x86/kernel/head_32.S: they * don't have a stack at this point, so we can't just use call and ret. */ init_pagetables: #if PTRS_PER_PMD > 1 #define PAGE_TABLE_SIZE(pages) (((pages) / PTRS_PER_PMD) + PTRS_PER_PGD) #else #define PAGE_TABLE_SIZE(pages) ((pages) / PTRS_PER_PGD) #endif #define pa(X) ((X) - __PAGE_OFFSET) /* Enough space to fit pagetables for the low memory linear map */ MAPPING_BEYOND_END = \ PAGE_TABLE_SIZE(((1<<32) - __PAGE_OFFSET) >> PAGE_SHIFT) << PAGE_SHIFT #ifdef CONFIG_X86_PAE /* * In PAE mode initial_page_table is statically defined to contain * enough entries to cover the VMSPLIT option (that is the top 1, 2 or 3 * entries). The identity mapping is handled by pointing two PGD entries * to the first kernel PMD. * * Note the upper half of each PMD or PTE are always zero at this stage. */ #define KPMDS (((-__PAGE_OFFSET) >> 30) & 3) /* Number of kernel PMDs */ xorl %ebx,%ebx /* %ebx is kept at zero */ movl $pa(__brk_base), %edi movl $pa(initial_pg_pmd), %edx movl $PTE_IDENT_ATTR, %eax 10: leal PDE_IDENT_ATTR(%edi),%ecx /* Create PMD entry */ movl %ecx,(%edx) /* Store PMD entry */ /* Upper half already zero */ addl $8,%edx movl $512,%ecx 11: stosl xchgl %eax,%ebx stosl xchgl %eax,%ebx addl $0x1000,%eax loop 11b /* * End condition: we must map up to the end + MAPPING_BEYOND_END. */ movl $pa(_end) + MAPPING_BEYOND_END + PTE_IDENT_ATTR, %ebp cmpl %ebp,%eax jb 10b 1: addl $__PAGE_OFFSET, %edi movl %edi, pa(_brk_end) shrl $12, %eax movl %eax, pa(max_pfn_mapped) /* Do early initialization of the fixmap area */ movl $pa(initial_pg_fixmap)+PDE_IDENT_ATTR,%eax movl %eax,pa(initial_pg_pmd+0x1000*KPMDS-8) #else /* Not PAE */ page_pde_offset = (__PAGE_OFFSET >> 20); movl $pa(__brk_base), %edi movl $pa(initial_page_table), %edx movl $PTE_IDENT_ATTR, %eax 10: leal PDE_IDENT_ATTR(%edi),%ecx /* Create PDE entry */ movl %ecx,(%edx) /* Store identity PDE entry */ movl %ecx,page_pde_offset(%edx) /* Store kernel PDE entry */ addl $4,%edx movl $1024, %ecx 11: stosl addl $0x1000,%eax loop 11b /* * End condition: we must map up to the end + MAPPING_BEYOND_END. */ movl $pa(_end) + MAPPING_BEYOND_END + PTE_IDENT_ATTR, %ebp cmpl %ebp,%eax jb 10b addl $__PAGE_OFFSET, %edi movl %edi, pa(_brk_end) shrl $12, %eax movl %eax, pa(max_pfn_mapped) /* Do early initialization of the fixmap area */ movl $pa(initial_pg_fixmap)+PDE_IDENT_ATTR,%eax movl %eax,pa(initial_page_table+0xffc) #endif ret /*G:055 * We create a macro which puts the assembler code between lgstart_ and lgend_ * markers. These templates are put in the .text section: they can't be Loading