aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkfraser@localhost.localdomain <kfraser@localhost.localdomain>2006-08-01 15:48:48 +0100
committerkfraser@localhost.localdomain <kfraser@localhost.localdomain>2006-08-01 15:48:48 +0100
commit177155de98343fa322fd0e3f6d1c05315aaa3f74 (patch)
tree82577c67409d80a3f630be6b02f2b186f66e9b94
parent5dd83c7e6d9eb830707ff31702f3f09a4a22a260 (diff)
downloadxen-177155de98343fa322fd0e3f6d1c05315aaa3f74.tar.gz
xen-177155de98343fa322fd0e3f6d1c05315aaa3f74.tar.bz2
xen-177155de98343fa322fd0e3f6d1c05315aaa3f74.zip
[LINUX] Do not early-unpin pagetables that contain foreign mappings.
This fixes a bug whereby foreign pages were freed by the unpin, which then become owned by the local domain before it destroys its ptes. It therefore (erroneously) detects the mappings as local and so updates reference counts, leading to crashes. Signed-off-by: Keir Fraser <keir@xensource.com>
-rw-r--r--linux-2.6-xen-sparse/arch/i386/kernel/ldt-xen.c1
-rw-r--r--linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c2
-rw-r--r--linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c3
-rw-r--r--linux-2.6-xen-sparse/arch/x86_64/mm/pageattr-xen.c3
-rw-r--r--linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/mmu.h3
-rw-r--r--linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/mmu.h1
6 files changed, 11 insertions, 2 deletions
diff --git a/linux-2.6-xen-sparse/arch/i386/kernel/ldt-xen.c b/linux-2.6-xen-sparse/arch/i386/kernel/ldt-xen.c
index 06970d9517..d2cceffbb1 100644
--- a/linux-2.6-xen-sparse/arch/i386/kernel/ldt-xen.c
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/ldt-xen.c
@@ -109,6 +109,7 @@ int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
init_MUTEX(&mm->context.sem);
mm->context.size = 0;
+ mm->context.has_foreign_mappings = 0;
old_mm = current->mm;
if (old_mm && old_mm->context.size > 0) {
down(&old_mm->context.sem);
diff --git a/linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c b/linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c
index 1de992b228..3438269705 100644
--- a/linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c
+++ b/linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c
@@ -126,6 +126,8 @@ int direct_remap_pfn_range(struct vm_area_struct *vma,
if (domid == DOMID_SELF)
return -EINVAL;
+ vma->vm_mm->context.has_foreign_mappings = 1;
+
return __direct_remap_pfn_range(
vma->vm_mm, address, mfn, size, prot, domid);
}
diff --git a/linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c b/linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c
index a551252c71..843c9d0fd3 100644
--- a/linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c
+++ b/linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c
@@ -694,6 +694,7 @@ void _arch_exit_mmap(struct mm_struct *mm)
task_unlock(tsk);
if (test_bit(PG_pinned, &virt_to_page(mm->pgd)->flags) &&
- (atomic_read(&mm->mm_count) == 1))
+ (atomic_read(&mm->mm_count) == 1) &&
+ !mm->context.has_foreign_mappings)
mm_unpin(mm);
}
diff --git a/linux-2.6-xen-sparse/arch/x86_64/mm/pageattr-xen.c b/linux-2.6-xen-sparse/arch/x86_64/mm/pageattr-xen.c
index 721c47b1fd..3641bfb805 100644
--- a/linux-2.6-xen-sparse/arch/x86_64/mm/pageattr-xen.c
+++ b/linux-2.6-xen-sparse/arch/x86_64/mm/pageattr-xen.c
@@ -159,7 +159,8 @@ void _arch_exit_mmap(struct mm_struct *mm)
task_unlock(tsk);
- if ( mm->context.pinned && (atomic_read(&mm->mm_count) == 1) )
+ if ( mm->context.pinned && (atomic_read(&mm->mm_count) == 1) &&
+ !mm->context.has_foreign_mappings )
mm_unpin(mm);
}
diff --git a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/mmu.h b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/mmu.h
index cba1785e39..139e54a9be 100644
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/mmu.h
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/mmu.h
@@ -12,6 +12,9 @@ typedef struct {
int size;
struct semaphore sem;
void *ldt;
+#ifdef CONFIG_XEN
+ int has_foreign_mappings;
+#endif
} mm_context_t;
/* mm/memory.c:exit_mmap hook */
diff --git a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/mmu.h b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/mmu.h
index f95e8d5d79..2ac8252954 100644
--- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/mmu.h
+++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/mmu.h
@@ -17,6 +17,7 @@ typedef struct {
struct semaphore sem;
#ifdef CONFIG_XEN
unsigned pinned:1;
+ unsigned has_foreign_mappings:1;
struct list_head unpinned;
#endif
} mm_context_t;