mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 10:40:03 +01:00
Simplify pagetable initialisation. Since swapper_pg_dir now
is the one allocated by the domain builder, we can be sure it is below 4GB (essential for PAE). Signed-off-by: Keir Fraser <keir@xensource.com>
This commit is contained in:
1 parent
4e4ffc8edf
commit
40326f9fc3
5 files changed
+60
-49
No files matched your search
@@ -14,8 +14,7 @@ obj-y := process.o signal.o entry.o traps.o \
|
||||
|
||||
c-obj-y := semaphore.o vm86.o \
|
||||
ptrace.o sys_i386.o \
|
||||
i387.o dmi_scan.o bootflag.o \
|
||||
doublefault.o
|
||||
i387.o dmi_scan.o bootflag.o
|
||||
s-obj-y :=
|
||||
|
||||
obj-y += cpu/
|
||||
@@ -85,7 +84,7 @@ $(obj)/vsyscall-syms.o: $(src)/vsyscall.lds \
|
||||
$(obj)/vsyscall-sysenter.o FORCE
|
||||
$(call if_changed,syscall)
|
||||
|
||||
c-link := init_task.o
|
||||
c-link :=
|
||||
s-link := vsyscall-int80.o vsyscall-sysenter.o vsyscall-sigreturn.o vsyscall.lds.o syscall_table.o
|
||||
|
||||
$(patsubst %.o,$(obj)/%.c,$(c-obj-y) $(c-obj-m) $(c-link)) $(patsubst %.o,$(obj)/%.S,$(s-obj-y) $(s-link)):
|
||||
|
||||
@@ -136,9 +136,6 @@ cpu_gdt_descr:
|
||||
ENTRY(empty_zero_page)
|
||||
|
||||
.org 0x2000
|
||||
ENTRY(swapper_pg_dir)
|
||||
|
||||
.org 0x3000
|
||||
ENTRY(cpu_gdt_table)
|
||||
.quad 0x0000000000000000 /* NULL descriptor */
|
||||
.quad 0x0000000000000000 /* 0x0b reserved */
|
||||
@@ -190,10 +187,10 @@ ENTRY(cpu_gdt_table)
|
||||
.quad 0x0000000000000000 /* 0xf8 - GDT entry 31: double-fault TSS */
|
||||
.fill GDT_ENTRIES-32,8,0
|
||||
|
||||
.org 0x4000
|
||||
.org 0x3000
|
||||
ENTRY(default_ldt)
|
||||
|
||||
.org 0x5000
|
||||
.org 0x4000
|
||||
/*
|
||||
* Real beginning of normal "text" segment
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
#include <linux/mm.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/init_task.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/mqueue.h>
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/desc.h>
|
||||
|
||||
static struct fs_struct init_fs = INIT_FS;
|
||||
static struct files_struct init_files = INIT_FILES;
|
||||
static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
|
||||
static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
|
||||
|
||||
#define swapper_pg_dir ((pgd_t *)NULL)
|
||||
struct mm_struct init_mm = INIT_MM(init_mm);
|
||||
#undef swapper_pg_dir
|
||||
|
||||
EXPORT_SYMBOL(init_mm);
|
||||
|
||||
/*
|
||||
* Initial thread structure.
|
||||
*
|
||||
* We need to make sure that this is THREAD_SIZE aligned due to the
|
||||
* way process stacks are handled. This is done by having a special
|
||||
* "init_task" linker map entry..
|
||||
*/
|
||||
union thread_union init_thread_union
|
||||
__attribute__((__section__(".data.init_task"))) =
|
||||
{ INIT_THREAD_INFO(init_task) };
|
||||
|
||||
/*
|
||||
* Initial task structure.
|
||||
*
|
||||
* All other task structs will be allocated on slabs in fork.c
|
||||
*/
|
||||
struct task_struct init_task = INIT_TASK(init_task);
|
||||
|
||||
EXPORT_SYMBOL(init_task);
|
||||
|
||||
/*
|
||||
* per-CPU TSS segments. Threads are completely 'soft' on Linux,
|
||||
* no more per-task TSS's.
|
||||
*/
|
||||
DEFINE_PER_CPU(struct tss_struct, init_tss) ____cacheline_maxaligned_in_smp = INIT_TSS;
|
||||
|
||||
@@ -342,11 +342,15 @@ unsigned long long __PAGE_KERNEL_EXEC = _PAGE_KERNEL_EXEC;
|
||||
extern void __init remap_numa_kva(void);
|
||||
#endif
|
||||
|
||||
pgd_t *swapper_pg_dir;
|
||||
|
||||
static void __init pagetable_init (void)
|
||||
{
|
||||
unsigned long vaddr;
|
||||
pgd_t *pgd_base = swapper_pg_dir;
|
||||
pgd_t *old_pgd = (pgd_t *)xen_start_info.pt_base;
|
||||
pgd_t *pgd_base = (pgd_t *)xen_start_info.pt_base;
|
||||
|
||||
swapper_pg_dir = pgd_base;
|
||||
init_mm.pgd = pgd_base;
|
||||
|
||||
#ifdef CONFIG_X86_PAE
|
||||
int i;
|
||||
@@ -367,44 +371,6 @@ static void __init pagetable_init (void)
|
||||
__PAGE_KERNEL_EXEC |= _PAGE_GLOBAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Switch to proper mm_init page directory. Initialise from the current
|
||||
* page directory, write-protect the new page directory, then switch to
|
||||
* it. We clean up by write-enabling and then freeing the old page dir.
|
||||
*/
|
||||
#ifndef CONFIG_X86_PAE
|
||||
memcpy(pgd_base, old_pgd, PTRS_PER_PGD_NO_HV*sizeof(pgd_t));
|
||||
make_page_readonly(pgd_base);
|
||||
xen_pgd_pin(__pa(pgd_base));
|
||||
load_cr3(pgd_base);
|
||||
xen_pgd_unpin(__pa(old_pgd));
|
||||
make_page_writable(old_pgd);
|
||||
__flush_tlb_all();
|
||||
free_bootmem(__pa(old_pgd), PAGE_SIZE);
|
||||
#else
|
||||
{
|
||||
pud_t *old_pud = pud_offset(old_pgd+3, PAGE_OFFSET);
|
||||
pmd_t *old_pmd = pmd_offset(old_pud, PAGE_OFFSET);
|
||||
pmd_t *new_pmd = alloc_bootmem_low_pages(PAGE_SIZE);
|
||||
|
||||
memcpy(new_pmd, old_pmd, PAGE_SIZE);
|
||||
memcpy(pgd_base, old_pgd, PTRS_PER_PGD_NO_HV*sizeof(pgd_t));
|
||||
set_pgd(&pgd_base[3], __pgd(__pa(new_pmd) | _PAGE_PRESENT));
|
||||
|
||||
make_page_readonly(new_pmd);
|
||||
make_page_readonly(pgd_base);
|
||||
xen_pgd_pin(__pa(pgd_base));
|
||||
load_cr3(pgd_base);
|
||||
xen_pgd_unpin(__pa(old_pgd));
|
||||
make_page_writable(old_pgd);
|
||||
make_page_writable(old_pmd);
|
||||
__flush_tlb_all();
|
||||
|
||||
free_bootmem(__pa(old_pgd), PAGE_SIZE);
|
||||
free_bootmem(__pa(old_pmd), PAGE_SIZE);
|
||||
}
|
||||
#endif
|
||||
|
||||
init_mm.context.pinned = 1;
|
||||
kernel_physical_mapping_init(pgd_base);
|
||||
remap_numa_kva();
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
*/
|
||||
#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
|
||||
extern unsigned long empty_zero_page[1024];
|
||||
extern pgd_t swapper_pg_dir[1024];
|
||||
extern pgd_t *swapper_pg_dir;
|
||||
extern kmem_cache_t *pgd_cache;
|
||||
extern kmem_cache_t *pmd_cache;
|
||||
extern spinlock_t pgd_lock;
|
||||
|
||||