Index: head-2006-06-07/arch/i386/mm/pgtable-xen.c =================================================================== --- head-2006-06-07.orig/arch/i386/mm/pgtable-xen.c 2006-06-08 12:41:06.000000000 +0200 +++ head-2006-06-07/arch/i386/mm/pgtable-xen.c 2006-06-08 12:41:33.000000000 +0200 @@ -614,6 +614,12 @@ void mm_pin_all(void) } } +void _arch_dup_mmap(struct mm_struct *mm) +{ + if (!test_bit(PG_pinned, &virt_to_page(mm->pgd)->flags)) + mm_pin(mm); +} + void _arch_exit_mmap(struct mm_struct *mm) { struct task_struct *tsk = current; Index: head-2006-06-07/arch/x86_64/mm/pageattr-xen.c =================================================================== --- head-2006-06-07.orig/arch/x86_64/mm/pageattr-xen.c 2006-06-08 12:41:06.000000000 +0200 +++ head-2006-06-07/arch/x86_64/mm/pageattr-xen.c 2006-06-08 12:41:33.000000000 +0200 @@ -130,6 +130,12 @@ void mm_pin_all(void) context.unpinned)); } +void _arch_dup_mmap(struct mm_struct *mm) +{ + if (!mm->context.pinned) + mm_pin(mm); +} + void _arch_exit_mmap(struct mm_struct *mm) { struct task_struct *tsk = current; Index: head-2006-06-07/include/asm-i386/mach-xen/asm/mmu.h =================================================================== --- head-2006-06-07.orig/include/asm-i386/mach-xen/asm/mmu.h 2006-06-08 12:41:06.000000000 +0200 +++ head-2006-06-07/include/asm-i386/mach-xen/asm/mmu.h 2006-06-08 12:41:33.000000000 +0200 @@ -18,4 +18,8 @@ typedef struct { extern void _arch_exit_mmap(struct mm_struct *mm); #define arch_exit_mmap(_mm) _arch_exit_mmap(_mm) +/* kernel/fork.c:dup_mmap hook */ +extern void _arch_dup_mmap(struct mm_struct *mm); +#define arch_dup_mmap(mm, oldmm) ((void)(oldmm), _arch_dup_mmap(mm)) + #endif Index: head-2006-06-07/include/asm-i386/mach-xen/asm/mmu_context.h =================================================================== --- head-2006-06-07.orig/include/asm-i386/mach-xen/asm/mmu_context.h 2006-06-08 12:41:06.000000000 +0200 +++ head-2006-06-07/include/asm-i386/mach-xen/asm/mmu_context.h 2006-06-08 12:41:33.000000000 +0200 @@ -51,8 +51,7 @@ static inline void switch_mm(struct mm_s struct mmuext_op _op[2], *op = _op; if (likely(prev != next)) { - if (!test_bit(PG_pinned, &virt_to_page(next->pgd)->flags)) - mm_pin(next); + BUG_ON(!test_bit(PG_pinned, &virt_to_page(next->pgd)->flags)); /* stop flush ipis for the previous mm */ cpu_clear(cpu, prev->cpu_vm_mask); @@ -99,7 +98,11 @@ static inline void switch_mm(struct mm_s #define deactivate_mm(tsk, mm) \ asm("movl %0,%%fs ; movl %0,%%gs": :"r" (0)) -#define activate_mm(prev, next) \ - switch_mm((prev),(next),NULL) +static inline void activate_mm(struct mm_struct *prev, struct mm_struct *next) +{ + if (!test_bit(PG_pinned, &virt_to_page(next->pgd)->flags)) + mm_pin(next); + switch_mm(prev, next, NULL); +} #endif Index: head-2006-06-07/include/asm-x86_64/mach-xen/asm/mmu.h =================================================================== --- head-2006-06-07.orig/include/asm-x86_64/mach-xen/asm/mmu.h 2006-06-08 12:41:06.000000000 +0200 +++ head-2006-06-07/include/asm-x86_64/mach-xen/asm/mmu.h 2006-06-08 12:41:33.000000000 +0200 @@ -28,6 +28,10 @@ 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) + +/* kernel/fork.c:dup_mmap hook */ +extern void _arch_dup_mmap(struct mm_struct *mm); +#define arch_dup_mmap(mm, oldmm) ((void)(oldmm), _arch_dup_mmap(mm)) #endif #endif Index: head-2006-06-07/include/asm-x86_64/mach-xen/asm/mmu_context.h =================================================================== --- head-2006-06-07.orig/include/asm-x86_64/mach-xen/asm/mmu_context.h 2006-06-08 12:41:06.000000000 +0200 +++ head-2006-06-07/include/asm-x86_64/mach-xen/asm/mmu_context.h 2006-06-08 12:41:33.000000000 +0200 @@ -73,8 +73,7 @@ static inline void switch_mm(struct mm_s struct mmuext_op _op[3], *op = _op; if (likely(prev != next)) { - if (!next->context.pinned) - mm_pin(next); + BUG_ON(!next->context.pinned); /* stop flush ipis for the previous mm */ clear_bit(cpu, &prev->cpu_vm_mask); @@ -127,8 +126,11 @@ static inline void switch_mm(struct mm_s asm volatile("movl %0,%%fs"::"r"(0)); \ } while(0) -#define activate_mm(prev, next) do { \ - switch_mm((prev),(next),NULL); \ -} while (0) +static inline void activate_mm(struct mm_struct *prev, struct mm_struct *next) +{ + if (!next->context.pinned) + mm_pin(next); + switch_mm(prev, next, NULL); +} #endif Index: head-2006-06-07/kernel/fork.c =================================================================== --- head-2006-06-07.orig/kernel/fork.c 2006-06-08 12:41:06.000000000 +0200 +++ head-2006-06-07/kernel/fork.c 2006-06-08 12:41:33.000000000 +0200 @@ -280,6 +280,9 @@ static inline int dup_mmap(struct mm_str if (retval) goto out; } +#ifdef arch_dup_mmap + arch_dup_mmap(mm, oldmm); +#endif retval = 0; out: up_write(&mm->mmap_sem);