diff options
author | cl349@firebug.cl.cam.ac.uk <cl349@firebug.cl.cam.ac.uk> | 2005-06-01 16:40:26 +0000 |
---|---|---|
committer | cl349@firebug.cl.cam.ac.uk <cl349@firebug.cl.cam.ac.uk> | 2005-06-01 16:40:26 +0000 |
commit | f3925909949960e1d7c11f15ddb99589e7dd3f59 (patch) | |
tree | df7ba8311fce38fa32e43d0eaffe192a95301025 | |
parent | 0a461095daeffe7d114c3e7ba83cda3af76decda (diff) | |
download | xen-f3925909949960e1d7c11f15ddb99589e7dd3f59.tar.gz xen-f3925909949960e1d7c11f15ddb99589e7dd3f59.tar.bz2 xen-f3925909949960e1d7c11f15ddb99589e7dd3f59.zip |
bitkeeper revision 1.1629.1.1 (429de4faESWSriZYlaDxRVk7hKj32g)
All page directory pages have to be pinned before/during relocation, so
that the entries they contain can be canonicalised during relocation.
mmu_context.h, mmu.h, pgtable.c, ldt.c, reboot.c:
Pin all unpinned in-use pgd's before relocation.
reboot.c:
Flush the pgd cache before relocation.
Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
5 files changed, 33 insertions, 0 deletions
diff --git a/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/ldt.c b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/ldt.c index cee69b73ed..675509e0be 100644 --- a/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/ldt.c +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/ldt.c @@ -18,6 +18,7 @@ #include <asm/system.h> #include <asm/ldt.h> #include <asm/desc.h> +#include <asm/mmu_context.h> #ifdef CONFIG_SMP /* avoids "defined but not used" warnig */ static void flush_ldt(void *null) @@ -108,6 +109,11 @@ int init_new_context(struct task_struct *tsk, struct mm_struct *mm) retval = copy_ldt(&mm->context, &old_mm->context); up(&old_mm->context.sem); } + if (retval == 0) { + spin_lock(&mm_unpinned_lock); + list_add(&mm->context.unpinned, &mm_unpinned); + spin_unlock(&mm_unpinned_lock); + } return retval; } @@ -128,6 +134,9 @@ void destroy_context(struct mm_struct *mm) kfree(mm->context.ldt); mm->context.size = 0; } + spin_lock(&mm_unpinned_lock); + list_del(&mm->context.unpinned); + spin_unlock(&mm_unpinned_lock); } static int read_ldt(void __user * ptr, unsigned long bytecount) diff --git a/linux-2.6.11-xen-sparse/arch/xen/i386/mm/pgtable.c b/linux-2.6.11-xen-sparse/arch/xen/i386/mm/pgtable.c index 0215422a5a..f3756654c3 100644 --- a/linux-2.6.11-xen-sparse/arch/xen/i386/mm/pgtable.c +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/mm/pgtable.c @@ -408,6 +408,9 @@ void make_pages_writable(void *va, unsigned int nr) } #endif /* CONFIG_XEN_SHADOW_MODE */ +LIST_HEAD(mm_unpinned); +DEFINE_SPINLOCK(mm_unpinned_lock); + static inline void mm_walk_set_prot(void *pt, pgprot_t flags) { struct page *page = virt_to_page(pt); @@ -461,6 +464,9 @@ void mm_pin(struct mm_struct *mm) pfn_pte(virt_to_phys(mm->pgd)>>PAGE_SHIFT, PAGE_KERNEL_RO), 0); xen_pgd_pin(__pa(mm->pgd)); mm->context.pinned = 1; + spin_lock(&mm_unpinned_lock); + list_del(&mm->context.unpinned); + spin_unlock(&mm_unpinned_lock); spin_unlock(&mm->page_table_lock); } @@ -475,10 +481,20 @@ void mm_unpin(struct mm_struct *mm) pfn_pte(virt_to_phys(mm->pgd)>>PAGE_SHIFT, PAGE_KERNEL), 0); mm_walk(mm, PAGE_KERNEL); mm->context.pinned = 0; + spin_lock(&mm_unpinned_lock); + list_add(&mm->context.unpinned, &mm_unpinned); + spin_unlock(&mm_unpinned_lock); spin_unlock(&mm->page_table_lock); } +void mm_pin_all(void) +{ + while (!list_empty(&mm_unpinned)) + mm_pin(list_entry(mm_unpinned.next, struct mm_struct, + context.unpinned)); +} + void _arch_exit_mmap(struct mm_struct *mm) { struct task_struct *tsk = current; diff --git a/linux-2.6.11-xen-sparse/arch/xen/kernel/reboot.c b/linux-2.6.11-xen-sparse/arch/xen/kernel/reboot.c index 4e6dcf649d..62c8274895 100644 --- a/linux-2.6.11-xen-sparse/arch/xen/kernel/reboot.c +++ b/linux-2.6.11-xen-sparse/arch/xen/kernel/reboot.c @@ -103,6 +103,9 @@ static void __do_suspend(void) __cli(); + mm_pin_all(); + kmem_cache_shrink(pgd_cache); + netif_suspend(); blkdev_suspend(); diff --git a/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mmu.h b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mmu.h index 0e27763469..b628b46f3b 100644 --- a/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mmu.h +++ b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mmu.h @@ -13,8 +13,12 @@ typedef struct { struct semaphore sem; void *ldt; unsigned pinned:1; + struct list_head unpinned; } mm_context_t; +extern struct list_head mm_unpinned; +extern spinlock_t mm_unpinned_lock; + /* mm/memory.c:exit_mmap hook */ extern void _arch_exit_mmap(struct mm_struct *mm); #define arch_exit_mmap(_mm) _arch_exit_mmap(_mm) diff --git a/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mmu_context.h b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mmu_context.h index b1fe2fb594..f46144e37f 100644 --- a/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mmu_context.h +++ b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mmu_context.h @@ -43,6 +43,7 @@ static inline void __prepare_arch_switch(void) extern void mm_pin(struct mm_struct *mm); extern void mm_unpin(struct mm_struct *mm); +void mm_pin_all(void); static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, |