aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>2005-06-02 07:56:31 +0000
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>2005-06-02 07:56:31 +0000
commitf7e5e27947fc992c6a4a0b832d2e168a0c088db7 (patch)
tree847d239dc419f2439185d4f2f9b2a3e499119812
parent2f7ddb37506671e2a64a1af8050d48e5b3057ea3 (diff)
parentf3925909949960e1d7c11f15ddb99589e7dd3f59 (diff)
downloadxen-f7e5e27947fc992c6a4a0b832d2e168a0c088db7.tar.gz
xen-f7e5e27947fc992c6a4a0b832d2e168a0c088db7.tar.bz2
xen-f7e5e27947fc992c6a4a0b832d2e168a0c088db7.zip
bitkeeper revision 1.1631 (429ebbaffap59sNVOihMG1SP6ejcrg)
Merge firebug.cl.cam.ac.uk:/auto/groups/xeno-xenod/BK/xen-unstable.bk into firebug.cl.cam.ac.uk:/local/scratch/kaf24/xen-unstable.bk
-rw-r--r--linux-2.6.11-xen-sparse/arch/xen/i386/kernel/ldt.c9
-rw-r--r--linux-2.6.11-xen-sparse/arch/xen/i386/mm/pgtable.c16
-rw-r--r--linux-2.6.11-xen-sparse/arch/xen/kernel/reboot.c3
-rw-r--r--linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mmu.h4
-rw-r--r--linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mmu_context.h1
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,