[Pkg-uml-commit] r167 - in trunk/src: . kernel-patch-skas linux-patch-skas linux-patch-skas/debian

Mattia Dongili malattia at costa.debian.org
Sun Aug 27 15:17:05 UTC 2006


Author: malattia
Date: 2006-08-27 15:16:57 +0000 (Sun, 27 Aug 2006)
New Revision: 167

Added:
   trunk/src/linux-patch-skas/
   trunk/src/linux-patch-skas/debian/
   trunk/src/linux-patch-skas/debian/changelog
   trunk/src/linux-patch-skas/debian/control
   trunk/src/linux-patch-skas/debian/patches/
   trunk/src/linux-patch-skas/debian/rules
   trunk/src/linux-patch-skas/host-skas3-2.4.25-v3.patch
   trunk/src/linux-patch-skas/host-skas3-2.6.3-v1.patch
   trunk/src/linux-patch-skas/host-skas3-2.6.6-v1.patch
   trunk/src/linux-patch-skas/host-skas3-2.6.7-v1.patch
   trunk/src/linux-patch-skas/host-skas3-2.6.8-v6.patch
   trunk/src/linux-patch-skas/host-skas3-2.6.9-v7.patch
   trunk/src/linux-patch-skas/host-skas3.patch
   trunk/src/linux-patch-skas/skas-2.6.10-v8.patch
   trunk/src/linux-patch-skas/skas-2.6.11-v8.2.patch
   trunk/src/linux-patch-skas/skas-2.6.12-v9-pre7.patch
   trunk/src/linux-patch-skas/skas-2.6.13-rc7-v9-pre7.patch
   trunk/src/linux-patch-skas/skas-2.6.14-v9-pre7.patch
   trunk/src/linux-patch-skas/skas-2.6.15-v9-pre8.patch
   trunk/src/linux-patch-skas/skas-2.6.16-v9-pre9.patch
   trunk/src/linux-patch-skas/skas-2.6.17-rc5-v9-pre9.patch
Removed:
   trunk/src/kernel-patch-skas/host-skas3-2.4.25-v3.patch
   trunk/src/kernel-patch-skas/host-skas3-2.6.3-v1.patch
   trunk/src/kernel-patch-skas/host-skas3-2.6.6-v1.patch
   trunk/src/kernel-patch-skas/host-skas3-2.6.7-v1.patch
   trunk/src/kernel-patch-skas/host-skas3-2.6.8-v6.patch
   trunk/src/kernel-patch-skas/host-skas3-2.6.9-v7.patch
   trunk/src/kernel-patch-skas/host-skas3.patch
   trunk/src/kernel-patch-skas/skas-2.6.10-v8.patch
   trunk/src/kernel-patch-skas/skas-2.6.11-v8.2.patch
   trunk/src/kernel-patch-skas/skas-2.6.12-v9-pre7.patch
   trunk/src/kernel-patch-skas/skas-2.6.13-rc7-v9-pre7.patch
   trunk/src/kernel-patch-skas/skas-2.6.14-v9-pre7.patch
   trunk/src/kernel-patch-skas/skas-2.6.15-v9-pre8.patch
   trunk/src/kernel-patch-skas/skas-2.6.16-v9-pre9.patch
   trunk/src/kernel-patch-skas/skas-2.6.17-rc5-v9-pre9.patch
   trunk/src/linux-patch-skas/debian/changelog
   trunk/src/linux-patch-skas/debian/control
   trunk/src/linux-patch-skas/debian/rules
Log:
prepare structure for the new linux-patch-skas and the empty kernel-patch-skas

Deleted: trunk/src/kernel-patch-skas/host-skas3-2.4.25-v3.patch
===================================================================
--- trunk/src/kernel-patch-skas/host-skas3-2.4.25-v3.patch	2006-08-27 15:01:30 UTC (rev 166)
+++ trunk/src/kernel-patch-skas/host-skas3-2.4.25-v3.patch	2006-08-27 15:16:57 UTC (rev 167)
@@ -1,801 +0,0 @@
---- linux-2.4.25-paolo/arch/i386/kernel/ldt.c	2004-09-11 19:25:37.632440992 +0200
-+++ linux-2.4.25-paolo/arch/i386/kernel/ldt.c	2004-08-29 17:21:52.276721288 +0200
-@@ -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 *mm)
-@@ -53,7 +54,7 @@
- 	wmb();
- 	pc->ldt = newldt;
- 	pc->size = mincount;
--	if (reload) {
-+	if (reload && (&current->active_mm->context == pc)) {
- 		load_LDT(pc);
- #ifdef CONFIG_SMP
- 		if (current->mm->cpu_vm_mask != (1<<smp_processor_id()))
-@@ -86,6 +87,12 @@
-  * we do not have to muck with descriptors here, that is
-  * done in switch_mm() as needed.
-  */
-+void init_new_empty_context(struct mm_struct *mm)
-+{
-+	init_MUTEX(&mm->context.sem);
-+	mm->context.size = 0;
-+}
-+
- int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
- {
- 	struct mm_struct * old_mm;
-@@ -102,6 +109,26 @@
- 	return retval;
- }
- 
-+int copy_context(struct mm_struct *mm, struct mm_struct *old_mm)
-+{
-+	int err = 0;
-+	mm_context_t *new, *old;
-+	new = &mm->context;
-+	old = &old_mm->context;
-+	if (old_mm && old_mm->context.size > 0) {
-+		down(&old_mm->context.sem);
-+		err = alloc_ldt(new, old->size, 0);
-+		if (err < 0) {
-+			up(&old_mm->context.sem);
-+			goto out;
-+		}
-+		memcpy(new->ldt, old->ldt, old->size*LDT_ENTRY_SIZE);
-+		up(&old_mm->context.sem);
-+	}
-+out:
-+	return err;
-+}
-+
- /*
-  * No need to lock the MM as we are the last user
-  * Do not touch the ldt register, we are already
-@@ -118,11 +145,10 @@
- 	}
- }
- 
--static int read_ldt(void * ptr, unsigned long bytecount)
-+static int read_ldt(struct mm_struct * mm, void * ptr, unsigned long bytecount)
- {
- 	int err;
- 	unsigned long size;
--	struct mm_struct * mm = current->mm;
- 
- 	if (!mm->context.size)
- 		return 0;
-@@ -166,9 +192,8 @@
- 	return err;
- }
- 
--static int write_ldt(void * ptr, unsigned long bytecount, int oldmode)
-+static int write_ldt(struct mm_struct * mm, void * ptr, unsigned long bytecount, int oldmode)
- {
--	struct mm_struct * mm = current->mm;
- 	__u32 entry_1, entry_2, *lp;
- 	int error;
- 	struct modify_ldt_ldt_s ldt_info;
-@@ -192,7 +217,7 @@
- 
- 	down(&mm->context.sem);
- 	if (ldt_info.entry_number >= mm->context.size) {
--		error = alloc_ldt(&current->mm->context, ldt_info.entry_number+1, 1);
-+		error = alloc_ldt(&mm->context, ldt_info.entry_number+1, 1);
- 		if (error < 0)
- 			goto out_unlock;
- 	}
-@@ -243,20 +268,24 @@
--asmlinkage int sys_modify_ldt(int func, void *ptr, unsigned long bytecount)
-+int modify_ldt(struct mm_struct * mm, int func, void *ptr, unsigned long bytecount)
- {
- 	int ret = -ENOSYS;
- 
- 	switch (func) {
- 	case 0:
--		ret = read_ldt(ptr, bytecount);
-+		ret = read_ldt(mm, ptr, bytecount);
- 		break;
- 	case 1:
--		ret = write_ldt(ptr, bytecount, 1);
-+		ret = write_ldt(mm, ptr, bytecount, 1);
- 		break;
- 	case 2:
- 		ret = read_default_ldt(ptr, bytecount);
- 		break;
- 	case 0x11:
--		ret = write_ldt(ptr, bytecount, 0);
-+		ret = write_ldt(mm, ptr, bytecount, 0);
- 		break;
- 	}
- 	return ret;
- }
-+
-+asmlinkage int sys_modify_ldt(int func, void *ptr, unsigned long bytecount) {
-+	return modify_ldt(current->mm, func, ptr, bytecount);
-+}
---- linux-2.4.25-paolo/arch/i386/kernel/ptrace.c	2004-08-29 17:21:51.920775400 +0200
-+++ linux-2.4.25-paolo/arch/i386/kernel/ptrace.c	2004-08-29 17:21:52.616669608 +0200
-@@ -147,6 +147,11 @@
- 	put_stack_long(child, EFL_OFFSET, tmp);
- }
- 
-+extern int modify_ldt(struct mm_struct *mm, int func, void *ptr,
-+		      unsigned long bytecount);
-+
-+extern struct mm_struct *proc_mm_get_mm(int fd);
-+
- asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
- {
- 	struct task_struct *child;
-@@ -270,6 +275,7 @@
- 		  }
- 		  break;
- 
-+	case PTRACE_SYSEMU: /* continue and replace next syscall */
- 	case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
- 	case PTRACE_CONT: { /* restart after signal. */
- 		long tmp;
-@@ -277,6 +283,10 @@
- 		ret = -EIO;
- 		if ((unsigned long) data > _NSIG)
- 			break;
-+		if (request == PTRACE_SYSEMU)
-+			child->ptrace |= PT_SYSEMU;
-+		else
-+			child->ptrace &= ~PT_SYSEMU;
- 		if (request == PTRACE_SYSCALL)
- 			child->ptrace |= PT_TRACESYS;
- 		else
-@@ -315,7 +325,7 @@
- 		ret = -EIO;
- 		if ((unsigned long) data > _NSIG)
- 			break;
--		child->ptrace &= ~PT_TRACESYS;
-+		child->ptrace &= ~(PT_TRACESYS|PT_SYSEMU);
- 		if ((child->ptrace & PT_DTRACE) == 0) {
- 			/* Spurious delayed TF traps may occur */
- 			child->ptrace |= PT_DTRACE;
-@@ -419,6 +429,53 @@
- 		break;
- 	}
- 
-+	case PTRACE_FAULTINFO: {
-+		struct ptrace_faultinfo fault;
-+
-+		fault = ((struct ptrace_faultinfo)
-+			{ .is_write	= child->thread.error_code,
-+			  .addr		= child->thread.cr2 });
-+		ret = copy_to_user((unsigned long *) data, &fault,
-+				   sizeof(fault));
-+		break;
-+	}
-+	case PTRACE_SIGPENDING:
-+		ret = copy_to_user((unsigned long *) data,
-+				   &child->pending.signal,
-+				   sizeof(child->pending.signal));
-+		break;
-+
-+	case PTRACE_LDT: {
-+		struct ptrace_ldt ldt;
-+
-+		if(copy_from_user(&ldt, (unsigned long *) data,
-+				  sizeof(ldt))){
-+			ret = -EIO;
-+			break;
-+		}
-+		ret = modify_ldt(child->mm, ldt.func, ldt.ptr, ldt.bytecount);
-+		break;
-+	}
-+
-+#if 1 /* CONFIG_PROC_MM*/
-+	case PTRACE_SWITCH_MM: {
-+		struct mm_struct *old = child->mm;
-+		struct mm_struct *new = proc_mm_get_mm(data);
-+
-+		if(IS_ERR(new)){
-+			ret = PTR_ERR(new);
-+			break;
-+		}
-+
-+		atomic_inc(&new->mm_users);
-+		child->mm = new;
-+		child->active_mm = new;
-+		mmput(old);
-+		ret = 0;
-+		break;
-+	}
-+#endif
-+
- 	default:
- 		ret = -EIO;
- 		break;
-@@ -430,6 +487,29 @@
- 	return ret;
- }
- 
-+asmlinkage void syscall_emulate(void)
-+{
-+	if ((current->ptrace & (PT_PTRACED|PT_SYSEMU)) !=
-+			(PT_PTRACED|PT_SYSEMU))
-+		return;
-+	/* the 0x80 provides a way for the tracing parent to distinguish
-+	   between a syscall stop and SIGTRAP delivery */
-+	current->exit_code = SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
-+					? 0x80 : 0);
-+	current->state = TASK_STOPPED;
-+	notify_parent(current, SIGCHLD);
-+	schedule();
-+	/*
-+	 * this isn't the same as continuing with a signal, but it will do
-+	 * for normal use.  strace only continues with a signal if the
-+	 * stopping signal is not SIGTRAP.  -brl
-+	 */
-+	if (current->exit_code) {
-+		send_sig(current->exit_code, current, 1);
-+		current->exit_code = 0;
-+	}
-+}
-+
- asmlinkage void syscall_trace(void)
- {
- 	if ((current->ptrace & (PT_PTRACED|PT_TRACESYS)) !=
---- linux-2.4.25/arch/i386/kernel/sys_i386.c~host-skas3-2.4.25-no_CONFIG	2004-08-29 17:21:51.100900040 +0200
-+++ linux-2.4.25-paolo/arch/i386/kernel/sys_i386.c	2004-08-29 17:21:51.111898368 +0200
-@@ -40,7 +40,7 @@ asmlinkage int sys_pipe(unsigned long * 
- }
- 
- /* common code for old and new mmaps */
--static inline long do_mmap2(
-+long do_mmap2(struct mm_struct *mm,
- 	unsigned long addr, unsigned long len,
- 	unsigned long prot, unsigned long flags,
- 	unsigned long fd, unsigned long pgoff)
-@@ -55,9 +55,9 @@ static inline long do_mmap2(
- 			goto out;
- 	}
- 
--	down_write(&current->mm->mmap_sem);
--	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
--	up_write(&current->mm->mmap_sem);
-+	down_write(&mm->mmap_sem);
-+	error = do_mmap_pgoff(mm, file, addr, len, prot, flags, pgoff);
-+	up_write(&mm->mmap_sem);
- 
- 	if (file)
- 		fput(file);
-@@ -69,7 +69,7 @@ asmlinkage long sys_mmap2(unsigned long 
- 	unsigned long prot, unsigned long flags,
- 	unsigned long fd, unsigned long pgoff)
- {
--	return do_mmap2(addr, len, prot, flags, fd, pgoff);
-+	return do_mmap2(current->mm, addr, len, prot, flags, fd, pgoff);
- }
- 
- /*
-@@ -100,7 +100,7 @@ asmlinkage int old_mmap(struct mmap_arg_
- 	if (a.offset & ~PAGE_MASK)
- 		goto out;
- 
--	err = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
-+	err = do_mmap2(current->mm, a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
- out:
- 	return err;
- }
---- linux-2.4.25/include/asm-i386/processor.h~host-skas3-2.4.25-no_CONFIG	2004-08-29 17:21:51.101899888 +0200
-+++ linux-2.4.25-paolo/include/asm-i386/processor.h	2004-08-29 17:21:51.111898368 +0200
-@@ -433,6 +433,8 @@ extern int arch_kernel_thread(int (*fn)(
- static inline void copy_segments(struct task_struct *p, struct mm_struct * mm) { }
- static inline void release_segments(struct mm_struct * mm) { }
- 
-+extern int __init_new_context(struct mm_struct *old_mm, struct mm_struct *mm);
-+
- /*
-  * Return saved PC of a blocked thread.
-  */
---- linux-2.4.25/include/asm-i386/ptrace.h~host-skas3-2.4.25-no_CONFIG	2004-08-29 17:21:51.102899736 +0200
-+++ linux-2.4.25-paolo/include/asm-i386/ptrace.h	2004-08-29 17:21:51.111898368 +0200
-@@ -51,6 +51,22 @@ struct pt_regs {
- 
- #define PTRACE_SETOPTIONS         21
- 
-+struct ptrace_faultinfo {
-+	int is_write;
-+	unsigned long addr;
-+};
-+
-+struct ptrace_ldt {
-+	int func;
-+  	void *ptr;
-+	unsigned long bytecount;
-+};
-+
-+#define PTRACE_FAULTINFO 52
-+#define PTRACE_SIGPENDING 53
-+#define PTRACE_LDT 54
-+#define PTRACE_SWITCH_MM 55
-+
- /* options set using PTRACE_SETOPTIONS */
- #define PTRACE_O_TRACESYSGOOD     0x00000001
- 
---- linux-2.4.25/include/linux/mm.h~host-skas3-2.4.25-no_CONFIG	2004-08-29 17:21:51.103899584 +0200
-+++ linux-2.4.25-paolo/include/linux/mm.h	2004-08-29 17:21:51.112898216 +0200
-@@ -505,6 +505,9 @@ extern int ptrace_check_attach(struct ta
- int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, unsigned long start,
- 		int len, int write, int force, struct page **pages, struct vm_area_struct **vmas);
- 
-+extern long do_mprotect(struct mm_struct *mm, unsigned long start,
-+			size_t len, unsigned long prot);
-+
- /*
-  * On a two-level page table, this ends up being trivial. Thus the
-  * inlining and the symmetry break with pte_alloc() that does all
-@@ -552,9 +555,10 @@ extern void exit_mmap(struct mm_struct *
- 
- extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
- 
--extern unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
--	unsigned long len, unsigned long prot,
--	unsigned long flag, unsigned long pgoff);
-+extern unsigned long do_mmap_pgoff(struct mm_struct *mm,
-+				   struct file *file, unsigned long addr,
-+				   unsigned long len, unsigned long prot,
-+				   unsigned long flag, unsigned long pgoff);
- 
- static inline unsigned long do_mmap(struct file *file, unsigned long addr,
- 	unsigned long len, unsigned long prot,
-@@ -564,7 +568,7 @@ static inline unsigned long do_mmap(stru
- 	if ((offset + PAGE_ALIGN(len)) < offset)
- 		goto out;
- 	if (!(offset & ~PAGE_MASK))
--		ret = do_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT);
-+		ret = do_mmap_pgoff(current->mm, file, addr, len, prot, flag, offset >> PAGE_SHIFT);
- out:
- 	return ret;
- }
---- /dev/null	2004-06-25 17:47:25.000000000 +0200
-+++ linux-2.4.25-paolo/include/linux/proc_mm.h	2004-08-29 17:21:51.112898216 +0200
-@@ -0,0 +1,44 @@
-+/*
-+ * Copyright (C) 2002 Jeff Dike (jdike at karaya.com)
-+ * Licensed under the GPL
-+ */
-+
-+#ifndef __PROC_MM_H
-+#define __PROC_MM_H
-+
-+#define MM_MMAP 54
-+#define MM_MUNMAP 55
-+#define MM_MPROTECT 56
-+#define MM_COPY_SEGMENTS 57
-+
-+struct mm_mmap {
-+	unsigned long addr;
-+	unsigned long len;
-+	unsigned long prot;
-+	unsigned long flags;
-+	unsigned long fd;
-+	unsigned long offset;
-+};
-+
-+struct mm_munmap {
-+	unsigned long addr;
-+	unsigned long len;
-+};
-+
-+struct mm_mprotect {
-+	unsigned long addr;
-+	unsigned long len;
-+        unsigned int prot;
-+};
-+
-+struct proc_mm_op {
-+	int op;
-+	union {
-+		struct mm_mmap mmap;
-+		struct mm_munmap munmap;
-+	        struct mm_mprotect mprotect;
-+		int copy_segments;
-+	} u;
-+};
-+
-+#endif
---- linux-2.4.25/mm/Makefile~host-skas3-2.4.25-no_CONFIG	2004-08-29 17:21:51.105899280 +0200
-+++ linux-2.4.25-paolo/mm/Makefile	2004-08-29 17:21:51.112898216 +0200
-@@ -17,5 +17,6 @@ obj-y	 := memory.o mmap.o filemap.o mpro
- 	    shmem.o
- 
- obj-$(CONFIG_HIGHMEM) += highmem.o
-+obj-y += proc_mm.o
- 
- include $(TOPDIR)/Rules.make
---- linux-2.4.25/mm/mmap.c~host-skas3-2.4.25-no_CONFIG	2004-08-29 17:21:51.106899128 +0200
-+++ linux-2.4.25-paolo/mm/mmap.c	2004-08-29 17:21:51.112898216 +0200
-@@ -391,10 +391,11 @@ static int vma_merge(struct mm_struct * 
- 	return 0;
- }
- 
--unsigned long do_mmap_pgoff(struct file * file, unsigned long addr, unsigned long len,
--	unsigned long prot, unsigned long flags, unsigned long pgoff)
-+unsigned long do_mmap_pgoff(struct mm_struct *mm, struct file * file,
-+			    unsigned long addr, unsigned long len,
-+			    unsigned long prot, unsigned long flags,
-+			    unsigned long pgoff)
- {
--	struct mm_struct * mm = current->mm;
- 	struct vm_area_struct * vma, * prev;
- 	unsigned int vm_flags;
- 	int correct_wcount = 0;
---- linux-2.4.25-paolo/mm/mprotect.c	2004-08-29 17:21:51.113898064 +0200
-+++ linux-2.4.25-paolo/mm/mprotect.c	2004-08-29 17:21:52.974615192 +0200
-@@ -71,23 +71,24 @@
- 	} while (address && (address < end));
- }
- 
--static void change_protection(unsigned long start, unsigned long end, pgprot_t newprot)
-+static void change_protection(struct mm_struct *mm,
-+	unsigned long start, unsigned long end, pgprot_t newprot)
- {
- 	pgd_t *dir;
- 	unsigned long beg = start;
- 
--	dir = pgd_offset(current->mm, start);
--	flush_cache_range(current->mm, beg, end);
-+	dir = pgd_offset(mm, start);
-+	flush_cache_range(mm, beg, end);
- 	if (start >= end)
- 		BUG();
--	spin_lock(&current->mm->page_table_lock);
-+	spin_lock(&mm->page_table_lock);
- 	do {
- 		change_pmd_range(dir, start, end - start, newprot);
- 		start = (start + PGDIR_SIZE) & PGDIR_MASK;
- 		dir++;
- 	} while (start && (start < end));
--	spin_unlock(&current->mm->page_table_lock);
--	flush_tlb_range(current->mm, beg, end);
-+	spin_unlock(&mm->page_table_lock);
-+	flush_tlb_range(mm, beg, end);
- 	return;
- }
- 
-@@ -125,6 +126,7 @@
- 	int newflags, pgprot_t prot)
- {
- 	struct vm_area_struct * n, * prev = *pprev;
-+	struct mm_struct * mm = vma->vm_mm;
- 
- 	*pprev = vma;
- 
-@@ -153,7 +155,7 @@
- 	lock_vma_mappings(vma);
- 	spin_lock(&vma->vm_mm->page_table_lock);
- 	vma->vm_start = end;
--	__insert_vm_struct(current->mm, n);
-+	__insert_vm_struct(mm, n);
- 	spin_unlock(&vma->vm_mm->page_table_lock);
- 	unlock_vma_mappings(vma);
- 
-@@ -165,6 +167,7 @@
- 	int newflags, pgprot_t prot)
- {
- 	struct vm_area_struct * n;
-+	struct mm_struct * mm = vma->vm_mm;
- 
- 	n = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
- 	if (!n)
-@@ -182,7 +185,7 @@
- 	lock_vma_mappings(vma);
- 	spin_lock(&vma->vm_mm->page_table_lock);
- 	vma->vm_end = start;
--	__insert_vm_struct(current->mm, n);
-+	__insert_vm_struct(mm, n);
- 	spin_unlock(&vma->vm_mm->page_table_lock);
- 	unlock_vma_mappings(vma);
- 
-@@ -196,6 +199,7 @@
- 	int newflags, pgprot_t prot)
- {
- 	struct vm_area_struct * left, * right;
-+	struct mm_struct * mm = vma->vm_mm;
- 
- 	left = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
- 	if (!left)
-@@ -226,8 +230,8 @@
- 	vma->vm_start = start;
- 	vma->vm_end = end;
- 	vma->vm_flags = newflags;
--	__insert_vm_struct(current->mm, left);
--	__insert_vm_struct(current->mm, right);
-+	__insert_vm_struct(mm, left);
-+	__insert_vm_struct(mm, right);
- 	spin_unlock(&vma->vm_mm->page_table_lock);
- 	unlock_vma_mappings(vma);
- 
-@@ -241,6 +245,7 @@
- {
- 	pgprot_t newprot;
- 	int error;
-+	struct mm_struct * mm = vma->vm_mm;
- 
- 	if (newflags == vma->vm_flags) {
- 		*pprev = vma;
-@@ -260,11 +265,12 @@
- 	if (error)
- 		return error;
- 
--	change_protection(start, end, newprot);
-+	change_protection(mm, start, end, newprot);
- 	return 0;
- }
- 
--asmlinkage long sys_mprotect(unsigned long start, size_t len, unsigned long prot)
-+long do_mprotect(struct mm_struct *mm, unsigned long start, size_t len,
-+		 unsigned long prot)
- {
- 	unsigned long nstart, end, tmp;
- 	struct vm_area_struct * vma, * next, * prev;
-@@ -281,9 +287,9 @@
- 	if (end == start)
- 		return 0;
- 
--	down_write(&current->mm->mmap_sem);
-+	down_write(&mm->mmap_sem);
- 
--	vma = find_vma_prev(current->mm, start, &prev);
-+	vma = find_vma_prev(mm, start, &prev);
- 	error = -ENOMEM;
- 	if (!vma || vma->vm_start > start)
- 		goto out;
-@@ -335,3 +341,8 @@
--	up_write(&current->mm->mmap_sem);
-+	up_write(&mm->mmap_sem);
- 	return error;
- }
-+
-+asmlinkage long sys_mprotect(unsigned long start, size_t len, unsigned long prot)
-+{
-+	return(do_mprotect(current->mm, start, len, prot));
-+}
---- linux-2.4.25-paolo/mm/proc_mm.c	2004-08-29 17:21:52.277721136 +0200
-+++ linux-2.4.25-paolo/mm/proc_mm.c	2004-08-29 17:21:52.974615192 +0200
-@@ -0,0 +1,181 @@
-+/*
-+ * Copyright (C) 2002 Jeff Dike (jdike at karaya.com)
-+ * Licensed under the GPL
-+ */
-+
-+#include "linux/proc_fs.h"
-+#include "linux/proc_mm.h"
-+#include "linux/file.h"
-+#include "linux/mman.h"
-+#include "asm/uaccess.h"
-+#include "asm/mmu_context.h"
-+
-+static struct file_operations proc_mm_fops;
-+
-+struct mm_struct *proc_mm_get_mm(int fd)
-+{
-+	struct mm_struct *ret = ERR_PTR(-EBADF);
-+	struct file *file;
-+
-+	file = fget(fd);
-+	if (!file)
-+		goto out;
-+
-+	ret = ERR_PTR(-EINVAL);
-+	if(file->f_op != &proc_mm_fops)
-+		goto out_fput;
-+
-+	ret = file->private_data;
-+
-+ out_fput:
-+	fput(file);
-+ out:
-+	return(ret);
-+}
-+
-+extern long do_mmap2(struct mm_struct *mm, unsigned long addr,
-+		     unsigned long len, unsigned long prot,
-+		     unsigned long flags, unsigned long fd,
-+		     unsigned long pgoff);
-+
-+static ssize_t write_proc_mm(struct file *file, const char *buffer,
-+			     size_t count, loff_t *ppos)
-+{
-+	struct mm_struct *mm = file->private_data;
-+	struct proc_mm_op req;
-+	int n, ret;
-+
-+	if(count > sizeof(req))
-+		return(-EINVAL);
-+
-+	n = copy_from_user(&req, buffer, count);
-+	if(n != 0)
-+		return(-EFAULT);
-+
-+	ret = count;
-+	switch(req.op){
-+	case MM_MMAP: {
-+		struct mm_mmap *map = &req.u.mmap;
-+
-+		/* Nobody ever noticed it, but do_mmap_pgoff() calls
-+		 * get_unmapped_area() which checks current->mm, if
-+		 * MAP_FIXED is not set, so mmap() could replace
-+		 * an old mapping.
-+		 */
-+		if (! (map->flags & MAP_FIXED))
-+			return(-EINVAL);
-+
-+		ret = do_mmap2(mm, map->addr, map->len, map->prot,
-+			       map->flags, map->fd, map->offset >> PAGE_SHIFT);
-+		if((ret & ~PAGE_MASK) == 0)
-+			ret = count;
-+
-+		break;
-+	}
-+	case MM_MUNMAP: {
-+		struct mm_munmap *unmap = &req.u.munmap;
-+
-+		down_write(&mm->mmap_sem);
-+		ret = do_munmap(mm, unmap->addr, unmap->len);
-+		up_write(&mm->mmap_sem);
-+
-+		if(ret == 0)
-+			ret = count;
-+		break;
-+	}
-+	case MM_MPROTECT: {
-+		struct mm_mprotect *protect = &req.u.mprotect;
-+
-+		ret = do_mprotect(mm, protect->addr, protect->len,
-+				  protect->prot);
-+		if(ret == 0)
-+			ret = count;
-+		break;
-+	}
-+
-+	case MM_COPY_SEGMENTS: {
-+		struct mm_struct *from = proc_mm_get_mm(req.u.copy_segments);
-+
-+		if(IS_ERR(from)){
-+			ret = PTR_ERR(from);
-+			break;
-+		}
-+
-+		/*mm_copy_segments(from, mm);*/
-+		ret = copy_context(mm, from);
-+		if(ret == 0)
-+			ret = count;
-+		break;
-+	}
-+	default:
-+		ret = -EINVAL;
-+		break;
-+	}
-+
-+	return(ret);
-+}
-+
-+static int open_proc_mm(struct inode *inode, struct file *file)
-+{
-+	struct mm_struct *mm = mm_alloc();
-+	int ret;
-+
-+	ret = -ENOMEM;
-+	if(mm == NULL)
-+		goto out_mem;
-+
-+	init_new_empty_context(mm);
-+
-+	spin_lock(&mmlist_lock);
-+	list_add(&mm->mmlist, &current->mm->mmlist);
-+	mmlist_nr++;
-+	spin_unlock(&mmlist_lock);
-+
-+	file->private_data = mm;
-+
-+	return(0);
-+
-+ out_mem:
-+	return(ret);
-+}
-+
-+static int release_proc_mm(struct inode *inode, struct file *file)
-+{
-+	struct mm_struct *mm = file->private_data;
-+
-+	mmput(mm);
-+	return(0);
-+}
-+
-+static struct file_operations proc_mm_fops = {
-+	.open		= open_proc_mm,
-+	.release	= release_proc_mm,
-+	.write		= write_proc_mm,
-+};
-+
-+static int make_proc_mm(void)
-+{
-+	struct proc_dir_entry *ent;
-+
-+	ent = create_proc_entry("mm", 0222, &proc_root);
-+	if(ent == NULL){
-+		printk("make_proc_mm : Failed to register /proc/mm\n");
-+		return(0);
-+	}
-+	ent->proc_fops = &proc_mm_fops;
-+
-+	return(0);
-+}
-+
-+__initcall(make_proc_mm);
-+
-+/*
-+ * Overrides for Emacs so that we follow Linus's tabbing style.
-+ * Emacs will notice this stuff at the end of the file and automatically
-+ * adjust the settings for this buffer only.  This must remain at the end
-+ * of the file.
-+ * ---------------------------------------------------------------------------
-+ * Local variables:
-+ * c-file-style: "linux"
-+ * End:
-+ */
---- linux-2.4.25-paolo/arch/i386/kernel/entry.S	2004-08-29 17:21:51.920775400 +0200
-+++ linux-2.4.25-paolo/arch/i386/kernel/entry.S	2004-08-29 17:21:52.616669608 +0200
-@@ -203,6 +203,8 @@
- 	pushl %eax			# save orig_eax
- 	SAVE_ALL
- 	GET_CURRENT(%ebx)
-+	testb $0x20,tsk_ptrace(%ebx)	# PT_SYSEMU
-+	jne emulatesys
- 	testb $0x02,tsk_ptrace(%ebx)	# PT_TRACESYS
- 	jne tracesys
- 	cmpl $(NR_syscalls),%eax
-@@ -237,6 +239,10 @@
- 	jmp restore_all
- 
- 	ALIGN
-+emulatesys:
-+	call SYMBOL_NAME(syscall_emulate)
-+	jmp ret_from_sys_call
-+	ALIGN
- tracesys:
- 	movl $-ENOSYS,EAX(%esp)
- 	call SYMBOL_NAME(syscall_trace)
---- linux-2.4.25-paolo/include/linux/ptrace.h	2004-08-29 17:21:51.920775400 +0200
-+++ linux-2.4.25-paolo/include/linux/ptrace.h	2004-08-29 17:21:52.616669608 +0200
-@@ -20,6 +20,7 @@
- #define PTRACE_DETACH		0x11
- 
- #define PTRACE_SYSCALL		  24
-+#define PTRACE_SYSEMU		  31
- 
- #include <asm/ptrace.h>
- 
---- linux-2.4.25-paolo/include/linux/sched.h	2004-08-29 17:21:51.921775248 +0200
-+++ linux-2.4.25-paolo/include/linux/sched.h	2004-08-29 17:21:52.617669456 +0200
-@@ -445,6 +445,7 @@
- #define PT_DTRACE	0x00000004	/* delayed trace (used on m68k, i386) */
- #define PT_TRACESYSGOOD	0x00000008
- #define PT_PTRACE_CAP	0x00000010	/* ptracer can follow suid-exec */
-+#define PT_SYSEMU	0x00000020	/* syscall emulation for UML */
- 
- #define is_dumpable(tsk)    ((tsk)->task_dumpable && (tsk)->mm && (tsk)->mm->dumpable)
- 
---- linux-2.4.25/include/asm-i386/mmu_context.h~skas-avoid-ldt	2004-08-29 17:21:52.273721744 +0200
-+++ linux-2.4.25-paolo/include/asm-i386/mmu_context.h	2004-08-29 17:21:52.276721288 +0200
-@@ -13,6 +13,8 @@
-  */
- int init_new_context(struct task_struct *tsk, struct mm_struct *mm);
- void destroy_context(struct mm_struct *mm);
-+int copy_context(struct mm_struct *mm, struct mm_struct *old_mm);
-+void init_new_empty_context(struct mm_struct *mm);
- 
- #ifdef CONFIG_SMP
- 

Deleted: trunk/src/kernel-patch-skas/host-skas3-2.6.3-v1.patch
===================================================================
--- trunk/src/kernel-patch-skas/host-skas3-2.6.3-v1.patch	2006-08-27 15:01:30 UTC (rev 166)
+++ trunk/src/kernel-patch-skas/host-skas3-2.6.3-v1.patch	2006-08-27 15:16:57 UTC (rev 167)
@@ -1,631 +0,0 @@
---- linux-2.6.0/include/linux/mm.h.Skas_add	2003-12-31 11:55:31.000000000 +0100
-+++ linux-2.6.0/include/linux/mm.h	2003-12-31 17:13:57.000000000 +0100
-@@ -507,6 +507,9 @@
- 	return __set_page_dirty_buffers(page);
- }
- 
-+extern long do_mprotect(struct mm_struct *mm, unsigned long start, 
-+			size_t len, unsigned long prot);
-+
- /*
-  * On a two-level page table, this ends up being trivial. Thus the
-  * inlining and the symmetry break with pte_alloc_map() that does all
-@@ -537,9 +540,15 @@
- 
- extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
- 
--extern unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
-+extern unsigned long __do_mmap_pgoff(struct mm_struct *mm, struct file *file, 
-+				   unsigned long addr, unsigned long len,
-+				   unsigned long prot, unsigned long flag,
-+				   unsigned long pgoff);
-+static inline unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
- 	unsigned long len, unsigned long prot,
--	unsigned long flag, unsigned long pgoff);
-+	unsigned long flag, unsigned long pgoff) {
-+	return __do_mmap_pgoff(current->mm, file, addr, len, prot, flag, pgoff);
-+}
- 
- static inline unsigned long do_mmap(struct file *file, unsigned long addr,
- 	unsigned long len, unsigned long prot,
---- linux-2.6.0/include/linux/proc_mm.h.Skas_add	2003-12-31 11:55:31.000000000 +0100
-+++ linux-2.6.0/include/linux/proc_mm.h	2003-12-31 17:13:57.000000000 +0100
-@@ -0,0 +1,48 @@
-+/* 
-+ * Copyright (C) 2002 Jeff Dike (jdike at karaya.com)
-+ * Licensed under the GPL
-+ */
-+
-+#ifndef __PROC_MM_H
-+#define __PROC_MM_H
-+
-+#include "linux/sched.h"
-+
-+#define MM_MMAP 54
-+#define MM_MUNMAP 55
-+#define MM_MPROTECT 56
-+#define MM_COPY_SEGMENTS 57
-+
-+struct mm_mmap {
-+	unsigned long addr;
-+	unsigned long len;
-+	unsigned long prot;
-+	unsigned long flags;
-+	unsigned long fd;
-+	unsigned long offset;
-+};
-+
-+struct mm_munmap {
-+	unsigned long addr;
-+	unsigned long len;	
-+};
-+
-+struct mm_mprotect {
-+	unsigned long addr;
-+	unsigned long len;
-+        unsigned int prot;
-+};
-+
-+struct proc_mm_op {
-+	int op;
-+	union {
-+		struct mm_mmap mmap;
-+		struct mm_munmap munmap;
-+	        struct mm_mprotect mprotect;
-+		int copy_segments;
-+	} u;
-+};
-+
-+extern struct mm_struct *proc_mm_get_mm(int fd);
-+
-+#endif
---- linux-2.6.0/mm/mmap.c.Skas_add	2003-12-31 11:55:32.000000000 +0100
-+++ linux-2.6.0/mm/mmap.c	2003-12-31 17:13:57.000000000 +0100
-@@ -460,11 +460,11 @@
-  * The caller must hold down_write(current->mm->mmap_sem).
-  */
- 
--unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
--			unsigned long len, unsigned long prot,
--			unsigned long flags, unsigned long pgoff)
-+unsigned long __do_mmap_pgoff(struct mm_struct *mm, struct file * file, 
-+			    unsigned long addr, unsigned long len,
-+			    unsigned long prot, unsigned long flags,
-+			    unsigned long pgoff)
- {
--	struct mm_struct * mm = current->mm;
- 	struct vm_area_struct * vma, * prev;
- 	struct inode *inode;
- 	unsigned int vm_flags;
-@@ -712,7 +712,7 @@
- 	return error;
- }
- 
--EXPORT_SYMBOL(do_mmap_pgoff);
-+EXPORT_SYMBOL(__do_mmap_pgoff);
- 
- /* Get an address range which is currently unmapped.
-  * For shmat() with addr=0.
---- linux-2.6.0/mm/mprotect.c.Skas_add	2003-12-31 11:55:32.000000000 +0100
-+++ linux-2.6.0/mm/mprotect.c	2003-12-31 17:13:57.000000000 +0100
-@@ -221,8 +221,9 @@
- 	return error;
- }
- 
--asmlinkage long
--sys_mprotect(unsigned long start, size_t len, unsigned long prot)
-+long
-+do_mprotect(struct mm_struct *mm, unsigned long start, size_t len, 
-+	     unsigned long prot)
- {
- 	unsigned long vm_flags, nstart, end, tmp;
- 	struct vm_area_struct * vma, * next, * prev;
-@@ -245,9 +246,9 @@
- 
- 	vm_flags = calc_vm_prot_bits(prot);
- 
--	down_write(&current->mm->mmap_sem);
-+	down_write(&mm->mmap_sem);
- 
--	vma = find_vma_prev(current->mm, start, &prev);
-+	vma = find_vma_prev(mm, start, &prev);
- 	error = -ENOMEM;
- 	if (!vma)
- 		goto out;
-@@ -326,6 +327,11 @@
- 		prev->vm_mm->map_count--;
- 	}
- out:
--	up_write(&current->mm->mmap_sem);
-+	up_write(&mm->mmap_sem);
- 	return error;
- }
-+
-+asmlinkage long sys_mprotect(unsigned long start, size_t len, unsigned long prot)
-+{
-+        return(do_mprotect(current->mm, start, len, prot));
-+}
---- linux-2.6.0/mm/proc_mm.c.Skas_add	2003-12-31 11:55:32.000000000 +0100
-+++ linux-2.6.0/mm/proc_mm.c	2003-12-31 17:13:57.000000000 +0100
-@@ -0,0 +1,174 @@
-+/* 
-+ * Copyright (C) 2002 Jeff Dike (jdike at karaya.com)
-+ * Licensed under the GPL
-+ */
-+
-+#include "linux/mm.h"
-+#include "linux/init.h"
-+#include "linux/proc_fs.h"
-+#include "linux/proc_mm.h"
-+#include "linux/file.h"
-+#include "asm/uaccess.h"
-+#include "asm/mmu_context.h"
-+
-+static struct file_operations proc_mm_fops;
-+
-+struct mm_struct *proc_mm_get_mm(int fd)
-+{
-+	struct mm_struct *ret = ERR_PTR(-EBADF);
-+	struct file *file;
-+
-+	file = fget(fd);
-+	if (!file)
-+		goto out;
-+
-+	ret = ERR_PTR(-EINVAL);
-+	if(file->f_op != &proc_mm_fops)
-+		goto out_fput;
-+
-+	ret = file->private_data;
-+ out_fput:
-+	fput(file);
-+ out:
-+	return(ret);
-+}
-+
-+extern long do_mmap2(struct mm_struct *mm, unsigned long addr, 
-+		     unsigned long len, unsigned long prot, 
-+		     unsigned long flags, unsigned long fd,
-+		     unsigned long pgoff);
-+
-+static ssize_t write_proc_mm(struct file *file, const char *buffer,
-+			     size_t count, loff_t *ppos)
-+{
-+	struct mm_struct *mm = file->private_data;
-+	struct proc_mm_op req;
-+	int n, ret;
-+
-+	if(count > sizeof(req))
-+		return(-EINVAL);
-+
-+	n = copy_from_user(&req, buffer, count);
-+	if(n != 0)
-+		return(-EFAULT);
-+
-+	ret = count;
-+	switch(req.op){
-+	case MM_MMAP: {
-+		struct mm_mmap *map = &req.u.mmap;
-+
-+		ret = do_mmap2(mm, map->addr, map->len, map->prot, 
-+			       map->flags, map->fd, map->offset >> PAGE_SHIFT);
-+		if((ret & ~PAGE_MASK) == 0)
-+			ret = count;
-+	
-+		break;
-+	}
-+	case MM_MUNMAP: {
-+		struct mm_munmap *unmap = &req.u.munmap;
-+
-+		down_write(&mm->mmap_sem);
-+		ret = do_munmap(mm, unmap->addr, unmap->len);
-+		up_write(&mm->mmap_sem);
-+
-+		if(ret == 0)
-+			ret = count;
-+		break;
-+	}
-+	case MM_MPROTECT: {
-+		struct mm_mprotect *protect = &req.u.mprotect;
-+
-+		ret = do_mprotect(mm, protect->addr, protect->len, 
-+				  protect->prot);
-+		if(ret == 0)
-+			ret = count;
-+		break;
-+	}
-+
-+	case MM_COPY_SEGMENTS: {
-+		struct mm_struct *from = proc_mm_get_mm(req.u.copy_segments);
-+
-+		if(IS_ERR(from)){
-+			ret = PTR_ERR(from);
-+			break;
-+		}
-+
-+		__init_new_context(mm, from);
-+		break;
-+	}
-+	default:
-+		ret = -EINVAL;
-+		break;
-+	}
-+
-+	return(ret);
-+}
-+
-+static int open_proc_mm(struct inode *inode, struct file *file)
-+{
-+	struct mm_struct *mm = mm_alloc();
-+	int ret;
-+
-+	ret = -ENOMEM;
-+	if(mm == NULL)
-+		goto out_mem;
-+
-+	ret = init_new_context(current, mm);
-+	if(ret)
-+		goto out_free;
-+
-+	spin_lock(&mmlist_lock);
-+	list_add(&mm->mmlist, &current->mm->mmlist);
-+	mmlist_nr++;
-+	spin_unlock(&mmlist_lock);
-+
-+	file->private_data = mm;
-+
-+	return(0);
-+
-+ out_free:
-+	mmput(mm);
-+ out_mem:
-+	return(ret);
-+}
-+
-+static int release_proc_mm(struct inode *inode, struct file *file)
-+{
-+	struct mm_struct *mm = file->private_data;
-+
-+	mmput(mm);
-+	return(0);
-+}
-+
-+static struct file_operations proc_mm_fops = {
-+	.open		= open_proc_mm,
-+	.release	= release_proc_mm,
-+	.write		= write_proc_mm,
-+};
-+
-+static int make_proc_mm(void)
-+{
-+	struct proc_dir_entry *ent;
-+
-+	ent = create_proc_entry("mm", 0222, &proc_root);
-+	if(ent == NULL){
-+		printk("make_proc_mm : Failed to register /proc/mm\n");
-+		return(0);
-+	}
-+	ent->proc_fops = &proc_mm_fops;
-+
-+	return(0);
-+}
-+
-+__initcall(make_proc_mm);
-+
-+/*
-+ * Overrides for Emacs so that we follow Linus's tabbing style.
-+ * Emacs will notice this stuff at the end of the file and automatically
-+ * adjust the settings for this buffer only.  This must remain at the end
-+ * of the file.
-+ * ---------------------------------------------------------------------------
-+ * Local variables:
-+ * c-file-style: "linux"
-+ * End:
-+ */
---- linux-2.6.0/mm/Makefile.Skas_add	2003-12-31 11:55:32.000000000 +0100
-+++ linux-2.6.0/mm/Makefile	2003-12-31 17:13:57.000000000 +0100
-@@ -12,3 +12,5 @@
- 			   slab.o swap.o truncate.o vmscan.o $(mmu-y)
- 
- obj-$(CONFIG_SWAP)	+= page_io.o swap_state.o swapfile.o
-+obj-$(CONFIG_PROC_MM)	+= proc_mm.o
-+
---- linux-2.6.0/arch/i386/kernel/sys_i386.c.i386_Skas	2003-12-31 11:55:27.000000000 +0100
-+++ linux-2.6.0/arch/i386/kernel/sys_i386.c	2003-12-31 16:57:39.000000000 +0100
-@@ -40,7 +40,7 @@
- }
- 
- /* common code for old and new mmaps */
--static inline long do_mmap2(
-+long do_mmap2(struct mm_struct *mm,
- 	unsigned long addr, unsigned long len,
- 	unsigned long prot, unsigned long flags,
- 	unsigned long fd, unsigned long pgoff)
-@@ -55,9 +55,9 @@
- 			goto out;
- 	}
- 
--	down_write(&current->mm->mmap_sem);
--	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
--	up_write(&current->mm->mmap_sem);
-+	down_write(&mm->mmap_sem);
-+	error = __do_mmap_pgoff(mm, file, addr, len, prot, flags, pgoff);
-+	up_write(&mm->mmap_sem);
- 
- 	if (file)
- 		fput(file);
-@@ -69,7 +69,7 @@
- 	unsigned long prot, unsigned long flags,
- 	unsigned long fd, unsigned long pgoff)
- {
--	return do_mmap2(addr, len, prot, flags, fd, pgoff);
-+	return do_mmap2(current->mm, addr, len, prot, flags, fd, pgoff);
- }
- 
- /*
-@@ -100,7 +100,7 @@
- 	if (a.offset & ~PAGE_MASK)
- 		goto out;
- 
--	err = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
-+	err = do_mmap2(current->mm, a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
- out:
- 	return err;
- }
---- linux-2.6.0/arch/i386/kernel/ptrace.c.i386_Skas	2003-12-31 11:55:27.000000000 +0100
-+++ linux-2.6.0/arch/i386/kernel/ptrace.c	2003-12-31 16:57:39.000000000 +0100
-@@ -14,6 +14,7 @@
- #include <linux/ptrace.h>
- #include <linux/user.h>
- #include <linux/security.h>
-+#include <linux/proc_mm.h>
- 
- #include <asm/uaccess.h>
- #include <asm/pgtable.h>
-@@ -507,6 +508,56 @@
- 					     addr, (struct user_desc __user *) data);
- 		break;
- 
-+#ifdef CONFIG_PROC_MM
-+	case PTRACE_FAULTINFO: {
-+		struct ptrace_faultinfo fault;
-+
-+		fault = ((struct ptrace_faultinfo) 
-+			{ .is_write	= child->thread.error_code,
-+			  .addr		= child->thread.cr2 });
-+		ret = copy_to_user((unsigned long *) data, &fault, 
-+				   sizeof(fault));
-+		if(ret)
-+			break;
-+		break;
-+	}
-+
-+	case PTRACE_SIGPENDING:
-+		ret = copy_to_user((unsigned long *) data, 
-+				   &child->pending.signal,
-+				   sizeof(child->pending.signal));
-+		break;
-+
-+	case PTRACE_LDT: {
-+		struct ptrace_ldt ldt;
-+
-+		if(copy_from_user(&ldt, (unsigned long *) data, 
-+				  sizeof(ldt))){
-+			ret = -EIO;
-+			break;
-+		}
-+		ret = modify_ldt(child->mm, ldt.func, ldt.ptr, ldt.bytecount);
-+		break;
-+	}
-+
-+	case PTRACE_SWITCH_MM: {
-+		struct mm_struct *old = child->mm;
-+		struct mm_struct *new = proc_mm_get_mm(data);
-+
-+		if(IS_ERR(new)){
-+			ret = PTR_ERR(new);
-+			break;
-+		}
-+
-+		atomic_inc(&new->mm_users);
-+		child->mm = new;
-+		child->active_mm = new;
-+		mmput(old);
-+		ret = 0;
-+		break;
-+	}
-+#endif
-+
- 	default:
- 		ret = ptrace_request(child, request, addr, data);
- 		break;
---- linux-2.6.0/arch/i386/kernel/ldt.c.i386_Skas	2003-12-31 11:55:27.000000000 +0100
-+++ linux-2.6.0/arch/i386/kernel/ldt.c	2003-12-31 16:57:40.000000000 +0100
-@@ -54,7 +54,7 @@
- 	pc->size = mincount;
- 	wmb();
- 
--	if (reload) {
-+	if (reload && (&current->active_mm->context == pc)) {
- #ifdef CONFIG_SMP
- 		cpumask_t mask;
- 		preempt_disable();
-@@ -89,14 +89,12 @@
-  * we do not have to muck with descriptors here, that is
-  * done in switch_mm() as needed.
-  */
--int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
-+int __init_new_context(struct mm_struct *mm, struct mm_struct *old_mm)
- {
--	struct mm_struct * old_mm;
- 	int retval = 0;
- 
- 	init_MUTEX(&mm->context.sem);
- 	mm->context.size = 0;
--	old_mm = current->mm;
- 	if (old_mm && old_mm->context.size > 0) {
- 		down(&old_mm->context.sem);
- 		retval = copy_ldt(&mm->context, &old_mm->context);
-@@ -105,6 +103,11 @@
- 	return retval;
- }
- 
-+int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
-+{
-+	return __init_new_context(mm, current->mm);
-+}
-+
- /*
-  * No need to lock the MM as we are the last user
-  */
-@@ -121,11 +124,11 @@
- 	}
- }
- 
--static int read_ldt(void __user * ptr, unsigned long bytecount)
-+static int read_ldt(struct mm_struct * mm, void __user * ptr,
-+		    unsigned long bytecount)
- {
- 	int err;
- 	unsigned long size;
--	struct mm_struct * mm = current->mm;
- 
- 	if (!mm->context.size)
- 		return 0;
-@@ -169,9 +172,8 @@
- 	return err;
- }
- 
--static int write_ldt(void __user * ptr, unsigned long bytecount, int oldmode)
-+static int write_ldt(struct mm_struct * mm, void __user * ptr, unsigned long bytecount, int oldmode)
- {
--	struct mm_struct * mm = current->mm;
- 	__u32 entry_1, entry_2, *lp;
- 	int error;
- 	struct user_desc ldt_info;
-@@ -195,7 +197,7 @@
- 
- 	down(&mm->context.sem);
- 	if (ldt_info.entry_number >= mm->context.size) {
--		error = alloc_ldt(&current->mm->context, ldt_info.entry_number+1, 1);
-+		error = alloc_ldt(&mm->context, ldt_info.entry_number+1, 1);
- 		if (error < 0)
- 			goto out_unlock;
- 	}
-@@ -228,23 +230,29 @@
- 	return error;
- }
- 
--asmlinkage int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
-+int modify_ldt(struct mm_struct * mm, int func, void __user *ptr,
-+	       unsigned long bytecount)
- {
- 	int ret = -ENOSYS;
- 
- 	switch (func) {
- 	case 0:
--		ret = read_ldt(ptr, bytecount);
-+		ret = read_ldt(mm, ptr, bytecount);
- 		break;
- 	case 1:
--		ret = write_ldt(ptr, bytecount, 1);
-+		ret = write_ldt(mm, ptr, bytecount, 1);
- 		break;
- 	case 2:
- 		ret = read_default_ldt(ptr, bytecount);
- 		break;
- 	case 0x11:
--		ret = write_ldt(ptr, bytecount, 0);
-+		ret = write_ldt(mm, ptr, bytecount, 0);
- 		break;
- 	}
- 	return ret;
- }
-+
-+asmlinkage int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
-+{
-+	return modify_ldt(current->mm, func, ptr, bytecount);
-+}
---- linux-2.6.0/arch/i386/Kconfig.i386_Skas	2003-12-31 11:55:27.000000000 +0100
-+++ linux-2.6.0/arch/i386/Kconfig	2003-12-31 16:57:40.000000000 +0100
-@@ -698,6 +698,9 @@
- 	depends on HIGHMEM64G
- 	default y
- 
-+config PROC_MM
-+	bool "/proc/mm support"
-+
- # Common NUMA Features
- config NUMA
- 	bool "Numa Memory Allocation Support"
---- linux-2.6.0/include/asm-i386/desc.h.i386_Skas	2003-12-31 11:55:31.000000000 +0100
-+++ linux-2.6.0/include/asm-i386/desc.h	2003-12-31 16:57:40.000000000 +0100
-@@ -123,6 +123,9 @@
- 	put_cpu();
- }
- 
-+extern int modify_ldt(struct mm_struct * mm, int func, void __user *ptr,
-+		      unsigned long bytecount);
-+
- #endif /* !__ASSEMBLY__ */
- 
- #endif
---- ./include/asm-i386/processor.h.fix	2004-01-09 21:27:46.000000000 +0100
-+++ ./include/asm-i386/processor.h	2004-02-11 19:13:22.000000000 +0100
-@@ -630,4 +630,6 @@
- 
- extern void select_idle_routine(const struct cpuinfo_x86 *c);
- 
-+extern int __init_new_context(struct mm_struct *mm, struct mm_struct *old_mm);
-+
- #endif /* __ASM_I386_PROCESSOR_H */
---- linux-2.6.0/include/asm-i386/ptrace.h.i386_Skas	2003-12-31 11:55:31.000000000 +0100
-+++ linux-2.6.0/include/asm-i386/ptrace.h	2003-12-31 16:57:54.000000000 +0100
-@@ -59,4 +59,26 @@
- #define instruction_pointer(regs) ((regs)->eip)
- #endif
- 
-+/*For SKAS3 support.*/
-+#ifndef _LINUX_PTRACE_STRUCT_DEF
-+#define _LINUX_PTRACE_STRUCT_DEF
-+
-+#define PTRACE_FAULTINFO	  52
-+#define PTRACE_SIGPENDING	  53
-+#define PTRACE_LDT		  54
-+#define PTRACE_SWITCH_MM 	  55
-+
-+struct ptrace_faultinfo {
-+	int is_write;
-+	unsigned long addr;
-+};
-+
-+struct ptrace_ldt {
-+	int func;
-+  	void *ptr;
-+	unsigned long bytecount;
-+};
-+
-+#endif /*ifndef _LINUX_PTRACE_STRUCT_DEF*/
-+
- #endif
---- ./include/asm-i386/mmu_context.h.fix	2003-12-25 19:24:24.000000000 +0100
-+++ ./include/asm-i386/mmu_context.h	2004-02-29 16:16:54.000000000 +0100
-@@ -29,6 +29,10 @@
- {
- 	int cpu = smp_processor_id();
- 
-+#ifdef CONFIG_SMP
-+	prev = cpu_tlbstate[cpu].active_mm;
-+#endif
-+
- 	if (likely(prev != next)) {
- 		/* stop flush ipis for the previous mm */
- 		cpu_clear(cpu, prev->cpu_vm_mask);
-@@ -50,7 +54,6 @@
- #ifdef CONFIG_SMP
- 	else {
- 		cpu_tlbstate[cpu].state = TLBSTATE_OK;
--		BUG_ON(cpu_tlbstate[cpu].active_mm != next);
- 
- 		if (!cpu_test_and_set(cpu, next->cpu_vm_mask)) {
- 			/* We were in lazy tlb mode and leave_mm disabled 

Deleted: trunk/src/kernel-patch-skas/host-skas3-2.6.6-v1.patch
===================================================================
--- trunk/src/kernel-patch-skas/host-skas3-2.6.6-v1.patch	2006-08-27 15:01:30 UTC (rev 166)
+++ trunk/src/kernel-patch-skas/host-skas3-2.6.6-v1.patch	2006-08-27 15:16:57 UTC (rev 167)
@@ -1,631 +0,0 @@
---- linux-2.6.0/include/linux/mm.h.Skas_add	2003-12-31 11:55:31.000000000 +0100
-+++ linux-2.6.0/include/linux/mm.h	2003-12-31 17:13:57.000000000 +0100
-@@ -515,6 +515,9 @@
- extern struct shrinker *set_shrinker(int, shrinker_t);
- extern void remove_shrinker(struct shrinker *shrinker);
- 
-+extern long do_mprotect(struct mm_struct *mm, unsigned long start, 
-+			size_t len, unsigned long prot);
-+
- /*
-  * On a two-level page table, this ends up being trivial. Thus the
-  * inlining and the symmetry break with pte_alloc_map() that does all
-@@ -548,9 +551,15 @@
- 
- extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
- 
--extern unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
-+extern unsigned long __do_mmap_pgoff(struct mm_struct *mm, struct file *file, 
-+				   unsigned long addr, unsigned long len,
-+				   unsigned long prot, unsigned long flag,
-+				   unsigned long pgoff);
-+static inline unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
- 	unsigned long len, unsigned long prot,
--	unsigned long flag, unsigned long pgoff);
-+	unsigned long flag, unsigned long pgoff) {
-+	return __do_mmap_pgoff(current->mm, file, addr, len, prot, flag, pgoff);
-+}
- 
- static inline unsigned long do_mmap(struct file *file, unsigned long addr,
- 	unsigned long len, unsigned long prot,
---- linux-2.6.0/include/linux/proc_mm.h.Skas_add	2003-12-31 11:55:31.000000000 +0100
-+++ linux-2.6.0/include/linux/proc_mm.h	2003-12-31 17:13:57.000000000 +0100
-@@ -0,0 +1,48 @@
-+/* 
-+ * Copyright (C) 2002 Jeff Dike (jdike at karaya.com)
-+ * Licensed under the GPL
-+ */
-+
-+#ifndef __PROC_MM_H
-+#define __PROC_MM_H
-+
-+#include "linux/sched.h"
-+
-+#define MM_MMAP 54
-+#define MM_MUNMAP 55
-+#define MM_MPROTECT 56
-+#define MM_COPY_SEGMENTS 57
-+
-+struct mm_mmap {
-+	unsigned long addr;
-+	unsigned long len;
-+	unsigned long prot;
-+	unsigned long flags;
-+	unsigned long fd;
-+	unsigned long offset;
-+};
-+
-+struct mm_munmap {
-+	unsigned long addr;
-+	unsigned long len;	
-+};
-+
-+struct mm_mprotect {
-+	unsigned long addr;
-+	unsigned long len;
-+        unsigned int prot;
-+};
-+
-+struct proc_mm_op {
-+	int op;
-+	union {
-+		struct mm_mmap mmap;
-+		struct mm_munmap munmap;
-+	        struct mm_mprotect mprotect;
-+		int copy_segments;
-+	} u;
-+};
-+
-+extern struct mm_struct *proc_mm_get_mm(int fd);
-+
-+#endif
---- linux-2.6.0/mm/mmap.c.Skas_add	2003-12-31 11:55:32.000000000 +0100
-+++ linux-2.6.0/mm/mmap.c	2003-12-31 17:13:57.000000000 +0100
-@@ -480,11 +480,11 @@
-  * The caller must hold down_write(current->mm->mmap_sem).
-  */
- 
--unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
--			unsigned long len, unsigned long prot,
--			unsigned long flags, unsigned long pgoff)
-+unsigned long __do_mmap_pgoff(struct mm_struct *mm, struct file * file, 
-+			    unsigned long addr, unsigned long len,
-+			    unsigned long prot, unsigned long flags,
-+			    unsigned long pgoff)
- {
--	struct mm_struct * mm = current->mm;
- 	struct vm_area_struct * vma, * prev;
- 	struct inode *inode;
- 	unsigned int vm_flags;
-@@ -737,7 +737,7 @@
- 	return error;
- }
- 
--EXPORT_SYMBOL(do_mmap_pgoff);
-+EXPORT_SYMBOL(__do_mmap_pgoff);
- 
- /* Get an address range which is currently unmapped.
-  * For shmat() with addr=0.
---- linux-2.6.0/mm/mprotect.c.Skas_add	2003-12-31 11:55:32.000000000 +0100
-+++ linux-2.6.0/mm/mprotect.c	2003-12-31 17:13:57.000000000 +0100
-@@ -223,8 +223,9 @@
- 	return error;
- }
- 
--asmlinkage long
--sys_mprotect(unsigned long start, size_t len, unsigned long prot)
-+long
-+do_mprotect(struct mm_struct *mm, unsigned long start, size_t len, 
-+	     unsigned long prot)
- {
- 	unsigned long vm_flags, nstart, end, tmp;
- 	struct vm_area_struct * vma, * next, * prev;
-@@ -247,9 +248,9 @@
- 
- 	vm_flags = calc_vm_prot_bits(prot);
- 
--	down_write(&current->mm->mmap_sem);
-+	down_write(&mm->mmap_sem);
- 
--	vma = find_vma_prev(current->mm, start, &prev);
-+	vma = find_vma_prev(mm, start, &prev);
- 	error = -ENOMEM;
- 	if (!vma)
- 		goto out;
-@@ -328,6 +329,11 @@
- 		prev->vm_mm->map_count--;
- 	}
- out:
--	up_write(&current->mm->mmap_sem);
-+	up_write(&mm->mmap_sem);
- 	return error;
- }
-+
-+asmlinkage long sys_mprotect(unsigned long start, size_t len, unsigned long prot)
-+{
-+        return(do_mprotect(current->mm, start, len, prot));
-+}
---- linux-2.6.0/mm/proc_mm.c.Skas_add	2003-12-31 11:55:32.000000000 +0100
-+++ linux-2.6.0/mm/proc_mm.c	2003-12-31 17:13:57.000000000 +0100
-@@ -0,0 +1,174 @@
-+/* 
-+ * Copyright (C) 2002 Jeff Dike (jdike at karaya.com)
-+ * Licensed under the GPL
-+ */
-+
-+#include "linux/mm.h"
-+#include "linux/init.h"
-+#include "linux/proc_fs.h"
-+#include "linux/proc_mm.h"
-+#include "linux/file.h"
-+#include "asm/uaccess.h"
-+#include "asm/mmu_context.h"
-+
-+static struct file_operations proc_mm_fops;
-+
-+struct mm_struct *proc_mm_get_mm(int fd)
-+{
-+	struct mm_struct *ret = ERR_PTR(-EBADF);
-+	struct file *file;
-+
-+	file = fget(fd);
-+	if (!file)
-+		goto out;
-+
-+	ret = ERR_PTR(-EINVAL);
-+	if(file->f_op != &proc_mm_fops)
-+		goto out_fput;
-+
-+	ret = file->private_data;
-+ out_fput:
-+	fput(file);
-+ out:
-+	return(ret);
-+}
-+
-+extern long do_mmap2(struct mm_struct *mm, unsigned long addr, 
-+		     unsigned long len, unsigned long prot, 
-+		     unsigned long flags, unsigned long fd,
-+		     unsigned long pgoff);
-+
-+static ssize_t write_proc_mm(struct file *file, const char *buffer,
-+			     size_t count, loff_t *ppos)
-+{
-+	struct mm_struct *mm = file->private_data;
-+	struct proc_mm_op req;
-+	int n, ret;
-+
-+	if(count > sizeof(req))
-+		return(-EINVAL);
-+
-+	n = copy_from_user(&req, buffer, count);
-+	if(n != 0)
-+		return(-EFAULT);
-+
-+	ret = count;
-+	switch(req.op){
-+	case MM_MMAP: {
-+		struct mm_mmap *map = &req.u.mmap;
-+
-+		ret = do_mmap2(mm, map->addr, map->len, map->prot, 
-+			       map->flags, map->fd, map->offset >> PAGE_SHIFT);
-+		if((ret & ~PAGE_MASK) == 0)
-+			ret = count;
-+	
-+		break;
-+	}
-+	case MM_MUNMAP: {
-+		struct mm_munmap *unmap = &req.u.munmap;
-+
-+		down_write(&mm->mmap_sem);
-+		ret = do_munmap(mm, unmap->addr, unmap->len);
-+		up_write(&mm->mmap_sem);
-+
-+		if(ret == 0)
-+			ret = count;
-+		break;
-+	}
-+	case MM_MPROTECT: {
-+		struct mm_mprotect *protect = &req.u.mprotect;
-+
-+		ret = do_mprotect(mm, protect->addr, protect->len, 
-+				  protect->prot);
-+		if(ret == 0)
-+			ret = count;
-+		break;
-+	}
-+
-+	case MM_COPY_SEGMENTS: {
-+		struct mm_struct *from = proc_mm_get_mm(req.u.copy_segments);
-+
-+		if(IS_ERR(from)){
-+			ret = PTR_ERR(from);
-+			break;
-+		}
-+
-+		__init_new_context(mm, from);
-+		break;
-+	}
-+	default:
-+		ret = -EINVAL;
-+		break;
-+	}
-+
-+	return(ret);
-+}
-+
-+static int open_proc_mm(struct inode *inode, struct file *file)
-+{
-+	struct mm_struct *mm = mm_alloc();
-+	int ret;
-+
-+	ret = -ENOMEM;
-+	if(mm == NULL)
-+		goto out_mem;
-+
-+	ret = init_new_context(current, mm);
-+	if(ret)
-+		goto out_free;
-+
-+	spin_lock(&mmlist_lock);
-+	list_add(&mm->mmlist, &current->mm->mmlist);
-+	mmlist_nr++;
-+	spin_unlock(&mmlist_lock);
-+
-+	file->private_data = mm;
-+
-+	return(0);
-+
-+ out_free:
-+	mmput(mm);
-+ out_mem:
-+	return(ret);
-+}
-+
-+static int release_proc_mm(struct inode *inode, struct file *file)
-+{
-+	struct mm_struct *mm = file->private_data;
-+
-+	mmput(mm);
-+	return(0);
-+}
-+
-+static struct file_operations proc_mm_fops = {
-+	.open		= open_proc_mm,
-+	.release	= release_proc_mm,
-+	.write		= write_proc_mm,
-+};
-+
-+static int make_proc_mm(void)
-+{
-+	struct proc_dir_entry *ent;
-+
-+	ent = create_proc_entry("mm", 0222, &proc_root);
-+	if(ent == NULL){
-+		printk("make_proc_mm : Failed to register /proc/mm\n");
-+		return(0);
-+	}
-+	ent->proc_fops = &proc_mm_fops;
-+
-+	return(0);
-+}
-+
-+__initcall(make_proc_mm);
-+
-+/*
-+ * Overrides for Emacs so that we follow Linus's tabbing style.
-+ * Emacs will notice this stuff at the end of the file and automatically
-+ * adjust the settings for this buffer only.  This must remain at the end
-+ * of the file.
-+ * ---------------------------------------------------------------------------
-+ * Local variables:
-+ * c-file-style: "linux"
-+ * End:
-+ */
---- linux-2.6.0/mm/Makefile.Skas_add	2003-12-31 11:55:32.000000000 +0100
-+++ linux-2.6.0/mm/Makefile	2003-12-31 17:13:57.000000000 +0100
-@@ -13,3 +13,5 @@
- 
- obj-$(CONFIG_SWAP)	+= page_io.o swap_state.o swapfile.o
- obj-$(CONFIG_HUGETLBFS)	+= hugetlb.o
-+obj-$(CONFIG_PROC_MM)	+= proc_mm.o
-+
---- linux-2.6.0/arch/i386/kernel/sys_i386.c.i386_Skas	2003-12-31 11:55:27.000000000 +0100
-+++ linux-2.6.0/arch/i386/kernel/sys_i386.c	2003-12-31 16:57:39.000000000 +0100
-@@ -41,7 +41,7 @@
- }
- 
- /* common code for old and new mmaps */
--static inline long do_mmap2(
-+long do_mmap2(struct mm_struct *mm,
- 	unsigned long addr, unsigned long len,
- 	unsigned long prot, unsigned long flags,
- 	unsigned long fd, unsigned long pgoff)
-@@ -56,9 +56,9 @@
- 			goto out;
- 	}
- 
--	down_write(&current->mm->mmap_sem);
--	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
--	up_write(&current->mm->mmap_sem);
-+	down_write(&mm->mmap_sem);
-+	error = __do_mmap_pgoff(mm, file, addr, len, prot, flags, pgoff);
-+	up_write(&mm->mmap_sem);
- 
- 	if (file)
- 		fput(file);
-@@ -70,7 +70,7 @@
- 	unsigned long prot, unsigned long flags,
- 	unsigned long fd, unsigned long pgoff)
- {
--	return do_mmap2(addr, len, prot, flags, fd, pgoff);
-+	return do_mmap2(current->mm, addr, len, prot, flags, fd, pgoff);
- }
- 
- /*
-@@ -101,7 +101,7 @@
- 	if (a.offset & ~PAGE_MASK)
- 		goto out;
- 
--	err = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
-+	err = do_mmap2(current->mm, a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
- out:
- 	return err;
- }
---- linux-2.6.0/arch/i386/kernel/ptrace.c.i386_Skas	2003-12-31 11:55:27.000000000 +0100
-+++ linux-2.6.0/arch/i386/kernel/ptrace.c	2003-12-31 16:57:39.000000000 +0100
-@@ -15,6 +15,7 @@
- #include <linux/user.h>
- #include <linux/security.h>
- #include <linux/audit.h>
-+#include <linux/proc_mm.h>
- 
- #include <asm/uaccess.h>
- #include <asm/pgtable.h>
-@@ -508,6 +509,56 @@
- 					     addr, (struct user_desc __user *) data);
- 		break;
- 
-+#ifdef CONFIG_PROC_MM
-+	case PTRACE_FAULTINFO: {
-+		struct ptrace_faultinfo fault;
-+
-+		fault = ((struct ptrace_faultinfo) 
-+			{ .is_write	= child->thread.error_code,
-+			  .addr		= child->thread.cr2 });
-+		ret = copy_to_user((unsigned long *) data, &fault, 
-+				   sizeof(fault));
-+		if(ret)
-+			break;
-+		break;
-+	}
-+
-+	case PTRACE_SIGPENDING:
-+		ret = copy_to_user((unsigned long *) data, 
-+				   &child->pending.signal,
-+				   sizeof(child->pending.signal));
-+		break;
-+
-+	case PTRACE_LDT: {
-+		struct ptrace_ldt ldt;
-+
-+		if(copy_from_user(&ldt, (unsigned long *) data, 
-+				  sizeof(ldt))){
-+			ret = -EIO;
-+			break;
-+		}
-+		ret = modify_ldt(child->mm, ldt.func, ldt.ptr, ldt.bytecount);
-+		break;
-+	}
-+
-+	case PTRACE_SWITCH_MM: {
-+		struct mm_struct *old = child->mm;
-+		struct mm_struct *new = proc_mm_get_mm(data);
-+
-+		if(IS_ERR(new)){
-+			ret = PTR_ERR(new);
-+			break;
-+		}
-+
-+		atomic_inc(&new->mm_users);
-+		child->mm = new;
-+		child->active_mm = new;
-+		mmput(old);
-+		ret = 0;
-+		break;
-+	}
-+#endif
-+
- 	default:
- 		ret = ptrace_request(child, request, addr, data);
- 		break;
---- linux-2.6.0/arch/i386/kernel/ldt.c.i386_Skas	2003-12-31 11:55:27.000000000 +0100
-+++ linux-2.6.0/arch/i386/kernel/ldt.c	2003-12-31 16:57:40.000000000 +0100
-@@ -54,7 +54,7 @@
- 	pc->size = mincount;
- 	wmb();
- 
--	if (reload) {
-+	if (reload && (&current->active_mm->context == pc)) {
- #ifdef CONFIG_SMP
- 		cpumask_t mask;
- 		preempt_disable();
-@@ -89,14 +89,12 @@
-  * we do not have to muck with descriptors here, that is
-  * done in switch_mm() as needed.
-  */
--int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
-+int __init_new_context(struct mm_struct *mm, struct mm_struct *old_mm)
- {
--	struct mm_struct * old_mm;
- 	int retval = 0;
- 
- 	init_MUTEX(&mm->context.sem);
- 	mm->context.size = 0;
--	old_mm = current->mm;
- 	if (old_mm && old_mm->context.size > 0) {
- 		down(&old_mm->context.sem);
- 		retval = copy_ldt(&mm->context, &old_mm->context);
-@@ -105,6 +103,11 @@
- 	return retval;
- }
- 
-+int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
-+{
-+	return __init_new_context(mm, current->mm);
-+}
-+
- /*
-  * No need to lock the MM as we are the last user
-  */
-@@ -121,11 +124,11 @@
- 	}
- }
- 
--static int read_ldt(void __user * ptr, unsigned long bytecount)
-+static int read_ldt(struct mm_struct * mm, void __user * ptr,
-+		    unsigned long bytecount)
- {
- 	int err;
- 	unsigned long size;
--	struct mm_struct * mm = current->mm;
- 
- 	if (!mm->context.size)
- 		return 0;
-@@ -169,9 +172,8 @@
- 	return err;
- }
- 
--static int write_ldt(void __user * ptr, unsigned long bytecount, int oldmode)
-+static int write_ldt(struct mm_struct * mm, void __user * ptr, unsigned long bytecount, int oldmode)
- {
--	struct mm_struct * mm = current->mm;
- 	__u32 entry_1, entry_2, *lp;
- 	int error;
- 	struct user_desc ldt_info;
-@@ -195,7 +197,7 @@
- 
- 	down(&mm->context.sem);
- 	if (ldt_info.entry_number >= mm->context.size) {
--		error = alloc_ldt(&current->mm->context, ldt_info.entry_number+1, 1);
-+		error = alloc_ldt(&mm->context, ldt_info.entry_number+1, 1);
- 		if (error < 0)
- 			goto out_unlock;
- 	}
-@@ -228,23 +230,29 @@
- 	return error;
- }
- 
--asmlinkage int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
-+int modify_ldt(struct mm_struct * mm, int func, void __user *ptr,
-+	       unsigned long bytecount)
- {
- 	int ret = -ENOSYS;
- 
- 	switch (func) {
- 	case 0:
--		ret = read_ldt(ptr, bytecount);
-+		ret = read_ldt(mm, ptr, bytecount);
- 		break;
- 	case 1:
--		ret = write_ldt(ptr, bytecount, 1);
-+		ret = write_ldt(mm, ptr, bytecount, 1);
- 		break;
- 	case 2:
- 		ret = read_default_ldt(ptr, bytecount);
- 		break;
- 	case 0x11:
--		ret = write_ldt(ptr, bytecount, 0);
-+		ret = write_ldt(mm, ptr, bytecount, 0);
- 		break;
- 	}
- 	return ret;
- }
-+
-+asmlinkage int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
-+{
-+	return modify_ldt(current->mm, func, ptr, bytecount);
-+}
---- linux-2.6.0/arch/i386/Kconfig.i386_Skas	2003-12-31 11:55:27.000000000 +0100
-+++ linux-2.6.0/arch/i386/Kconfig	2003-12-31 16:57:40.000000000 +0100
-@@ -707,6 +707,9 @@
- 	depends on HIGHMEM64G
- 	default y
- 
-+config PROC_MM
-+	bool "/proc/mm support"
-+
- # Common NUMA Features
- config NUMA
- 	bool "Numa Memory Allocation Support"
---- linux-2.6.0/include/asm-i386/desc.h.i386_Skas	2003-12-31 11:55:31.000000000 +0100
-+++ linux-2.6.0/include/asm-i386/desc.h	2003-12-31 16:57:40.000000000 +0100
-@@ -123,6 +123,9 @@
- 	put_cpu();
- }
- 
-+extern int modify_ldt(struct mm_struct * mm, int func, void __user *ptr,
-+		      unsigned long bytecount);
-+
- #endif /* !__ASSEMBLY__ */
- 
- #endif
---- ./include/asm-i386/processor.h.fix	2004-01-09 21:27:46.000000000 +0100
-+++ ./include/asm-i386/processor.h	2004-02-11 19:13:22.000000000 +0100
-@@ -648,4 +648,6 @@
- 
- extern void select_idle_routine(const struct cpuinfo_x86 *c);
- 
-+extern int __init_new_context(struct mm_struct *mm, struct mm_struct *old_mm);
-+
- #endif /* __ASM_I386_PROCESSOR_H */
---- linux-2.6.0/include/asm-i386/ptrace.h.i386_Skas	2003-12-31 11:55:31.000000000 +0100
-+++ linux-2.6.0/include/asm-i386/ptrace.h	2003-12-31 16:57:54.000000000 +0100
-@@ -59,4 +59,26 @@
- #define instruction_pointer(regs) ((regs)->eip)
- #endif
- 
-+/*For SKAS3 support.*/
-+#ifndef _LINUX_PTRACE_STRUCT_DEF
-+#define _LINUX_PTRACE_STRUCT_DEF
-+
-+#define PTRACE_FAULTINFO	  52
-+#define PTRACE_SIGPENDING	  53
-+#define PTRACE_LDT		  54
-+#define PTRACE_SWITCH_MM 	  55
-+
-+struct ptrace_faultinfo {
-+	int is_write;
-+	unsigned long addr;
-+};
-+
-+struct ptrace_ldt {
-+	int func;
-+  	void *ptr;
-+	unsigned long bytecount;
-+};
-+
-+#endif /*ifndef _LINUX_PTRACE_STRUCT_DEF*/
-+
- #endif
---- ./include/asm-i386/mmu_context.h.fix	2003-12-25 19:24:24.000000000 +0100
-+++ ./include/asm-i386/mmu_context.h	2004-02-29 16:16:54.000000000 +0100
-@@ -29,6 +29,10 @@
- {
- 	int cpu = smp_processor_id();
- 
-+#ifdef CONFIG_SMP
-+	prev = cpu_tlbstate[cpu].active_mm;
-+#endif
-+
- 	if (likely(prev != next)) {
- 		/* stop flush ipis for the previous mm */
- 		cpu_clear(cpu, prev->cpu_vm_mask);
-@@ -50,7 +54,6 @@
- #ifdef CONFIG_SMP
- 	else {
- 		cpu_tlbstate[cpu].state = TLBSTATE_OK;
--		BUG_ON(cpu_tlbstate[cpu].active_mm != next);
- 
- 		if (!cpu_test_and_set(cpu, next->cpu_vm_mask)) {
- 			/* We were in lazy tlb mode and leave_mm disabled 

Deleted: trunk/src/kernel-patch-skas/host-skas3-2.6.7-v1.patch
===================================================================
--- trunk/src/kernel-patch-skas/host-skas3-2.6.7-v1.patch	2006-08-27 15:01:30 UTC (rev 166)
+++ trunk/src/kernel-patch-skas/host-skas3-2.6.7-v1.patch	2006-08-27 15:16:57 UTC (rev 167)
@@ -1,633 +0,0 @@
---- ./arch/i386/kernel/sys_i386.c.skas	2004-03-13 17:55:23.000000000 +0100
-+++ ./arch/i386/kernel/sys_i386.c	2004-06-17 16:24:30.000000000 +0200
-@@ -41,7 +41,7 @@
- }
- 
- /* common code for old and new mmaps */
--static inline long do_mmap2(
-+long do_mmap2(struct mm_struct *mm,
- 	unsigned long addr, unsigned long len,
- 	unsigned long prot, unsigned long flags,
- 	unsigned long fd, unsigned long pgoff)
-@@ -56,9 +56,9 @@
- 			goto out;
- 	}
- 
--	down_write(&current->mm->mmap_sem);
--	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
--	up_write(&current->mm->mmap_sem);
-+	down_write(&mm->mmap_sem);
-+	error = __do_mmap_pgoff(mm, file, addr, len, prot, flags, pgoff);
-+	up_write(&mm->mmap_sem);
- 
- 	if (file)
- 		fput(file);
-@@ -70,7 +70,7 @@
- 	unsigned long prot, unsigned long flags,
- 	unsigned long fd, unsigned long pgoff)
- {
--	return do_mmap2(addr, len, prot, flags, fd, pgoff);
-+	return do_mmap2(current->mm, addr, len, prot, flags, fd, pgoff);
- }
- 
- /*
-@@ -101,7 +101,7 @@
- 	if (a.offset & ~PAGE_MASK)
- 		goto out;
- 
--	err = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
-+	err = do_mmap2(current->mm, a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
- out:
- 	return err;
- }
---- ./arch/i386/kernel/ptrace.c.skas	2004-06-16 22:25:18.000000000 +0200
-+++ ./arch/i386/kernel/ptrace.c	2004-06-17 16:24:30.000000000 +0200
-@@ -15,6 +15,7 @@
- #include <linux/user.h>
- #include <linux/security.h>
- #include <linux/audit.h>
-+#include <linux/proc_mm.h>
- 
- #include <asm/uaccess.h>
- #include <asm/pgtable.h>
-@@ -509,6 +510,56 @@
- 					(struct user_desc __user *) data);
- 		break;
- 
-+#ifdef CONFIG_PROC_MM
-+	case PTRACE_FAULTINFO: {
-+		struct ptrace_faultinfo fault;
-+
-+		fault = ((struct ptrace_faultinfo) 
-+			{ .is_write	= child->thread.error_code,
-+			  .addr		= child->thread.cr2 });
-+		ret = copy_to_user((unsigned long *) data, &fault, 
-+				   sizeof(fault));
-+		if(ret)
-+			break;
-+		break;
-+	}
-+
-+	case PTRACE_SIGPENDING:
-+		ret = copy_to_user((unsigned long *) data, 
-+				   &child->pending.signal,
-+				   sizeof(child->pending.signal));
-+		break;
-+
-+	case PTRACE_LDT: {
-+		struct ptrace_ldt ldt;
-+
-+		if(copy_from_user(&ldt, (unsigned long *) data, 
-+				  sizeof(ldt))){
-+			ret = -EIO;
-+			break;
-+		}
-+		ret = modify_ldt(child->mm, ldt.func, ldt.ptr, ldt.bytecount);
-+		break;
-+	}
-+
-+	case PTRACE_SWITCH_MM: {
-+		struct mm_struct *old = child->mm;
-+		struct mm_struct *new = proc_mm_get_mm(data);
-+
-+		if(IS_ERR(new)){
-+			ret = PTR_ERR(new);
-+			break;
-+		}
-+
-+		atomic_inc(&new->mm_users);
-+		child->mm = new;
-+		child->active_mm = new;
-+		mmput(old);
-+		ret = 0;
-+		break;
-+	}
-+#endif
-+
- 	default:
- 		ret = ptrace_request(child, request, addr, data);
- 		break;
---- ./arch/i386/kernel/ldt.c.skas	2003-12-25 19:23:56.000000000 +0100
-+++ ./arch/i386/kernel/ldt.c	2004-06-17 16:24:30.000000000 +0200
-@@ -54,7 +54,7 @@
- 	pc->size = mincount;
- 	wmb();
- 
--	if (reload) {
-+	if (reload && (&current->active_mm->context == pc)) {
- #ifdef CONFIG_SMP
- 		cpumask_t mask;
- 		preempt_disable();
-@@ -89,14 +89,12 @@
-  * we do not have to muck with descriptors here, that is
-  * done in switch_mm() as needed.
-  */
--int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
-+int __init_new_context(struct mm_struct *mm, struct mm_struct *old_mm)
- {
--	struct mm_struct * old_mm;
- 	int retval = 0;
- 
- 	init_MUTEX(&mm->context.sem);
- 	mm->context.size = 0;
--	old_mm = current->mm;
- 	if (old_mm && old_mm->context.size > 0) {
- 		down(&old_mm->context.sem);
- 		retval = copy_ldt(&mm->context, &old_mm->context);
-@@ -105,6 +103,11 @@
- 	return retval;
- }
- 
-+int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
-+{
-+	return __init_new_context(mm, current->mm);
-+}
-+
- /*
-  * No need to lock the MM as we are the last user
-  */
-@@ -121,11 +124,11 @@
- 	}
- }
- 
--static int read_ldt(void __user * ptr, unsigned long bytecount)
-+static int read_ldt(struct mm_struct * mm, void __user * ptr,
-+		    unsigned long bytecount)
- {
- 	int err;
- 	unsigned long size;
--	struct mm_struct * mm = current->mm;
- 
- 	if (!mm->context.size)
- 		return 0;
-@@ -169,9 +172,8 @@
- 	return err;
- }
- 
--static int write_ldt(void __user * ptr, unsigned long bytecount, int oldmode)
-+static int write_ldt(struct mm_struct * mm, void __user * ptr, unsigned long bytecount, int oldmode)
- {
--	struct mm_struct * mm = current->mm;
- 	__u32 entry_1, entry_2, *lp;
- 	int error;
- 	struct user_desc ldt_info;
-@@ -195,7 +197,7 @@
- 
- 	down(&mm->context.sem);
- 	if (ldt_info.entry_number >= mm->context.size) {
--		error = alloc_ldt(&current->mm->context, ldt_info.entry_number+1, 1);
-+		error = alloc_ldt(&mm->context, ldt_info.entry_number+1, 1);
- 		if (error < 0)
- 			goto out_unlock;
- 	}
-@@ -228,23 +230,29 @@
- 	return error;
- }
- 
--asmlinkage int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
-+int modify_ldt(struct mm_struct * mm, int func, void __user *ptr,
-+	       unsigned long bytecount)
- {
- 	int ret = -ENOSYS;
- 
- 	switch (func) {
- 	case 0:
--		ret = read_ldt(ptr, bytecount);
-+		ret = read_ldt(mm, ptr, bytecount);
- 		break;
- 	case 1:
--		ret = write_ldt(ptr, bytecount, 1);
-+		ret = write_ldt(mm, ptr, bytecount, 1);
- 		break;
- 	case 2:
- 		ret = read_default_ldt(ptr, bytecount);
- 		break;
- 	case 0x11:
--		ret = write_ldt(ptr, bytecount, 0);
-+		ret = write_ldt(mm, ptr, bytecount, 0);
- 		break;
- 	}
- 	return ret;
- }
-+
-+asmlinkage int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
-+{
-+	return modify_ldt(current->mm, func, ptr, bytecount);
-+}
---- ./arch/i386/Kconfig.skas	2004-06-16 22:25:18.000000000 +0200
-+++ ./arch/i386/Kconfig	2004-06-17 16:24:30.000000000 +0200
-@@ -720,6 +720,10 @@
- 	depends on HIGHMEM64G
- 	default y
- 
-+config PROC_MM
-+	bool "/proc/mm support"
-+	default y
-+
- # Common NUMA Features
- config NUMA
- 	bool "Numa Memory Allocation and Scheduler Support"
---- ./include/linux/mm.h.skas	2004-06-16 22:27:11.000000000 +0200
-+++ ./include/linux/mm.h	2004-06-17 16:24:30.000000000 +0200
-@@ -574,6 +574,9 @@
- extern struct shrinker *set_shrinker(int, shrinker_t);
- extern void remove_shrinker(struct shrinker *shrinker);
- 
-+extern long do_mprotect(struct mm_struct *mm, unsigned long start, 
-+			size_t len, unsigned long prot);
-+
- /*
-  * On a two-level page table, this ends up being trivial. Thus the
-  * inlining and the symmetry break with pte_alloc_map() that does all
-@@ -632,9 +635,15 @@
- 
- extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
- 
--extern unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
-+extern unsigned long __do_mmap_pgoff(struct mm_struct *mm, struct file *file, 
-+				   unsigned long addr, unsigned long len,
-+				   unsigned long prot, unsigned long flag,
-+				   unsigned long pgoff);
-+static inline unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
- 	unsigned long len, unsigned long prot,
--	unsigned long flag, unsigned long pgoff);
-+	unsigned long flag, unsigned long pgoff) {
-+	return __do_mmap_pgoff(current->mm, file, addr, len, prot, flag, pgoff);
-+}
- 
- static inline unsigned long do_mmap(struct file *file, unsigned long addr,
- 	unsigned long len, unsigned long prot,
---- ./include/linux/proc_mm.h.skas	2004-06-17 16:24:30.000000000 +0200
-+++ ./include/linux/proc_mm.h	2004-06-17 16:24:30.000000000 +0200
-@@ -0,0 +1,48 @@
-+/* 
-+ * Copyright (C) 2002 Jeff Dike (jdike at karaya.com)
-+ * Licensed under the GPL
-+ */
-+
-+#ifndef __PROC_MM_H
-+#define __PROC_MM_H
-+
-+#include "linux/sched.h"
-+
-+#define MM_MMAP 54
-+#define MM_MUNMAP 55
-+#define MM_MPROTECT 56
-+#define MM_COPY_SEGMENTS 57
-+
-+struct mm_mmap {
-+	unsigned long addr;
-+	unsigned long len;
-+	unsigned long prot;
-+	unsigned long flags;
-+	unsigned long fd;
-+	unsigned long offset;
-+};
-+
-+struct mm_munmap {
-+	unsigned long addr;
-+	unsigned long len;	
-+};
-+
-+struct mm_mprotect {
-+	unsigned long addr;
-+	unsigned long len;
-+        unsigned int prot;
-+};
-+
-+struct proc_mm_op {
-+	int op;
-+	union {
-+		struct mm_mmap mmap;
-+		struct mm_munmap munmap;
-+	        struct mm_mprotect mprotect;
-+		int copy_segments;
-+	} u;
-+};
-+
-+extern struct mm_struct *proc_mm_get_mm(int fd);
-+
-+#endif
---- ./include/asm-i386/desc.h.skas	2003-12-20 17:44:08.000000000 +0100
-+++ ./include/asm-i386/desc.h	2004-06-17 16:24:30.000000000 +0200
-@@ -123,6 +123,9 @@
- 	put_cpu();
- }
- 
-+extern int modify_ldt(struct mm_struct * mm, int func, void __user *ptr,
-+		      unsigned long bytecount);
-+
- #endif /* !__ASSEMBLY__ */
- 
- #endif
---- ./include/asm-i386/processor.h.skas	2004-06-16 22:27:00.000000000 +0200
-+++ ./include/asm-i386/processor.h	2004-06-17 16:24:30.000000000 +0200
-@@ -649,6 +649,8 @@
- 
- extern void select_idle_routine(const struct cpuinfo_x86 *c);
- 
-+extern int __init_new_context(struct mm_struct *mm, struct mm_struct *old_mm);
-+
- #define cache_line_size() (boot_cpu_data.x86_cache_alignment)
- 
- #ifdef CONFIG_SCHED_SMT
---- ./include/asm-i386/ptrace.h.skas	2003-12-20 17:21:33.000000000 +0100
-+++ ./include/asm-i386/ptrace.h	2004-06-17 16:24:30.000000000 +0200
-@@ -59,4 +59,26 @@
- #define instruction_pointer(regs) ((regs)->eip)
- #endif
- 
-+/*For SKAS3 support.*/
-+#ifndef _LINUX_PTRACE_STRUCT_DEF
-+#define _LINUX_PTRACE_STRUCT_DEF
-+
-+#define PTRACE_FAULTINFO	  52
-+#define PTRACE_SIGPENDING	  53
-+#define PTRACE_LDT		  54
-+#define PTRACE_SWITCH_MM 	  55
-+
-+struct ptrace_faultinfo {
-+	int is_write;
-+	unsigned long addr;
-+};
-+
-+struct ptrace_ldt {
-+	int func;
-+  	void *ptr;
-+	unsigned long bytecount;
-+};
-+
-+#endif /*ifndef _LINUX_PTRACE_STRUCT_DEF*/
-+
- #endif
---- ./include/asm-i386/mmu_context.h.skas	2003-12-25 19:24:24.000000000 +0100
-+++ ./include/asm-i386/mmu_context.h	2004-06-17 16:24:30.000000000 +0200
-@@ -29,6 +29,10 @@
- {
- 	int cpu = smp_processor_id();
- 
-+#ifdef CONFIG_SMP
-+	prev = cpu_tlbstate[cpu].active_mm;
-+#endif
-+
- 	if (likely(prev != next)) {
- 		/* stop flush ipis for the previous mm */
- 		cpu_clear(cpu, prev->cpu_vm_mask);
-@@ -50,7 +54,6 @@
- #ifdef CONFIG_SMP
- 	else {
- 		cpu_tlbstate[cpu].state = TLBSTATE_OK;
--		BUG_ON(cpu_tlbstate[cpu].active_mm != next);
- 
- 		if (!cpu_test_and_set(cpu, next->cpu_vm_mask)) {
- 			/* We were in lazy tlb mode and leave_mm disabled 
---- ./mm/mmap.c.skas	2004-06-16 22:27:18.000000000 +0200
-+++ ./mm/mmap.c	2004-06-17 16:24:30.000000000 +0200
-@@ -725,11 +725,11 @@
-  * The caller must hold down_write(current->mm->mmap_sem).
-  */
- 
--unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
--			unsigned long len, unsigned long prot,
--			unsigned long flags, unsigned long pgoff)
-+unsigned long __do_mmap_pgoff(struct mm_struct *mm, struct file * file, 
-+			    unsigned long addr, unsigned long len,
-+			    unsigned long prot, unsigned long flags,
-+			    unsigned long pgoff)
- {
--	struct mm_struct * mm = current->mm;
- 	struct vm_area_struct * vma, * prev;
- 	struct inode *inode;
- 	unsigned int vm_flags;
-@@ -988,7 +988,7 @@
- 	return error;
- }
- 
--EXPORT_SYMBOL(do_mmap_pgoff);
-+EXPORT_SYMBOL(__do_mmap_pgoff);
- 
- /* Get an address range which is currently unmapped.
-  * For shmat() with addr=0.
---- ./mm/mprotect.c.skas	2004-06-16 22:27:18.000000000 +0200
-+++ ./mm/mprotect.c	2004-06-17 16:24:30.000000000 +0200
-@@ -185,8 +185,9 @@
- 	return error;
- }
- 
--asmlinkage long
--sys_mprotect(unsigned long start, size_t len, unsigned long prot)
-+long
-+do_mprotect(struct mm_struct *mm, unsigned long start, size_t len, 
-+	     unsigned long prot)
- {
- 	unsigned long vm_flags, nstart, end, tmp;
- 	struct vm_area_struct *vma, *prev;
-@@ -209,9 +210,9 @@
- 
- 	vm_flags = calc_vm_prot_bits(prot);
- 
--	down_write(&current->mm->mmap_sem);
-+	down_write(&mm->mmap_sem);
- 
--	vma = find_vma_prev(current->mm, start, &prev);
-+	vma = find_vma_prev(mm, start, &prev);
- 	error = -ENOMEM;
- 	if (!vma)
- 		goto out;
-@@ -277,6 +278,11 @@
- 		}
- 	}
- out:
--	up_write(&current->mm->mmap_sem);
-+	up_write(&mm->mmap_sem);
- 	return error;
- }
-+
-+asmlinkage long sys_mprotect(unsigned long start, size_t len, unsigned long prot)
-+{
-+        return(do_mprotect(current->mm, start, len, prot));
-+}
---- ./mm/proc_mm.c.skas	2004-06-17 16:24:30.000000000 +0200
-+++ ./mm/proc_mm.c	2004-06-17 16:24:30.000000000 +0200
-@@ -0,0 +1,174 @@
-+/* 
-+ * Copyright (C) 2002 Jeff Dike (jdike at karaya.com)
-+ * Licensed under the GPL
-+ */
-+
-+#include "linux/mm.h"
-+#include "linux/init.h"
-+#include "linux/proc_fs.h"
-+#include "linux/proc_mm.h"
-+#include "linux/file.h"
-+#include "asm/uaccess.h"
-+#include "asm/mmu_context.h"
-+
-+static struct file_operations proc_mm_fops;
-+
-+struct mm_struct *proc_mm_get_mm(int fd)
-+{
-+	struct mm_struct *ret = ERR_PTR(-EBADF);
-+	struct file *file;
-+
-+	file = fget(fd);
-+	if (!file)
-+		goto out;
-+
-+	ret = ERR_PTR(-EINVAL);
-+	if(file->f_op != &proc_mm_fops)
-+		goto out_fput;
-+
-+	ret = file->private_data;
-+ out_fput:
-+	fput(file);
-+ out:
-+	return(ret);
-+}
-+
-+extern long do_mmap2(struct mm_struct *mm, unsigned long addr, 
-+		     unsigned long len, unsigned long prot, 
-+		     unsigned long flags, unsigned long fd,
-+		     unsigned long pgoff);
-+
-+static ssize_t write_proc_mm(struct file *file, const char *buffer,
-+			     size_t count, loff_t *ppos)
-+{
-+	struct mm_struct *mm = file->private_data;
-+	struct proc_mm_op req;
-+	int n, ret;
-+
-+	if(count > sizeof(req))
-+		return(-EINVAL);
-+
-+	n = copy_from_user(&req, buffer, count);
-+	if(n != 0)
-+		return(-EFAULT);
-+
-+	ret = count;
-+	switch(req.op){
-+	case MM_MMAP: {
-+		struct mm_mmap *map = &req.u.mmap;
-+
-+		ret = do_mmap2(mm, map->addr, map->len, map->prot, 
-+			       map->flags, map->fd, map->offset >> PAGE_SHIFT);
-+		if((ret & ~PAGE_MASK) == 0)
-+			ret = count;
-+	
-+		break;
-+	}
-+	case MM_MUNMAP: {
-+		struct mm_munmap *unmap = &req.u.munmap;
-+
-+		down_write(&mm->mmap_sem);
-+		ret = do_munmap(mm, unmap->addr, unmap->len);
-+		up_write(&mm->mmap_sem);
-+
-+		if(ret == 0)
-+			ret = count;
-+		break;
-+	}
-+	case MM_MPROTECT: {
-+		struct mm_mprotect *protect = &req.u.mprotect;
-+
-+		ret = do_mprotect(mm, protect->addr, protect->len, 
-+				  protect->prot);
-+		if(ret == 0)
-+			ret = count;
-+		break;
-+	}
-+
-+	case MM_COPY_SEGMENTS: {
-+		struct mm_struct *from = proc_mm_get_mm(req.u.copy_segments);
-+
-+		if(IS_ERR(from)){
-+			ret = PTR_ERR(from);
-+			break;
-+		}
-+
-+		__init_new_context(mm, from);
-+		break;
-+	}
-+	default:
-+		ret = -EINVAL;
-+		break;
-+	}
-+
-+	return(ret);
-+}
-+
-+static int open_proc_mm(struct inode *inode, struct file *file)
-+{
-+	struct mm_struct *mm = mm_alloc();
-+	int ret;
-+
-+	ret = -ENOMEM;
-+	if(mm == NULL)
-+		goto out_mem;
-+
-+	ret = init_new_context(current, mm);
-+	if(ret)
-+		goto out_free;
-+
-+	spin_lock(&mmlist_lock);
-+	list_add(&mm->mmlist, &current->mm->mmlist);
-+	mmlist_nr++;
-+	spin_unlock(&mmlist_lock);
-+
-+	file->private_data = mm;
-+
-+	return(0);
-+
-+ out_free:
-+	mmput(mm);
-+ out_mem:
-+	return(ret);
-+}
-+
-+static int release_proc_mm(struct inode *inode, struct file *file)
-+{
-+	struct mm_struct *mm = file->private_data;
-+
-+	mmput(mm);
-+	return(0);
-+}
-+
-+static struct file_operations proc_mm_fops = {
-+	.open		= open_proc_mm,
-+	.release	= release_proc_mm,
-+	.write		= write_proc_mm,
-+};
-+
-+static int make_proc_mm(void)
-+{
-+	struct proc_dir_entry *ent;
-+
-+	ent = create_proc_entry("mm", 0222, &proc_root);
-+	if(ent == NULL){
-+		printk("make_proc_mm : Failed to register /proc/mm\n");
-+		return(0);
-+	}
-+	ent->proc_fops = &proc_mm_fops;
-+
-+	return(0);
-+}
-+
-+__initcall(make_proc_mm);
-+
-+/*
-+ * Overrides for Emacs so that we follow Linus's tabbing style.
-+ * Emacs will notice this stuff at the end of the file and automatically
-+ * adjust the settings for this buffer only.  This must remain at the end
-+ * of the file.
-+ * ---------------------------------------------------------------------------
-+ * Local variables:
-+ * c-file-style: "linux"
-+ * End:
-+ */
---- ./mm/Makefile.skas	2004-06-16 22:27:15.000000000 +0200
-+++ ./mm/Makefile	2004-06-17 16:24:30.000000000 +0200
-@@ -15,3 +15,4 @@
- obj-$(CONFIG_SWAP)	+= page_io.o swap_state.o swapfile.o
- obj-$(CONFIG_HUGETLBFS)	+= hugetlb.o
- obj-$(CONFIG_NUMA) 	+= mempolicy.o
-+obj-$(CONFIG_PROC_MM)	+= proc_mm.o

Deleted: trunk/src/kernel-patch-skas/host-skas3-2.6.8-v6.patch
===================================================================
--- trunk/src/kernel-patch-skas/host-skas3-2.6.8-v6.patch	2006-08-27 15:01:30 UTC (rev 166)
+++ trunk/src/kernel-patch-skas/host-skas3-2.6.8-v6.patch	2006-08-27 15:16:57 UTC (rev 167)
@@ -1,872 +0,0 @@
-
-
-Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade_spam at yahoo.it>
----
-
- vanilla-linux-2.6.8.1-paolo/Makefile                       |    2 
- vanilla-linux-2.6.8.1-paolo/arch/i386/Kconfig              |    4 
- vanilla-linux-2.6.8.1-paolo/arch/i386/kernel/entry.S       |    9 
- vanilla-linux-2.6.8.1-paolo/arch/i386/kernel/ldt.c         |   38 +-
- vanilla-linux-2.6.8.1-paolo/arch/i386/kernel/ptrace.c      |   71 ++++-
- vanilla-linux-2.6.8.1-paolo/arch/i386/kernel/sys_i386.c    |   12 
- vanilla-linux-2.6.8.1-paolo/include/asm-i386/desc.h        |    3 
- vanilla-linux-2.6.8.1-paolo/include/asm-i386/mmu_context.h |   19 +
- vanilla-linux-2.6.8.1-paolo/include/asm-i386/ptrace.h      |   22 +
- vanilla-linux-2.6.8.1-paolo/include/asm-i386/thread_info.h |    4 
- vanilla-linux-2.6.8.1-paolo/include/linux/mm.h             |   13 
- vanilla-linux-2.6.8.1-paolo/include/linux/proc_mm.h        |   48 +++
- vanilla-linux-2.6.8.1-paolo/include/linux/ptrace.h         |    1 
- vanilla-linux-2.6.8.1-paolo/kernel/fork.c                  |    1 
- vanilla-linux-2.6.8.1-paolo/mm/Makefile                    |    1 
- vanilla-linux-2.6.8.1-paolo/mm/mmap.c                      |   10 
- vanilla-linux-2.6.8.1-paolo/mm/mprotect.c                  |   23 +
- vanilla-linux-2.6.8.1-paolo/mm/proc_mm.c                   |  181 +++++++++++++
- 18 files changed, 415 insertions(+), 47 deletions(-)
-
-diff -puN arch/i386/Kconfig~host-skas3-2.6.8.1-v6 arch/i386/Kconfig
---- vanilla-linux-2.6.8.1/arch/i386/Kconfig~host-skas3-2.6.8.1-v6	2004-10-18 19:02:18.166827168 +0200
-+++ vanilla-linux-2.6.8.1-paolo/arch/i386/Kconfig	2004-10-18 19:02:18.301806648 +0200
-@@ -721,6 +721,10 @@ config X86_PAE
- 	depends on HIGHMEM64G
- 	default y
- 
-+config PROC_MM
-+	bool "/proc/mm support"
-+	default y
-+
- # Common NUMA Features
- config NUMA
- 	bool "Numa Memory Allocation and Scheduler Support"
-diff -puN arch/i386/kernel/entry.S~host-skas3-2.6.8.1-v6 arch/i386/kernel/entry.S
---- vanilla-linux-2.6.8.1/arch/i386/kernel/entry.S~host-skas3-2.6.8.1-v6	2004-10-18 19:02:18.202821696 +0200
-+++ vanilla-linux-2.6.8.1-paolo/arch/i386/kernel/entry.S	2004-10-18 19:02:18.335801480 +0200
-@@ -258,7 +258,7 @@ sysenter_past_esp:
- 	cmpl $(nr_syscalls), %eax
- 	jae syscall_badsys
- 
--	testb $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT),TI_flags(%ebp)
-+	testb $(_TIF_SYSCALL_EMU|_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT),TI_flags(%ebp)
- 	jnz syscall_trace_entry
- 	call *sys_call_table(,%eax,4)
- 	movl %eax,EAX(%esp)
-@@ -280,8 +280,8 @@ ENTRY(system_call)
- 	GET_THREAD_INFO(%ebp)
- 	cmpl $(nr_syscalls), %eax
- 	jae syscall_badsys
--					# system call tracing in operation
--	testb $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT),TI_flags(%ebp)
-+					# system call tracing in operation / emulation
-+	testb $(_TIF_SYSCALL_EMU|_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT),TI_flags(%ebp)
- 	jnz syscall_trace_entry
- syscall_call:
- 	call *sys_call_table(,%eax,4)
-@@ -340,6 +340,9 @@ syscall_trace_entry:
- 	movl %esp, %eax
- 	xorl %edx,%edx
- 	call do_syscall_trace
-+	cmpl $0, %eax
-+	jne syscall_exit		# ret != 0 -> running under PTRACE_SYSEMU,
-+					# so must skip actual syscall
- 	movl ORIG_EAX(%esp), %eax
- 	cmpl $(nr_syscalls), %eax
- 	jnae syscall_call
-diff -puN arch/i386/kernel/ldt.c~host-skas3-2.6.8.1-v6 arch/i386/kernel/ldt.c
---- vanilla-linux-2.6.8.1/arch/i386/kernel/ldt.c~host-skas3-2.6.8.1-v6	2004-10-18 19:02:18.203821544 +0200
-+++ vanilla-linux-2.6.8.1-paolo/arch/i386/kernel/ldt.c	2004-10-18 19:02:18.319803912 +0200
-@@ -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)
-@@ -54,7 +55,7 @@ static int alloc_ldt(mm_context_t *pc, i
- 	pc->size = mincount;
- 	wmb();
- 
--	if (reload) {
-+	if (reload && (&current->active_mm->context == pc)) {
- #ifdef CONFIG_SMP
- 		cpumask_t mask;
- 		preempt_disable();
-@@ -89,14 +90,10 @@ static inline int copy_ldt(mm_context_t 
-  * we do not have to muck with descriptors here, that is
-  * done in switch_mm() as needed.
-  */
--int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
-+int copy_context(struct mm_struct *mm, struct mm_struct *old_mm)
- {
--	struct mm_struct * old_mm;
- 	int retval = 0;
- 
--	init_MUTEX(&mm->context.sem);
--	mm->context.size = 0;
--	old_mm = current->mm;
- 	if (old_mm && old_mm->context.size > 0) {
- 		down(&old_mm->context.sem);
- 		retval = copy_ldt(&mm->context, &old_mm->context);
-@@ -105,6 +102,12 @@ int init_new_context(struct task_struct 
- 	return retval;
- }
- 
-+int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
-+{
-+	init_new_empty_context(mm);
-+	return copy_context(mm, current->mm);
-+}
-+
- /*
-  * No need to lock the MM as we are the last user
-  */
-@@ -121,11 +124,11 @@ void destroy_context(struct mm_struct *m
- 	}
- }
- 
--static int read_ldt(void __user * ptr, unsigned long bytecount)
-+static int read_ldt(struct mm_struct * mm, void __user * ptr,
-+		    unsigned long bytecount)
- {
- 	int err;
- 	unsigned long size;
--	struct mm_struct * mm = current->mm;
- 
- 	if (!mm->context.size)
- 		return 0;
-@@ -169,9 +172,8 @@ static int read_default_ldt(void __user 
- 	return err;
- }
- 
--static int write_ldt(void __user * ptr, unsigned long bytecount, int oldmode)
-+static int write_ldt(struct mm_struct * mm, void __user * ptr, unsigned long bytecount, int oldmode)
- {
--	struct mm_struct * mm = current->mm;
- 	__u32 entry_1, entry_2, *lp;
- 	int error;
- 	struct user_desc ldt_info;
-@@ -195,7 +197,7 @@ static int write_ldt(void __user * ptr, 
- 
- 	down(&mm->context.sem);
- 	if (ldt_info.entry_number >= mm->context.size) {
--		error = alloc_ldt(&current->mm->context, ldt_info.entry_number+1, 1);
-+		error = alloc_ldt(&mm->context, ldt_info.entry_number+1, 1);
- 		if (error < 0)
- 			goto out_unlock;
- 	}
-@@ -228,23 +230,29 @@ out:
- 	return error;
- }
- 
--asmlinkage int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
-+int modify_ldt(struct mm_struct * mm, int func, void __user *ptr,
-+	       unsigned long bytecount)
- {
- 	int ret = -ENOSYS;
- 
- 	switch (func) {
- 	case 0:
--		ret = read_ldt(ptr, bytecount);
-+		ret = read_ldt(mm, ptr, bytecount);
- 		break;
- 	case 1:
--		ret = write_ldt(ptr, bytecount, 1);
-+		ret = write_ldt(mm, ptr, bytecount, 1);
- 		break;
- 	case 2:
- 		ret = read_default_ldt(ptr, bytecount);
- 		break;
- 	case 0x11:
--		ret = write_ldt(ptr, bytecount, 0);
-+		ret = write_ldt(mm, ptr, bytecount, 0);
- 		break;
- 	}
- 	return ret;
- }
-+
-+asmlinkage int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
-+{
-+	return modify_ldt(current->mm, func, ptr, bytecount);
-+}
-diff -puN arch/i386/kernel/ptrace.c~host-skas3-2.6.8.1-v6 arch/i386/kernel/ptrace.c
---- vanilla-linux-2.6.8.1/arch/i386/kernel/ptrace.c~host-skas3-2.6.8.1-v6	2004-10-18 19:02:18.204821392 +0200
-+++ vanilla-linux-2.6.8.1-paolo/arch/i386/kernel/ptrace.c	2004-10-18 19:02:18.319803912 +0200
-@@ -15,6 +15,7 @@
- #include <linux/user.h>
- #include <linux/security.h>
- #include <linux/audit.h>
-+#include <linux/proc_mm.h>
- 
- #include <asm/uaccess.h>
- #include <asm/pgtable.h>
-@@ -357,6 +358,7 @@ asmlinkage int sys_ptrace(long request, 
- 		  }
- 		  break;
- 
-+	case PTRACE_SYSEMU: /* continue and replace next syscall */
- 	case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
- 	case PTRACE_CONT: { /* restart after signal. */
- 		long tmp;
-@@ -364,6 +366,12 @@ asmlinkage int sys_ptrace(long request, 
- 		ret = -EIO;
- 		if ((unsigned long) data > _NSIG)
- 			break;
-+		if (request == PTRACE_SYSEMU) {
-+			set_tsk_thread_flag(child, TIF_SYSCALL_EMU);
-+		}
-+		else {
-+			clear_tsk_thread_flag(child, TIF_SYSCALL_EMU);
-+		}
- 		if (request == PTRACE_SYSCALL) {
- 			set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- 		}
-@@ -404,6 +412,7 @@ asmlinkage int sys_ptrace(long request, 
- 		ret = -EIO;
- 		if ((unsigned long) data > _NSIG)
- 			break;
-+		clear_tsk_thread_flag(child, TIF_SYSCALL_EMU);
- 		clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- 		if ((child->ptrace & PT_DTRACE) == 0) {
- 			/* Spurious delayed TF traps may occur */
-@@ -509,6 +518,56 @@ asmlinkage int sys_ptrace(long request, 
- 					(struct user_desc __user *) data);
- 		break;
- 
-+#ifdef CONFIG_PROC_MM
-+	case PTRACE_FAULTINFO: {
-+		struct ptrace_faultinfo fault;
-+
-+		fault = ((struct ptrace_faultinfo)
-+			{ .is_write	= child->thread.error_code,
-+			  .addr		= child->thread.cr2 });
-+		ret = copy_to_user((unsigned long *) data, &fault,
-+				   sizeof(fault));
-+		if(ret)
-+			break;
-+		break;
-+	}
-+
-+	case PTRACE_SIGPENDING:
-+		ret = copy_to_user((unsigned long *) data,
-+				   &child->pending.signal,
-+				   sizeof(child->pending.signal));
-+		break;
-+
-+	case PTRACE_LDT: {
-+		struct ptrace_ldt ldt;
-+
-+		if(copy_from_user(&ldt, (unsigned long *) data,
-+				  sizeof(ldt))){
-+			ret = -EIO;
-+			break;
-+		}
-+		ret = modify_ldt(child->mm, ldt.func, ldt.ptr, ldt.bytecount);
-+		break;
-+	}
-+
-+	case PTRACE_SWITCH_MM: {
-+		struct mm_struct *old = child->mm;
-+		struct mm_struct *new = proc_mm_get_mm(data);
-+
-+		if(IS_ERR(new)){
-+			ret = PTR_ERR(new);
-+			break;
-+		}
-+
-+		atomic_inc(&new->mm_users);
-+		child->mm = new;
-+		child->active_mm = new;
-+		mmput(old);
-+		ret = 0;
-+		break;
-+	}
-+#endif
-+
- 	default:
- 		ret = ptrace_request(child, request, addr, data);
- 		break;
-@@ -524,8 +583,9 @@ out:
-  * - triggered by current->work.syscall_trace
-  */
- __attribute__((regparm(3)))
--void do_syscall_trace(struct pt_regs *regs, int entryexit)
-+int do_syscall_trace(struct pt_regs *regs, int entryexit)
- {
-+	int is_sysemu;
- 	if (unlikely(current->audit_context)) {
- 		if (!entryexit)
- 			audit_syscall_entry(current, regs->orig_eax,
-@@ -534,11 +594,12 @@ void do_syscall_trace(struct pt_regs *re
- 		else
- 			audit_syscall_exit(current, regs->eax);
- 	}
-+	is_sysemu = test_thread_flag(TIF_SYSCALL_EMU);
- 
--	if (!test_thread_flag(TIF_SYSCALL_TRACE))
--		return;
-+	if (!test_thread_flag(TIF_SYSCALL_TRACE) && !is_sysemu)
-+		return 0;
- 	if (!(current->ptrace & PT_PTRACED))
--		return;
-+		return 0;
- 	/* the 0x80 provides a way for the tracing parent to distinguish
- 	   between a syscall stop and SIGTRAP delivery */
- 	ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
-@@ -553,4 +614,6 @@ void do_syscall_trace(struct pt_regs *re
- 		send_sig(current->exit_code, current, 1);
- 		current->exit_code = 0;
- 	}
-+	/* != 0 if nullifying the syscall, 0 if running it normally */
-+	return is_sysemu;
- }
-diff -puN arch/i386/kernel/sys_i386.c~host-skas3-2.6.8.1-v6 arch/i386/kernel/sys_i386.c
---- vanilla-linux-2.6.8.1/arch/i386/kernel/sys_i386.c~host-skas3-2.6.8.1-v6	2004-10-18 19:02:18.205821240 +0200
-+++ vanilla-linux-2.6.8.1-paolo/arch/i386/kernel/sys_i386.c	2004-10-18 19:02:18.320803760 +0200
-@@ -41,7 +41,7 @@ asmlinkage int sys_pipe(unsigned long __
- }
- 
- /* common code for old and new mmaps */
--static inline long do_mmap2(
-+long do_mmap2(struct mm_struct *mm,
- 	unsigned long addr, unsigned long len,
- 	unsigned long prot, unsigned long flags,
- 	unsigned long fd, unsigned long pgoff)
-@@ -56,9 +56,9 @@ static inline long do_mmap2(
- 			goto out;
- 	}
- 
--	down_write(&current->mm->mmap_sem);
--	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
--	up_write(&current->mm->mmap_sem);
-+	down_write(&mm->mmap_sem);
-+	error = __do_mmap_pgoff(mm, file, addr, len, prot, flags, pgoff);
-+	up_write(&mm->mmap_sem);
- 
- 	if (file)
- 		fput(file);
-@@ -70,7 +70,7 @@ asmlinkage long sys_mmap2(unsigned long 
- 	unsigned long prot, unsigned long flags,
- 	unsigned long fd, unsigned long pgoff)
- {
--	return do_mmap2(addr, len, prot, flags, fd, pgoff);
-+	return do_mmap2(current->mm, addr, len, prot, flags, fd, pgoff);
- }
- 
- /*
-@@ -101,7 +101,7 @@ asmlinkage int old_mmap(struct mmap_arg_
- 	if (a.offset & ~PAGE_MASK)
- 		goto out;
- 
--	err = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
-+	err = do_mmap2(current->mm, a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
- out:
- 	return err;
- }
-diff -puN include/asm-i386/desc.h~host-skas3-2.6.8.1-v6 include/asm-i386/desc.h
---- vanilla-linux-2.6.8.1/include/asm-i386/desc.h~host-skas3-2.6.8.1-v6	2004-10-18 19:02:18.214819872 +0200
-+++ vanilla-linux-2.6.8.1-paolo/include/asm-i386/desc.h	2004-10-18 19:02:18.320803760 +0200
-@@ -124,6 +124,9 @@ static inline void load_LDT(mm_context_t
- 	put_cpu();
- }
- 
-+extern int modify_ldt(struct mm_struct * mm, int func, void __user *ptr,
-+		      unsigned long bytecount);
-+
- #endif /* !__ASSEMBLY__ */
- 
- #endif
-diff -puN include/asm-i386/mmu_context.h~host-skas3-2.6.8.1-v6 include/asm-i386/mmu_context.h
---- vanilla-linux-2.6.8.1/include/asm-i386/mmu_context.h~host-skas3-2.6.8.1-v6	2004-10-18 19:02:18.215819720 +0200
-+++ vanilla-linux-2.6.8.1-paolo/include/asm-i386/mmu_context.h	2004-10-18 19:02:18.335801480 +0200
-@@ -6,13 +6,25 @@
- #include <asm/atomic.h>
- #include <asm/pgalloc.h>
- #include <asm/tlbflush.h>
-+#include <asm/semaphore.h>
- 
- /*
-- * Used for LDT copy/destruction.
-+ * Used for LDT initialization/destruction. You cannot copy an LDT with
-+ * init_new_context, since it thinks you are passing it a new LDT and won't
-+ * deallocate its old content.
-  */
- int init_new_context(struct task_struct *tsk, struct mm_struct *mm);
- void destroy_context(struct mm_struct *mm);
- 
-+/* LDT initialization for a clean environment - needed for SKAS.*/
-+static inline void init_new_empty_context(struct mm_struct *mm)
-+{
-+	init_MUTEX(&mm->context.sem);
-+	mm->context.size = 0;
-+}
-+
-+/* LDT copy for SKAS - for the above problem.*/
-+int copy_context(struct mm_struct *mm, struct mm_struct *old_mm);
- 
- static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
- {
-@@ -29,6 +41,10 @@ static inline void switch_mm(struct mm_s
- {
- 	int cpu = smp_processor_id();
- 
-+#ifdef CONFIG_SMP
-+	prev = cpu_tlbstate[cpu].active_mm;
-+#endif
-+
- 	if (likely(prev != next)) {
- 		/* stop flush ipis for the previous mm */
- 		cpu_clear(cpu, prev->cpu_vm_mask);
-@@ -50,7 +66,6 @@ static inline void switch_mm(struct mm_s
- #ifdef CONFIG_SMP
- 	else {
- 		cpu_tlbstate[cpu].state = TLBSTATE_OK;
--		BUG_ON(cpu_tlbstate[cpu].active_mm != next);
- 
- 		if (!cpu_test_and_set(cpu, next->cpu_vm_mask)) {
- 			/* We were in lazy tlb mode and leave_mm disabled 
-diff -puN include/asm-i386/ptrace.h~host-skas3-2.6.8.1-v6 include/asm-i386/ptrace.h
---- vanilla-linux-2.6.8.1/include/asm-i386/ptrace.h~host-skas3-2.6.8.1-v6	2004-10-18 19:02:18.216819568 +0200
-+++ vanilla-linux-2.6.8.1-paolo/include/asm-i386/ptrace.h	2004-10-18 19:02:18.335801480 +0200
-@@ -59,4 +59,26 @@ struct pt_regs {
- #define instruction_pointer(regs) ((regs)->eip)
- #endif
- 
-+/*For SKAS3 support.*/
-+#ifndef _LINUX_PTRACE_STRUCT_DEF
-+#define _LINUX_PTRACE_STRUCT_DEF
-+
-+#define PTRACE_FAULTINFO	  52
-+#define PTRACE_SIGPENDING	  53
-+#define PTRACE_LDT		  54
-+#define PTRACE_SWITCH_MM 	  55
-+
-+struct ptrace_faultinfo {
-+	int is_write;
-+	unsigned long addr;
-+};
-+
-+struct ptrace_ldt {
-+	int func;
-+  	void *ptr;
-+	unsigned long bytecount;
-+};
-+
-+#endif /*ifndef _LINUX_PTRACE_STRUCT_DEF*/
-+
- #endif
-diff -puN include/asm-i386/thread_info.h~host-skas3-2.6.8.1-v6 include/asm-i386/thread_info.h
---- vanilla-linux-2.6.8.1/include/asm-i386/thread_info.h~host-skas3-2.6.8.1-v6	2004-10-18 19:02:18.217819416 +0200
-+++ vanilla-linux-2.6.8.1-paolo/include/asm-i386/thread_info.h	2004-10-18 19:02:18.336801328 +0200
-@@ -143,6 +143,7 @@ static inline unsigned long current_stac
- #define TIF_NEED_RESCHED	3	/* rescheduling necessary */
- #define TIF_SINGLESTEP		4	/* restore singlestep on return to user mode */
- #define TIF_IRET		5	/* return with iret */
-+#define TIF_SYSCALL_EMU		6	/* syscall emulation active */
- #define TIF_SYSCALL_AUDIT	7	/* syscall auditing active */
- #define TIF_POLLING_NRFLAG	16	/* true if poll_idle() is polling TIF_NEED_RESCHED */
- 
-@@ -152,12 +153,13 @@ static inline unsigned long current_stac
- #define _TIF_NEED_RESCHED	(1<<TIF_NEED_RESCHED)
- #define _TIF_SINGLESTEP		(1<<TIF_SINGLESTEP)
- #define _TIF_IRET		(1<<TIF_IRET)
-+#define _TIF_SYSCALL_EMU	(1<<TIF_SYSCALL_EMU)
- #define _TIF_SYSCALL_AUDIT	(1<<TIF_SYSCALL_AUDIT)
- #define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
- 
- /* work to do on interrupt/exception return */
- #define _TIF_WORK_MASK \
--  (0x0000FFFF & ~(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT))
-+  (0x0000FFFF & ~(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_EMU))
- #define _TIF_ALLWORK_MASK	0x0000FFFF	/* work to do on any return to u-space */
- 
- /*
-diff -puN include/linux/mm.h~host-skas3-2.6.8.1-v6 include/linux/mm.h
---- vanilla-linux-2.6.8.1/include/linux/mm.h~host-skas3-2.6.8.1-v6	2004-10-18 19:02:18.237816376 +0200
-+++ vanilla-linux-2.6.8.1-paolo/include/linux/mm.h	2004-10-18 19:02:18.248814704 +0200
-@@ -575,6 +575,9 @@ struct shrinker;
- extern struct shrinker *set_shrinker(int, shrinker_t);
- extern void remove_shrinker(struct shrinker *shrinker);
- 
-+extern long do_mprotect(struct mm_struct *mm, unsigned long start,
-+			size_t len, unsigned long prot);
-+
- /*
-  * On a two-level page table, this ends up being trivial. Thus the
-  * inlining and the symmetry break with pte_alloc_map() that does all
-@@ -633,9 +636,15 @@ extern void exit_mmap(struct mm_struct *
- 
- extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
- 
--extern unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
-+extern unsigned long __do_mmap_pgoff(struct mm_struct *mm, struct file *file,
-+				   unsigned long addr, unsigned long len,
-+				   unsigned long prot, unsigned long flag,
-+				   unsigned long pgoff);
-+static inline unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
- 	unsigned long len, unsigned long prot,
--	unsigned long flag, unsigned long pgoff);
-+	unsigned long flag, unsigned long pgoff) {
-+	return __do_mmap_pgoff(current->mm, file, addr, len, prot, flag, pgoff);
-+}
- 
- static inline unsigned long do_mmap(struct file *file, unsigned long addr,
- 	unsigned long len, unsigned long prot,
-diff -puN include/linux/proc_mm.h~host-skas3-2.6.8.1-v6 include/linux/proc_mm.h
---- vanilla-linux-2.6.8.1/include/linux/proc_mm.h~host-skas3-2.6.8.1-v6	2004-10-18 19:02:18.238816224 +0200
-+++ vanilla-linux-2.6.8.1-paolo/include/linux/proc_mm.h	2004-10-18 19:02:18.275810600 +0200
-@@ -0,0 +1,48 @@
-+/*
-+ * Copyright (C) 2002 Jeff Dike (jdike at karaya.com)
-+ * Licensed under the GPL
-+ */
-+
-+#ifndef __PROC_MM_H
-+#define __PROC_MM_H
-+
-+#include "linux/sched.h"
-+
-+#define MM_MMAP 54
-+#define MM_MUNMAP 55
-+#define MM_MPROTECT 56
-+#define MM_COPY_SEGMENTS 57
-+
-+struct mm_mmap {
-+	unsigned long addr;
-+	unsigned long len;
-+	unsigned long prot;
-+	unsigned long flags;
-+	unsigned long fd;
-+	unsigned long offset;
-+};
-+
-+struct mm_munmap {
-+	unsigned long addr;
-+	unsigned long len;
-+};
-+
-+struct mm_mprotect {
-+	unsigned long addr;
-+	unsigned long len;
-+        unsigned int prot;
-+};
-+
-+struct proc_mm_op {
-+	int op;
-+	union {
-+		struct mm_mmap mmap;
-+		struct mm_munmap munmap;
-+	        struct mm_mprotect mprotect;
-+		int copy_segments;
-+	} u;
-+};
-+
-+extern struct mm_struct *proc_mm_get_mm(int fd);
-+
-+#endif
-diff -puN include/linux/ptrace.h~host-skas3-2.6.8.1-v6 include/linux/ptrace.h
---- vanilla-linux-2.6.8.1/include/linux/ptrace.h~host-skas3-2.6.8.1-v6	2004-10-18 19:02:18.239816072 +0200
-+++ vanilla-linux-2.6.8.1-paolo/include/linux/ptrace.h	2004-10-18 19:02:18.336801328 +0200
-@@ -20,6 +20,7 @@
- #define PTRACE_DETACH		0x11
- 
- #define PTRACE_SYSCALL		  24
-+#define PTRACE_SYSEMU		  31
- 
- /* 0x4200-0x4300 are reserved for architecture-independent additions.  */
- #define PTRACE_SETOPTIONS	0x4200
-diff -puN kernel/fork.c~host-skas3-2.6.8.1-v6 kernel/fork.c
---- vanilla-linux-2.6.8.1/kernel/fork.c~host-skas3-2.6.8.1-v6	2004-10-18 19:02:18.240815920 +0200
-+++ vanilla-linux-2.6.8.1-paolo/kernel/fork.c	2004-10-18 19:02:18.337801176 +0200
-@@ -1008,6 +1008,7 @@ struct task_struct *copy_process(unsigne
- 	 * of CLONE_PTRACE.
- 	 */
- 	clear_tsk_thread_flag(p, TIF_SYSCALL_TRACE);
-+	clear_tsk_thread_flag(p, TIF_SYSCALL_EMU);
- 
- 	/* Our parent execution domain becomes current domain
- 	   These must match for thread signalling to apply */
-diff -puN mm/Makefile~host-skas3-2.6.8.1-v6 mm/Makefile
---- vanilla-linux-2.6.8.1/mm/Makefile~host-skas3-2.6.8.1-v6	2004-10-18 19:02:18.242815616 +0200
-+++ vanilla-linux-2.6.8.1-paolo/mm/Makefile	2004-10-18 19:02:18.275810600 +0200
-@@ -15,3 +15,4 @@ obj-y			:= bootmem.o filemap.o mempool.o
- obj-$(CONFIG_SWAP)	+= page_io.o swap_state.o swapfile.o
- obj-$(CONFIG_HUGETLBFS)	+= hugetlb.o
- obj-$(CONFIG_NUMA) 	+= mempolicy.o
-+obj-$(CONFIG_PROC_MM)	+= proc_mm.o
-diff -puN mm/mmap.c~host-skas3-2.6.8.1-v6 mm/mmap.c
---- vanilla-linux-2.6.8.1/mm/mmap.c~host-skas3-2.6.8.1-v6	2004-10-18 19:02:18.243815464 +0200
-+++ vanilla-linux-2.6.8.1-paolo/mm/mmap.c	2004-10-18 19:02:18.276810448 +0200
-@@ -736,11 +736,11 @@ none:
-  * The caller must hold down_write(current->mm->mmap_sem).
-  */
- 
--unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
--			unsigned long len, unsigned long prot,
--			unsigned long flags, unsigned long pgoff)
-+unsigned long __do_mmap_pgoff(struct mm_struct *mm, struct file * file,
-+			    unsigned long addr, unsigned long len,
-+			    unsigned long prot, unsigned long flags,
-+			    unsigned long pgoff)
- {
--	struct mm_struct * mm = current->mm;
- 	struct vm_area_struct * vma, * prev;
- 	struct inode *inode;
- 	unsigned int vm_flags;
-@@ -1006,7 +1006,7 @@ unacct_error:
- 	return error;
- }
- 
--EXPORT_SYMBOL(do_mmap_pgoff);
-+EXPORT_SYMBOL(__do_mmap_pgoff);
- 
- /* Get an address range which is currently unmapped.
-  * For shmat() with addr=0.
-diff -puN mm/mprotect.c~host-skas3-2.6.8.1-v6 mm/mprotect.c
---- vanilla-linux-2.6.8.1/mm/mprotect.c~host-skas3-2.6.8.1-v6	2004-10-18 19:02:18.244815312 +0200
-+++ vanilla-linux-2.6.8.1-paolo/mm/mprotect.c	2004-10-18 19:02:18.284809232 +0200
-@@ -92,19 +92,20 @@ change_protection(struct vm_area_struct 
- {
- 	pgd_t *dir;
- 	unsigned long beg = start;
-+	struct mm_struct * mm = vma->vm_mm;
- 
--	dir = pgd_offset(current->mm, start);
-+	dir = pgd_offset(mm, start);
- 	flush_cache_range(vma, beg, end);
- 	if (start >= end)
- 		BUG();
--	spin_lock(&current->mm->page_table_lock);
-+	spin_lock(&mm->page_table_lock);
- 	do {
- 		change_pmd_range(dir, start, end - start, newprot);
- 		start = (start + PGDIR_SIZE) & PGDIR_MASK;
- 		dir++;
- 	} while (start && (start < end));
- 	flush_tlb_range(vma, beg, end);
--	spin_unlock(&current->mm->page_table_lock);
-+	spin_unlock(&mm->page_table_lock);
- 	return;
- }
- 
-@@ -185,8 +186,9 @@ fail:
- 	return error;
- }
- 
--asmlinkage long
--sys_mprotect(unsigned long start, size_t len, unsigned long prot)
-+long
-+do_mprotect(struct mm_struct *mm, unsigned long start, size_t len,
-+	     unsigned long prot)
- {
- 	unsigned long vm_flags, nstart, end, tmp;
- 	struct vm_area_struct *vma, *prev;
-@@ -215,9 +217,9 @@ sys_mprotect(unsigned long start, size_t
- 
- 	vm_flags = calc_vm_prot_bits(prot);
- 
--	down_write(&current->mm->mmap_sem);
-+	down_write(&mm->mmap_sem);
- 
--	vma = find_vma_prev(current->mm, start, &prev);
-+	vma = find_vma_prev(mm, start, &prev);
- 	error = -ENOMEM;
- 	if (!vma)
- 		goto out;
-@@ -283,6 +285,11 @@ sys_mprotect(unsigned long start, size_t
- 		}
- 	}
- out:
--	up_write(&current->mm->mmap_sem);
-+	up_write(&mm->mmap_sem);
- 	return error;
- }
-+
-+asmlinkage long sys_mprotect(unsigned long start, size_t len, unsigned long prot)
-+{
-+        return(do_mprotect(current->mm, start, len, prot));
-+}
-diff -puN mm/proc_mm.c~host-skas3-2.6.8.1-v6 mm/proc_mm.c
---- vanilla-linux-2.6.8.1/mm/proc_mm.c~host-skas3-2.6.8.1-v6	2004-10-18 19:02:18.245815160 +0200
-+++ vanilla-linux-2.6.8.1-paolo/mm/proc_mm.c	2004-10-18 19:02:18.301806648 +0200
-@@ -0,0 +1,181 @@
-+/*
-+ * Copyright (C) 2002 Jeff Dike (jdike at karaya.com)
-+ * Licensed under the GPL
-+ */
-+
-+#include "linux/mm.h"
-+#include "linux/init.h"
-+#include "linux/proc_fs.h"
-+#include "linux/proc_mm.h"
-+#include "linux/file.h"
-+#include "linux/mman.h"
-+#include "asm/uaccess.h"
-+#include "asm/mmu_context.h"
-+
-+static struct file_operations proc_mm_fops;
-+
-+struct mm_struct *proc_mm_get_mm(int fd)
-+{
-+	struct mm_struct *ret = ERR_PTR(-EBADF);
-+	struct file *file;
-+
-+	file = fget(fd);
-+	if (!file)
-+		goto out;
-+
-+	ret = ERR_PTR(-EINVAL);
-+	if(file->f_op != &proc_mm_fops)
-+		goto out_fput;
-+
-+	ret = file->private_data;
-+ out_fput:
-+	fput(file);
-+ out:
-+	return(ret);
-+}
-+
-+extern long do_mmap2(struct mm_struct *mm, unsigned long addr,
-+		     unsigned long len, unsigned long prot,
-+		     unsigned long flags, unsigned long fd,
-+		     unsigned long pgoff);
-+
-+static ssize_t write_proc_mm(struct file *file, const char *buffer,
-+			     size_t count, loff_t *ppos)
-+{
-+	struct mm_struct *mm = file->private_data;
-+	struct proc_mm_op req;
-+	int n, ret;
-+
-+	if(count > sizeof(req))
-+		return(-EINVAL);
-+
-+	n = copy_from_user(&req, buffer, count);
-+	if(n != 0)
-+		return(-EFAULT);
-+
-+	ret = count;
-+	switch(req.op){
-+	case MM_MMAP: {
-+		struct mm_mmap *map = &req.u.mmap;
-+
-+		/* Nobody ever noticed it, but do_mmap_pgoff() calls
-+		 * get_unmapped_area() which checks current->mm, if
-+		 * MAP_FIXED is not set, so mmap() could replace
-+		 * an old mapping.
-+		 */
-+		if (! (map->flags & MAP_FIXED))
-+			return(-EINVAL);
-+
-+		ret = do_mmap2(mm, map->addr, map->len, map->prot,
-+			       map->flags, map->fd, map->offset >> PAGE_SHIFT);
-+		if((ret & ~PAGE_MASK) == 0)
-+			ret = count;
-+
-+		break;
-+	}
-+	case MM_MUNMAP: {
-+		struct mm_munmap *unmap = &req.u.munmap;
-+
-+		down_write(&mm->mmap_sem);
-+		ret = do_munmap(mm, unmap->addr, unmap->len);
-+		up_write(&mm->mmap_sem);
-+
-+		if(ret == 0)
-+			ret = count;
-+		break;
-+	}
-+	case MM_MPROTECT: {
-+		struct mm_mprotect *protect = &req.u.mprotect;
-+
-+		ret = do_mprotect(mm, protect->addr, protect->len,
-+				  protect->prot);
-+		if(ret == 0)
-+			ret = count;
-+		break;
-+	}
-+
-+	case MM_COPY_SEGMENTS: {
-+		struct mm_struct *from = proc_mm_get_mm(req.u.copy_segments);
-+
-+		if(IS_ERR(from)){
-+			ret = PTR_ERR(from);
-+			break;
-+		}
-+
-+		ret = copy_context(mm, from);
-+		if(ret == 0)
-+			ret = count;
-+		break;
-+	}
-+	default:
-+		ret = -EINVAL;
-+		break;
-+	}
-+
-+	return(ret);
-+}
-+
-+static int open_proc_mm(struct inode *inode, struct file *file)
-+{
-+	struct mm_struct *mm = mm_alloc();
-+	int ret;
-+
-+	ret = -ENOMEM;
-+	if(mm == NULL)
-+		goto out_mem;
-+
-+	init_new_empty_context(mm);
-+
-+	spin_lock(&mmlist_lock);
-+	list_add(&mm->mmlist, &current->mm->mmlist);
-+	mmlist_nr++;
-+	spin_unlock(&mmlist_lock);
-+
-+	file->private_data = mm;
-+
-+	return(0);
-+
-+ out_mem:
-+	return(ret);
-+}
-+
-+static int release_proc_mm(struct inode *inode, struct file *file)
-+{
-+	struct mm_struct *mm = file->private_data;
-+
-+	mmput(mm);
-+	return(0);
-+}
-+
-+static struct file_operations proc_mm_fops = {
-+	.open		= open_proc_mm,
-+	.release	= release_proc_mm,
-+	.write		= write_proc_mm,
-+};
-+
-+static int make_proc_mm(void)
-+{
-+	struct proc_dir_entry *ent;
-+
-+	ent = create_proc_entry("mm", 0222, &proc_root);
-+	if(ent == NULL){
-+		printk("make_proc_mm : Failed to register /proc/mm\n");
-+		return(0);
-+	}
-+	ent->proc_fops = &proc_mm_fops;
-+
-+	return(0);
-+}
-+
-+__initcall(make_proc_mm);
-+
-+/*
-+ * Overrides for Emacs so that we follow Linus's tabbing style.
-+ * Emacs will notice this stuff at the end of the file and automatically
-+ * adjust the settings for this buffer only.  This must remain at the end
-+ * of the file.
-+ * ---------------------------------------------------------------------------
-+ * Local variables:
-+ * c-file-style: "linux"
-+ * End:
-+ */
-_

Deleted: trunk/src/kernel-patch-skas/host-skas3-2.6.9-v7.patch
===================================================================
--- trunk/src/kernel-patch-skas/host-skas3-2.6.9-v7.patch	2006-08-27 15:01:30 UTC (rev 166)
+++ trunk/src/kernel-patch-skas/host-skas3-2.6.9-v7.patch	2006-08-27 15:16:57 UTC (rev 167)
@@ -1,871 +0,0 @@
---- vanilla-linux-2.6.9-paolo/arch/i386/kernel/entry.S	2004-10-26 02:24:42.196918400 +0200
-+++ vanilla-linux-2.6.9-paolo/arch/i386/kernel/entry.S	2004-10-26 02:24:46.219306904 +0200
-@@ -256,7 +256,7 @@
- 	SAVE_ALL
- 	GET_THREAD_INFO(%ebp)
- 
--	testb $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT),TI_flags(%ebp)
-+	testb $(_TIF_SYSCALL_EMU|_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT),TI_flags(%ebp)
- 	jnz syscall_trace_entry
- 	cmpl $(nr_syscalls), %eax
- 	jae syscall_badsys
-@@ -278,8 +278,8 @@
- 	pushl %eax			# save orig_eax
- 	SAVE_ALL
- 	GET_THREAD_INFO(%ebp)
--					# system call tracing in operation
--	testb $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT),TI_flags(%ebp)
-+					# system call tracing in operation / emulation
-+	testb $(_TIF_SYSCALL_EMU|_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT),TI_flags(%ebp)
- 	jnz syscall_trace_entry
- 	cmpl $(nr_syscalls), %eax
- 	jae syscall_badsys
-@@ -340,6 +340,9 @@
- 	movl %esp, %eax
- 	xorl %edx,%edx
- 	call do_syscall_trace
-+	cmpl $0, %eax
-+	jne syscall_exit		# ret != 0 -> running under PTRACE_SYSEMU,
-+					# so must skip actual syscall
- 	movl ORIG_EAX(%esp), %eax
- 	cmpl $(nr_syscalls), %eax
- 	jnae syscall_call
---- vanilla-linux-2.6.9-paolo/arch/i386/kernel/ptrace.c	2004-10-29 00:52:30.744281064 +0200
-+++ vanilla-linux-2.6.9-paolo/arch/i386/kernel/ptrace.c	2004-10-29 00:52:34.737673976 +0200
-@@ -15,6 +15,7 @@
- #include <linux/user.h>
- #include <linux/security.h>
- #include <linux/audit.h>
-+#include <linux/proc_mm.h>
- 
- #include <asm/uaccess.h>
- #include <asm/pgtable.h>
-@@ -358,6 +359,7 @@
- 		  }
- 		  break;
- 
-+	case PTRACE_SYSEMU: /* continue and stop at next syscall, which will not be executed */
- 	case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
- 	case PTRACE_CONT: { /* restart after signal. */
- 		long tmp;
-@@ -365,10 +367,21 @@
- 		ret = -EIO;
- 		if ((unsigned long) data > _NSIG)
- 			break;
-+		/* If we came here with PTRACE_SYSEMU and now continue with
-+		 * PTRACE_SYSCALL, entry.S used to intercept the syscall return.
-+		 * But it shouldn't!
-+		 * So we don't clear TIF_SYSCALL_EMU, which is always unused in
-+		 * this special case, to remember, we came from SYSEMU. That
-+		 * flag will be cleared by do_syscall_trace().
-+		 */
-+		if (request == PTRACE_SYSEMU) {
-+			set_tsk_thread_flag(child, TIF_SYSCALL_EMU);
-+		} else if (request == PTRACE_CONT) {
-+			clear_tsk_thread_flag(child, TIF_SYSCALL_EMU);
-+		}
- 		if (request == PTRACE_SYSCALL) {
- 			set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
--		}
--		else {
-+		} else {
- 			clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- 		}
- 		clear_tsk_thread_flag(child, TIF_SINGLESTEP);
-@@ -407,6 +420,8 @@
- 		ret = -EIO;
- 		if ((unsigned long) data > _NSIG)
- 			break;
-+		/*See do_syscall_trace to know why we don't clear
-+		 * TIF_SYSCALL_EMU.*/
- 		clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- 		if ((child->ptrace & PT_DTRACE) == 0) {
- 			/* Spurious delayed TF traps may occur */
-@@ -513,6 +528,56 @@
- 					(struct user_desc __user *) data);
- 		break;
- 
-+#ifdef CONFIG_PROC_MM
-+	case PTRACE_FAULTINFO: {
-+		struct ptrace_faultinfo fault;
-+
-+		fault = ((struct ptrace_faultinfo)
-+			{ .is_write	= child->thread.error_code,
-+			  .addr		= child->thread.cr2 });
-+		ret = copy_to_user((unsigned long *) data, &fault,
-+				   sizeof(fault));
-+		if(ret)
-+			break;
-+		break;
-+	}
-+
-+	case PTRACE_SIGPENDING:
-+		ret = copy_to_user((unsigned long *) data,
-+				   &child->pending.signal,
-+				   sizeof(child->pending.signal));
-+		break;
-+
-+	case PTRACE_LDT: {
-+		struct ptrace_ldt ldt;
-+
-+		if(copy_from_user(&ldt, (unsigned long *) data,
-+				  sizeof(ldt))){
-+			ret = -EIO;
-+			break;
-+		}
-+		ret = modify_ldt(child->mm, ldt.func, ldt.ptr, ldt.bytecount);
-+		break;
-+	}
-+
-+	case PTRACE_SWITCH_MM: {
-+		struct mm_struct *old = child->mm;
-+		struct mm_struct *new = proc_mm_get_mm(data);
-+
-+		if(IS_ERR(new)){
-+			ret = PTR_ERR(new);
-+			break;
-+		}
-+
-+		atomic_inc(&new->mm_users);
-+		child->mm = new;
-+		child->active_mm = new;
-+		mmput(old);
-+		ret = 0;
-+		break;
-+	}
-+#endif
-+
- 	default:
- 		ret = ptrace_request(child, request, addr, data);
- 		break;
-@@ -528,8 +593,9 @@
-  * - triggered by current->work.syscall_trace
-  */
- __attribute__((regparm(3)))
--void do_syscall_trace(struct pt_regs *regs, int entryexit)
-+int do_syscall_trace(struct pt_regs *regs, int entryexit)
- {
-+	int is_sysemu, is_systrace, is_singlestep;
- 	if (unlikely(current->audit_context)) {
- 		if (!entryexit)
- 			audit_syscall_entry(current, regs->orig_eax,
-@@ -538,16 +604,27 @@
- 		else
- 			audit_syscall_exit(current, regs->eax);
- 	}
-+	is_sysemu = test_thread_flag(TIF_SYSCALL_EMU);
-+	is_systrace = test_thread_flag(TIF_SYSCALL_TRACE);
-+	is_singlestep = test_thread_flag(TIF_SINGLESTEP);
- 
--	if (!test_thread_flag(TIF_SYSCALL_TRACE) &&
--	    !test_thread_flag(TIF_SINGLESTEP))
--		return;
-+	if (!is_systrace && !is_singlestep && !is_sysemu)
-+		return 0;
-+	/* We can detect the case of coming from PTRACE_SYSEMU and now running
-+	 * with PTRACE_SYSCALL or PTRACE_SINGLESTEP, by TIF_SYSCALL_EMU being
-+	 * set additionally.
-+	 * If so let's reset the flag and return without action.
-+	 */
-+	if (is_sysemu && (is_systrace || is_singlestep)) {
-+		clear_thread_flag(TIF_SYSCALL_EMU);
-+		return 0;
-+	}
- 	if (!(current->ptrace & PT_PTRACED))
--		return;
-+		return 0;
- 	/* the 0x80 provides a way for the tracing parent to distinguish
- 	   between a syscall stop and SIGTRAP delivery */
- 	ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) &&
--				 !test_thread_flag(TIF_SINGLESTEP) ? 0x80 : 0));
-+				 !is_singlestep ? 0x80 : 0));
- 
- 	/*
- 	 * this isn't the same as continuing with a signal, but it will do
-@@ -560,2 +637,4 @@
- 	}
-+	/* != 0 if nullifying the syscall, 0 if running it normally */
-+	return is_sysemu;
- }
---- vanilla-linux-2.6.9/include/asm-i386/thread_info.h~host-sysemu-2.6.7-4	2004-10-26 02:24:42.191919160 +0200
-+++ vanilla-linux-2.6.9-paolo/include/asm-i386/thread_info.h	2004-10-26 02:24:42.197918248 +0200
-@@ -143,6 +143,7 @@ static inline unsigned long current_stac
- #define TIF_NEED_RESCHED	3	/* rescheduling necessary */
- #define TIF_SINGLESTEP		4	/* restore singlestep on return to user mode */
- #define TIF_IRET		5	/* return with iret */
-+#define TIF_SYSCALL_EMU		6	/* syscall emulation active */
- #define TIF_SYSCALL_AUDIT	7	/* syscall auditing active */
- #define TIF_POLLING_NRFLAG	16	/* true if poll_idle() is polling TIF_NEED_RESCHED */
- 
-@@ -152,12 +153,14 @@ static inline unsigned long current_stac
- #define _TIF_NEED_RESCHED	(1<<TIF_NEED_RESCHED)
- #define _TIF_SINGLESTEP		(1<<TIF_SINGLESTEP)
- #define _TIF_IRET		(1<<TIF_IRET)
-+#define _TIF_SYSCALL_EMU	(1<<TIF_SYSCALL_EMU)
- #define _TIF_SYSCALL_AUDIT	(1<<TIF_SYSCALL_AUDIT)
- #define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
- 
- /* work to do on interrupt/exception return */
- #define _TIF_WORK_MASK \
--  (0x0000FFFF & ~(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP))
-+  (0x0000FFFF & ~(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP|\
-+		  _TIF_SYSCALL_EMU))
- #define _TIF_ALLWORK_MASK	0x0000FFFF	/* work to do on any return to u-space */
- 
- /*
---- vanilla-linux-2.6.9-paolo/include/linux/ptrace.h	2004-10-26 02:24:42.197918248 +0200
-+++ vanilla-linux-2.6.9-paolo/include/linux/ptrace.h	2004-10-26 02:24:46.218307056 +0200
-@@ -20,6 +20,7 @@
- #define PTRACE_DETACH		0x11
- 
- #define PTRACE_SYSCALL		  24
-+#define PTRACE_SYSEMU		  31
- 
- /* 0x4200-0x4300 are reserved for architecture-independent additions.  */
- #define PTRACE_SETOPTIONS	0x4200
---- vanilla-linux-2.6.9-paolo/kernel/fork.c	2004-10-26 02:24:42.197918248 +0200
-+++ vanilla-linux-2.6.9-paolo/kernel/fork.c	2004-10-26 01:59:51.388555720 +0200
-@@ -1040,6 +1040,9 @@
- 	 * of CLONE_PTRACE.
- 	 */
- 	clear_tsk_thread_flag(p, TIF_SYSCALL_TRACE);
-+#ifdef TIF_SYSCALL_EMU
-+	clear_tsk_thread_flag(p, TIF_SYSCALL_EMU);
-+#endif
- 
- 	/* Our parent execution domain becomes current domain
- 	   These must match for thread signalling to apply */
---- vanilla-linux-2.6.9/include/linux/mm.h~Add_generic_proc_mm_support	2004-10-26 00:46:35.058899416 +0200
-+++ vanilla-linux-2.6.9-paolo/include/linux/mm.h	2004-10-26 00:46:35.090894552 +0200
-@@ -623,6 +623,9 @@ struct shrinker;
- extern struct shrinker *set_shrinker(int, shrinker_t);
- extern void remove_shrinker(struct shrinker *shrinker);
- 
-+extern long do_mprotect(struct mm_struct *mm, unsigned long start,
-+			size_t len, unsigned long prot);
-+
- /*
-  * On a two-level page table, this ends up being trivial. Thus the
-  * inlining and the symmetry break with pte_alloc_map() that does all
-@@ -682,9 +685,15 @@ extern void exit_mmap(struct mm_struct *
- 
- extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
- 
--extern unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
-+extern unsigned long __do_mmap_pgoff(struct mm_struct *mm, struct file *file,
-+				   unsigned long addr, unsigned long len,
-+				   unsigned long prot, unsigned long flag,
-+				   unsigned long pgoff);
-+static inline unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
- 	unsigned long len, unsigned long prot,
--	unsigned long flag, unsigned long pgoff);
-+	unsigned long flag, unsigned long pgoff) {
-+	return __do_mmap_pgoff(current->mm, file, addr, len, prot, flag, pgoff);
-+}
- 
- static inline unsigned long do_mmap(struct file *file, unsigned long addr,
- 	unsigned long len, unsigned long prot,
---- vanilla-linux-2.6.9/include/linux/proc_mm.h~Add_generic_proc_mm_support	2004-10-26 00:46:35.059899264 +0200
-+++ vanilla-linux-2.6.9-paolo/include/linux/proc_mm.h	2004-10-26 00:46:35.090894552 +0200
-@@ -0,0 +1,48 @@
-+/*
-+ * Copyright (C) 2002 Jeff Dike (jdike at karaya.com)
-+ * Licensed under the GPL
-+ */
-+
-+#ifndef __PROC_MM_H
-+#define __PROC_MM_H
-+
-+#include "linux/sched.h"
-+
-+#define MM_MMAP 54
-+#define MM_MUNMAP 55
-+#define MM_MPROTECT 56
-+#define MM_COPY_SEGMENTS 57
-+
-+struct mm_mmap {
-+	unsigned long addr;
-+	unsigned long len;
-+	unsigned long prot;
-+	unsigned long flags;
-+	unsigned long fd;
-+	unsigned long offset;
-+};
-+
-+struct mm_munmap {
-+	unsigned long addr;
-+	unsigned long len;
-+};
-+
-+struct mm_mprotect {
-+	unsigned long addr;
-+	unsigned long len;
-+        unsigned int prot;
-+};
-+
-+struct proc_mm_op {
-+	int op;
-+	union {
-+		struct mm_mmap mmap;
-+		struct mm_munmap munmap;
-+	        struct mm_mprotect mprotect;
-+		int copy_segments;
-+	} u;
-+};
-+
-+extern struct mm_struct *proc_mm_get_mm(int fd);
-+
-+#endif
---- vanilla-linux-2.6.9/mm/Makefile~Add_generic_proc_mm_support	2004-10-26 00:46:35.060899112 +0200
-+++ vanilla-linux-2.6.9-paolo/mm/Makefile	2004-10-26 00:46:35.091894400 +0200
-@@ -18,3 +18,4 @@ obj-$(CONFIG_NUMA) 	+= mempolicy.o
- obj-$(CONFIG_SHMEM) += shmem.o
- obj-$(CONFIG_TINY_SHMEM) += tiny-shmem.o
- 
-+obj-$(CONFIG_PROC_MM)	+= proc_mm.o
---- vanilla-linux-2.6.9/mm/mmap.c~Add_generic_proc_mm_support	2004-10-26 00:46:35.061898960 +0200
-+++ vanilla-linux-2.6.9-paolo/mm/mmap.c	2004-10-26 00:46:35.091894400 +0200
-@@ -759,11 +759,11 @@ void __vm_stat_account(struct mm_struct 
-  * The caller must hold down_write(current->mm->mmap_sem).
-  */
- 
--unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
--			unsigned long len, unsigned long prot,
--			unsigned long flags, unsigned long pgoff)
-+unsigned long __do_mmap_pgoff(struct mm_struct *mm, struct file * file,
-+			    unsigned long addr, unsigned long len,
-+			    unsigned long prot, unsigned long flags,
-+			    unsigned long pgoff)
- {
--	struct mm_struct * mm = current->mm;
- 	struct vm_area_struct * vma, * prev;
- 	struct inode *inode;
- 	unsigned int vm_flags;
-@@ -1034,7 +1034,7 @@ unacct_error:
- 	return error;
- }
- 
--EXPORT_SYMBOL(do_mmap_pgoff);
-+EXPORT_SYMBOL(__do_mmap_pgoff);
- 
- /* Get an address range which is currently unmapped.
-  * For shmat() with addr=0.
---- vanilla-linux-2.6.9-paolo/mm/mprotect.c	2004-10-26 00:46:35.092894248 +0200
-+++ linux-2.6.9-current-paolo/mm/mprotect.c	2004-10-14 18:35:43.018815232 +0200
-@@ -92,19 +92,20 @@
- {
- 	pgd_t *dir;
- 	unsigned long beg = start;
-+	struct mm_struct * mm = vma->vm_mm;
- 
--	dir = pgd_offset(current->mm, start);
-+	dir = pgd_offset(mm, start);
- 	flush_cache_range(vma, beg, end);
- 	if (start >= end)
- 		BUG();
--	spin_lock(&current->mm->page_table_lock);
-+	spin_lock(&mm->page_table_lock);
- 	do {
- 		change_pmd_range(dir, start, end - start, newprot);
- 		start = (start + PGDIR_SIZE) & PGDIR_MASK;
- 		dir++;
- 	} while (start && (start < end));
- 	flush_tlb_range(vma, beg, end);
--	spin_unlock(&current->mm->page_table_lock);
-+	spin_unlock(&mm->page_table_lock);
- 	return;
- }
- 
-@@ -187,8 +188,9 @@
- 	return error;
- }
- 
--asmlinkage long
--sys_mprotect(unsigned long start, size_t len, unsigned long prot)
-+long
-+do_mprotect(struct mm_struct *mm, unsigned long start, size_t len,
-+	     unsigned long prot)
- {
- 	unsigned long vm_flags, nstart, end, tmp;
- 	struct vm_area_struct *vma, *prev;
-@@ -217,9 +219,9 @@
- 
- 	vm_flags = calc_vm_prot_bits(prot);
- 
--	down_write(&current->mm->mmap_sem);
-+	down_write(&mm->mmap_sem);
- 
--	vma = find_vma_prev(current->mm, start, &prev);
-+	vma = find_vma_prev(mm, start, &prev);
- 	error = -ENOMEM;
- 	if (!vma)
- 		goto out;
-@@ -288,3 +290,8 @@
--	up_write(&current->mm->mmap_sem);
-+	up_write(&mm->mmap_sem);
- 	return error;
- }
-+
-+asmlinkage long sys_mprotect(unsigned long start, size_t len, unsigned long prot)
-+{
-+        return(do_mprotect(current->mm, start, len, prot));
-+}
---- linux-2.6.9-current-paolo/mm/proc_mm.c	2004-10-14 18:35:43.019815080 +0200
-+++ linux-2.6.9-current-paolo/mm/proc_mm.c	2004-10-14 18:42:05.146722960 +0200
-@@ -0,0 +1,182 @@
-+/*
-+ * Copyright (C) 2002 Jeff Dike (jdike at karaya.com)
-+ * Licensed under the GPL
-+ */
-+
-+#include "linux/mm.h"
-+#include "linux/init.h"
-+#include "linux/proc_fs.h"
-+#include "linux/proc_mm.h"
-+#include "linux/file.h"
-+#include "linux/mman.h"
-+#include "asm/uaccess.h"
-+#include "asm/mmu_context.h"
-+
-+static struct file_operations proc_mm_fops;
-+
-+struct mm_struct *proc_mm_get_mm(int fd)
-+{
-+	struct mm_struct *ret = ERR_PTR(-EBADF);
-+	struct file *file;
-+
-+	file = fget(fd);
-+	if (!file)
-+		goto out;
-+
-+	ret = ERR_PTR(-EINVAL);
-+	if(file->f_op != &proc_mm_fops)
-+		goto out_fput;
-+
-+	ret = file->private_data;
-+ out_fput:
-+	fput(file);
-+ out:
-+	return(ret);
-+}
-+
-+extern long do_mmap2(struct mm_struct *mm, unsigned long addr,
-+		     unsigned long len, unsigned long prot,
-+		     unsigned long flags, unsigned long fd,
-+		     unsigned long pgoff);
-+
-+static ssize_t write_proc_mm(struct file *file, const char *buffer,
-+			     size_t count, loff_t *ppos)
-+{
-+	struct mm_struct *mm = file->private_data;
-+	struct proc_mm_op req;
-+	int n, ret;
-+
-+	if(count > sizeof(req))
-+		return(-EINVAL);
-+
-+	n = copy_from_user(&req, buffer, count);
-+	if(n != 0)
-+		return(-EFAULT);
-+
-+	ret = count;
-+	switch(req.op){
-+	case MM_MMAP: {
-+		struct mm_mmap *map = &req.u.mmap;
-+
-+		/* Nobody ever noticed it, but do_mmap_pgoff() calls
-+		 * get_unmapped_area() which checks current->mm, if
-+		 * MAP_FIXED is not set, so mmap() could replace
-+		 * an old mapping.
-+		 */
-+		if (! (map->flags & MAP_FIXED))
-+			return(-EINVAL);
-+
-+		ret = do_mmap2(mm, map->addr, map->len, map->prot,
-+			       map->flags, map->fd, map->offset >> PAGE_SHIFT);
-+		if((ret & ~PAGE_MASK) == 0)
-+			ret = count;
-+
-+		break;
-+	}
-+	case MM_MUNMAP: {
-+		struct mm_munmap *unmap = &req.u.munmap;
-+
-+		down_write(&mm->mmap_sem);
-+		ret = do_munmap(mm, unmap->addr, unmap->len);
-+		up_write(&mm->mmap_sem);
-+
-+		if(ret == 0)
-+			ret = count;
-+		break;
-+	}
-+	case MM_MPROTECT: {
-+		struct mm_mprotect *protect = &req.u.mprotect;
-+
-+		ret = do_mprotect(mm, protect->addr, protect->len,
-+				  protect->prot);
-+		if(ret == 0)
-+			ret = count;
-+		break;
-+	}
-+
-+	case MM_COPY_SEGMENTS: {
-+		struct mm_struct *from = proc_mm_get_mm(req.u.copy_segments);
-+
-+		if(IS_ERR(from)){
-+			ret = PTR_ERR(from);
-+			break;
-+		}
-+
-+		ret = copy_context(mm, from);
-+		if(ret == 0)
-+			ret = count;
-+		break;
-+	}
-+	default:
-+		ret = -EINVAL;
-+		break;
-+	}
-+
-+	return(ret);
-+}
-+
-+static int open_proc_mm(struct inode *inode, struct file *file)
-+{
-+	struct mm_struct *mm = mm_alloc();
-+	int ret;
-+
-+	ret = -ENOMEM;
-+	if(mm == NULL)
-+		goto out_mem;
-+
-+	init_new_empty_context(mm);
-+	arch_pick_mmap_layout(mm);
-+
-+	spin_lock(&mmlist_lock);
-+	list_add(&mm->mmlist, &current->mm->mmlist);
-+	mmlist_nr++;
-+	spin_unlock(&mmlist_lock);
-+
-+	file->private_data = mm;
-+
-+	return(0);
-+
-+ out_mem:
-+	return(ret);
-+}
-+
-+static int release_proc_mm(struct inode *inode, struct file *file)
-+{
-+	struct mm_struct *mm = file->private_data;
-+
-+	mmput(mm);
-+	return(0);
-+}
-+
-+static struct file_operations proc_mm_fops = {
-+	.open		= open_proc_mm,
-+	.release	= release_proc_mm,
-+	.write		= write_proc_mm,
-+};
-+
-+static int make_proc_mm(void)
-+{
-+	struct proc_dir_entry *ent;
-+
-+	ent = create_proc_entry("mm", 0222, &proc_root);
-+	if(ent == NULL){
-+		printk("make_proc_mm : Failed to register /proc/mm\n");
-+		return(0);
-+	}
-+	ent->proc_fops = &proc_mm_fops;
-+
-+	return(0);
-+}
-+
-+__initcall(make_proc_mm);
-+
-+/*
-+ * Overrides for Emacs so that we follow Linus's tabbing style.
-+ * Emacs will notice this stuff at the end of the file and automatically
-+ * adjust the settings for this buffer only.  This must remain at the end
-+ * of the file.
-+ * ---------------------------------------------------------------------------
-+ * Local variables:
-+ * c-file-style: "linux"
-+ * End:
-+ */
---- vanilla-linux-2.6.9/arch/i386/Kconfig~i386-specific	2004-10-29 00:52:34.701679448 +0200
-+++ vanilla-linux-2.6.9-paolo/arch/i386/Kconfig	2004-10-29 00:52:34.709678232 +0200
-@@ -724,6 +724,10 @@ config X86_PAE
- 	depends on HIGHMEM64G
- 	default y
- 
-+config PROC_MM
-+	bool "/proc/mm support"
-+	default y
-+
- # Common NUMA Features
- config NUMA
- 	bool "Numa Memory Allocation and Scheduler Support"
---- vanilla-linux-2.6.9-paolo/arch/i386/kernel/ldt.c	2004-10-29 00:52:34.737673976 +0200
-+++ linux-2.6.9-current-paolo/arch/i386/kernel/ldt.c	2004-10-14 18:27:44.384578696 +0200
-@@ -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)
-@@ -54,7 +55,7 @@
- 	pc->size = mincount;
- 	wmb();
- 
--	if (reload) {
-+	if (reload && (&current->active_mm->context == pc)) {
- #ifdef CONFIG_SMP
- 		cpumask_t mask;
- 		preempt_disable();
-@@ -89,14 +90,10 @@
-  * we do not have to muck with descriptors here, that is
-  * done in switch_mm() as needed.
-  */
--int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
-+int copy_context(struct mm_struct *mm, struct mm_struct *old_mm)
- {
--	struct mm_struct * old_mm;
- 	int retval = 0;
- 
--	init_MUTEX(&mm->context.sem);
--	mm->context.size = 0;
--	old_mm = current->mm;
- 	if (old_mm && old_mm->context.size > 0) {
- 		down(&old_mm->context.sem);
- 		retval = copy_ldt(&mm->context, &old_mm->context);
-@@ -105,6 +102,12 @@
- 	return retval;
- }
- 
-+int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
-+{
-+	init_new_empty_context(mm);
-+	return copy_context(mm, current->mm);
-+}
-+
- /*
-  * No need to lock the MM as we are the last user
-  */
-@@ -121,11 +124,11 @@
- 	}
- }
- 
--static int read_ldt(void __user * ptr, unsigned long bytecount)
-+static int read_ldt(struct mm_struct * mm, void __user * ptr,
-+		    unsigned long bytecount)
- {
- 	int err;
- 	unsigned long size;
--	struct mm_struct * mm = current->mm;
- 
- 	if (!mm->context.size)
- 		return 0;
-@@ -174,9 +177,8 @@
- 	return err;
- }
- 
--static int write_ldt(void __user * ptr, unsigned long bytecount, int oldmode)
-+static int write_ldt(struct mm_struct * mm, void __user * ptr, unsigned long bytecount, int oldmode)
- {
--	struct mm_struct * mm = current->mm;
- 	__u32 entry_1, entry_2, *lp;
- 	int error;
- 	struct user_desc ldt_info;
-@@ -200,7 +202,7 @@
- 
- 	down(&mm->context.sem);
- 	if (ldt_info.entry_number >= mm->context.size) {
--		error = alloc_ldt(&current->mm->context, ldt_info.entry_number+1, 1);
-+		error = alloc_ldt(&mm->context, ldt_info.entry_number+1, 1);
- 		if (error < 0)
- 			goto out_unlock;
- 	}
-@@ -236,20 +238,26 @@
--asmlinkage int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
-+int modify_ldt(struct mm_struct * mm, int func, void __user *ptr,
-+	       unsigned long bytecount)
- {
- 	int ret = -ENOSYS;
- 
- 	switch (func) {
- 	case 0:
--		ret = read_ldt(ptr, bytecount);
-+		ret = read_ldt(mm, ptr, bytecount);
- 		break;
- 	case 1:
--		ret = write_ldt(ptr, bytecount, 1);
-+		ret = write_ldt(mm, ptr, bytecount, 1);
- 		break;
- 	case 2:
- 		ret = read_default_ldt(ptr, bytecount);
- 		break;
- 	case 0x11:
--		ret = write_ldt(ptr, bytecount, 0);
-+		ret = write_ldt(mm, ptr, bytecount, 0);
- 		break;
- 	}
- 	return ret;
- }
-+
-+asmlinkage int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
-+{
-+	return modify_ldt(current->mm, func, ptr, bytecount);
-+}
---- vanilla-linux-2.6.9/arch/i386/kernel/sys_i386.c~i386-specific	2004-10-29 00:52:34.704678992 +0200
-+++ vanilla-linux-2.6.9-paolo/arch/i386/kernel/sys_i386.c	2004-10-29 00:52:34.738673824 +0200
-@@ -41,7 +41,7 @@ asmlinkage int sys_pipe(unsigned long __
- }
- 
- /* common code for old and new mmaps */
--static inline long do_mmap2(
-+long do_mmap2(struct mm_struct *mm,
- 	unsigned long addr, unsigned long len,
- 	unsigned long prot, unsigned long flags,
- 	unsigned long fd, unsigned long pgoff)
-@@ -56,9 +56,9 @@ static inline long do_mmap2(
- 			goto out;
- 	}
- 
--	down_write(&current->mm->mmap_sem);
--	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
--	up_write(&current->mm->mmap_sem);
-+	down_write(&mm->mmap_sem);
-+	error = __do_mmap_pgoff(mm, file, addr, len, prot, flags, pgoff);
-+	up_write(&mm->mmap_sem);
- 
- 	if (file)
- 		fput(file);
-@@ -70,7 +70,7 @@ asmlinkage long sys_mmap2(unsigned long 
- 	unsigned long prot, unsigned long flags,
- 	unsigned long fd, unsigned long pgoff)
- {
--	return do_mmap2(addr, len, prot, flags, fd, pgoff);
-+	return do_mmap2(current->mm, addr, len, prot, flags, fd, pgoff);
- }
- 
- /*
-@@ -101,7 +101,7 @@ asmlinkage int old_mmap(struct mmap_arg_
- 	if (a.offset & ~PAGE_MASK)
- 		goto out;
- 
--	err = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
-+	err = do_mmap2(current->mm, a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
- out:
- 	return err;
- }
---- vanilla-linux-2.6.9/include/asm-i386/desc.h~i386-specific	2004-10-29 00:52:34.705678840 +0200
-+++ vanilla-linux-2.6.9-paolo/include/asm-i386/desc.h	2004-10-29 00:52:34.738673824 +0200
-@@ -126,6 +126,9 @@ static inline void load_LDT(mm_context_t
- 	put_cpu();
- }
- 
-+extern int modify_ldt(struct mm_struct * mm, int func, void __user *ptr,
-+		      unsigned long bytecount);
-+
- #endif /* !__ASSEMBLY__ */
- 
- #endif
---- vanilla-linux-2.6.9/include/asm-i386/ptrace.h~i386-specific	2004-10-29 00:52:34.707678536 +0200
-+++ vanilla-linux-2.6.9-paolo/include/asm-i386/ptrace.h	2004-10-29 00:52:34.738673824 +0200
-@@ -64,4 +64,26 @@ extern unsigned long profile_pc(struct p
- #endif
- #endif
- 
-+/*For SKAS3 support.*/
-+#ifndef _LINUX_PTRACE_STRUCT_DEF
-+#define _LINUX_PTRACE_STRUCT_DEF
-+
-+#define PTRACE_FAULTINFO	  52
-+#define PTRACE_SIGPENDING	  53
-+#define PTRACE_LDT		  54
-+#define PTRACE_SWITCH_MM 	  55
-+
-+struct ptrace_faultinfo {
-+	int is_write;
-+	unsigned long addr;
-+};
-+
-+struct ptrace_ldt {
-+	int func;
-+  	void *ptr;
-+	unsigned long bytecount;
-+};
-+
-+#endif /*ifndef _LINUX_PTRACE_STRUCT_DEF*/
-+
- #endif
---- linux-2.6.9-current-paolo/include/asm-i386/mmu_context.h	2004-10-14 18:27:17.059732704 +0200
-+++ linux-2.6.9-current-paolo/include/asm-i386/mmu_context.h	2004-10-14 18:27:44.384578696 +0200
-@@ -6,13 +6,25 @@
- #include <asm/atomic.h>
- #include <asm/pgalloc.h>
- #include <asm/tlbflush.h>
-+#include <asm/semaphore.h>
- 
- /*
-- * Used for LDT copy/destruction.
-+ * Used for LDT initialization/destruction. You cannot copy an LDT with
-+ * init_new_context, since it thinks you are passing it a new LDT and won't
-+ * deallocate its old content.
-  */
- int init_new_context(struct task_struct *tsk, struct mm_struct *mm);
- void destroy_context(struct mm_struct *mm);
- 
-+/* LDT initialization for a clean environment - needed for SKAS.*/
-+static inline void init_new_empty_context(struct mm_struct *mm)
-+{
-+	init_MUTEX(&mm->context.sem);
-+	mm->context.size = 0;
-+}
-+
-+/* LDT copy for SKAS - for the above problem.*/
-+int copy_context(struct mm_struct *mm, struct mm_struct *old_mm);
- 
- static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
- {
-@@ -29,6 +41,10 @@
- {
- 	int cpu = smp_processor_id();
- 
-+#ifdef CONFIG_SMP
-+	prev = per_cpu(cpu_tlbstate, cpu).active_mm;
-+#endif
-+
- 	if (likely(prev != next)) {
- 		/* stop flush ipis for the previous mm */
- 		cpu_clear(cpu, prev->cpu_vm_mask);
-@@ -50,7 +66,6 @@
- #ifdef CONFIG_SMP
- 	else {
- 		per_cpu(cpu_tlbstate, cpu).state = TLBSTATE_OK;
--		BUG_ON(per_cpu(cpu_tlbstate, cpu).active_mm != next);
- 
- 		if (!cpu_test_and_set(cpu, next->cpu_vm_mask)) {
- 			/* We were in lazy tlb mode and leave_mm disabled 
---- vanilla-linux-2.6.9/arch/um/include/skas_ptrace.h~make-skas-uml-compatible	2004-10-26 01:59:51.352561192 +0200
-+++ vanilla-linux-2.6.9-paolo/arch/um/include/skas_ptrace.h	2004-10-26 01:59:51.388555720 +0200
-@@ -6,6 +6,7 @@
- #ifndef __SKAS_PTRACE_H
- #define __SKAS_PTRACE_H
- 
-+#ifndef PTRACE_FAULTINFO
- struct ptrace_faultinfo {
- 	int is_write;
- 	unsigned long addr;
-@@ -21,6 +22,7 @@ struct ptrace_ldt {
- #define PTRACE_SIGPENDING 53
- #define PTRACE_LDT 54
- #define PTRACE_SWITCH_MM 55
-+#endif
- 
- #endif

Deleted: trunk/src/kernel-patch-skas/host-skas3.patch
===================================================================
--- trunk/src/kernel-patch-skas/host-skas3.patch	2006-08-27 15:01:30 UTC (rev 166)
+++ trunk/src/kernel-patch-skas/host-skas3.patch	2006-08-27 15:16:57 UTC (rev 167)
@@ -1,589 +0,0 @@
-diff -Naur host/arch/i386/config.in host-ptrace/arch/i386/config.in
---- host/arch/i386/config.in	Fri Aug  9 15:57:14 2002
-+++ host-ptrace/arch/i386/config.in	Sun Nov 10 18:40:09 2002
-@@ -291,6 +291,8 @@
-    bool '    Use real mode APM BIOS call to power off' CONFIG_APM_REAL_MODE_POWER_OFF
- fi
- 
-+bool '/proc/mm' CONFIG_PROC_MM
-+
- endmenu
- 
- source drivers/mtd/Config.in
-diff -Naur host/arch/i386/kernel/ldt.c host-ptrace/arch/i386/kernel/ldt.c
---- host/arch/i386/kernel/ldt.c	Fri Oct 26 00:01:41 2001
-+++ host-ptrace/arch/i386/kernel/ldt.c	Sun Nov  3 18:37:48 2002
-@@ -24,11 +24,12 @@
-  * assured by user-space anyway. Writes are atomic, to protect
-  * the security checks done on new descriptors.
-  */
--static int read_ldt(void * ptr, unsigned long bytecount)
-+static int read_ldt(struct task_struct *task, void * ptr, 
-+		    unsigned long bytecount)
- {
- 	int err;
- 	unsigned long size;
--	struct mm_struct * mm = current->mm;
-+	struct mm_struct * mm = task->mm;
- 
- 	err = 0;
- 	if (!mm->context.segments)
-@@ -64,9 +65,10 @@
- 	return err;
- }
- 
--static int write_ldt(void * ptr, unsigned long bytecount, int oldmode)
-+static int write_ldt(struct task_struct *task, void * ptr, 
-+		     unsigned long bytecount, int oldmode)
- {
--	struct mm_struct * mm = current->mm;
-+	struct mm_struct * mm = task->mm;
- 	__u32 entry_1, entry_2, *lp;
- 	int error;
- 	struct modify_ldt_ldt_s ldt_info;
-@@ -148,23 +150,29 @@
- 	return error;
- }
- 
--asmlinkage int sys_modify_ldt(int func, void *ptr, unsigned long bytecount)
-+int modify_ldt(struct task_struct *task, int func, void *ptr, 
-+	       unsigned long bytecount)
- {
- 	int ret = -ENOSYS;
- 
- 	switch (func) {
- 	case 0:
--		ret = read_ldt(ptr, bytecount);
-+		ret = read_ldt(task, ptr, bytecount);
- 		break;
- 	case 1:
--		ret = write_ldt(ptr, bytecount, 1);
-+		ret = write_ldt(task, ptr, bytecount, 1);
- 		break;
- 	case 2:
- 		ret = read_default_ldt(ptr, bytecount);
- 		break;
- 	case 0x11:
--		ret = write_ldt(ptr, bytecount, 0);
-+		ret = write_ldt(task, ptr, bytecount, 0);
- 		break;
- 	}
- 	return ret;
-+}
-+
-+asmlinkage int sys_modify_ldt(int func, void *ptr, unsigned long bytecount)
-+{
-+	return(modify_ldt(current, func, ptr, bytecount));
- }
-diff -Naur host/arch/i386/kernel/process.c host-ptrace/arch/i386/kernel/process.c
---- host/arch/i386/kernel/process.c	Fri Aug  9 15:57:14 2002
-+++ host-ptrace/arch/i386/kernel/process.c	Wed Nov  6 22:12:45 2002
-@@ -551,13 +551,11 @@
-  * we do not have to muck with descriptors here, that is
-  * done in switch_mm() as needed.
-  */
--void copy_segments(struct task_struct *p, struct mm_struct *new_mm)
-+void mm_copy_segments(struct mm_struct *old_mm, struct mm_struct *new_mm)
- {
--	struct mm_struct * old_mm;
- 	void *old_ldt, *ldt;
- 
- 	ldt = NULL;
--	old_mm = current->mm;
- 	if (old_mm && (old_ldt = old_mm->context.segments) != NULL) {
- 		/*
- 		 * Completely new LDT, we initialize it from the parent:
-@@ -570,6 +568,16 @@
- 	}
- 	new_mm->context.segments = ldt;
- 	new_mm->context.cpuvalid = ~0UL;	/* valid on all CPU's - they can't have stale data */
-+}
-+
-+void copy_segments(struct task_struct *p, struct mm_struct *new_mm)
-+{
-+	mm_copy_segments(current->mm, new_mm);
-+}
-+
-+void copy_task_segments(struct task_struct *from, struct mm_struct *new_mm)
-+{
-+	mm_copy_segments(from->mm, new_mm);
- }
- 
- /*
-diff -Naur host/arch/i386/kernel/ptrace.c host-ptrace/arch/i386/kernel/ptrace.c
---- host/arch/i386/kernel/ptrace.c	Fri Aug  9 15:57:14 2002
-+++ host-ptrace/arch/i386/kernel/ptrace.c	Mon Nov 11 19:03:38 2002
-@@ -147,6 +147,11 @@
- 	put_stack_long(child, EFL_OFFSET, tmp);
- }
- 
-+extern int modify_ldt(struct task_struct *task, int func, void *ptr, 
-+		      unsigned long bytecount);
-+
-+extern struct mm_struct *proc_mm_get_mm(int fd);
-+
- asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
- {
- 	struct task_struct *child;
-@@ -415,6 +420,53 @@
- 			child->ptrace |= PT_TRACESYSGOOD;
- 		else
- 			child->ptrace &= ~PT_TRACESYSGOOD;
-+		ret = 0;
-+		break;
-+	}
-+
-+	case PTRACE_FAULTINFO: {
-+		struct ptrace_faultinfo fault;
-+
-+		fault = ((struct ptrace_faultinfo) 
-+			{ .is_write	= child->thread.error_code,
-+			  .addr		= child->thread.cr2 });
-+		ret = copy_to_user((unsigned long *) data, &fault, 
-+				   sizeof(fault));
-+		if(ret)
-+			break;
-+		break;
-+	}
-+	case PTRACE_SIGPENDING:
-+		ret = copy_to_user((unsigned long *) data, 
-+				   &child->pending.signal,
-+				   sizeof(child->pending.signal));
-+		break;
-+
-+	case PTRACE_LDT: {
-+		struct ptrace_ldt ldt;
-+
-+		if(copy_from_user(&ldt, (unsigned long *) data, 
-+				  sizeof(ldt))){
-+			ret = -EIO;
-+			break;
-+		}
-+		ret = modify_ldt(child, ldt.func, ldt.ptr, ldt.bytecount);
-+		break;
-+	}
-+
-+	case PTRACE_SWITCH_MM: {
-+		struct mm_struct *old = child->mm;
-+		struct mm_struct *new = proc_mm_get_mm(data);
-+
-+		if(IS_ERR(new)){
-+			ret = PTR_ERR(new);
-+			break;
-+		}
-+
-+		atomic_inc(&new->mm_users);
-+		child->mm = new;
-+		child->active_mm = new;
-+		mmput(old);
- 		ret = 0;
- 		break;
- 	}
-diff -Naur host/arch/i386/kernel/sys_i386.c host-ptrace/arch/i386/kernel/sys_i386.c
---- host/arch/i386/kernel/sys_i386.c	Mon Mar 19 15:35:09 2001
-+++ host-ptrace/arch/i386/kernel/sys_i386.c	Mon Nov 11 17:23:25 2002
-@@ -40,7 +40,7 @@
- }
- 
- /* common code for old and new mmaps */
--static inline long do_mmap2(
-+long do_mmap2(struct mm_struct *mm,
- 	unsigned long addr, unsigned long len,
- 	unsigned long prot, unsigned long flags,
- 	unsigned long fd, unsigned long pgoff)
-@@ -55,9 +55,9 @@
- 			goto out;
- 	}
- 
--	down_write(&current->mm->mmap_sem);
--	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
--	up_write(&current->mm->mmap_sem);
-+	down_write(&mm->mmap_sem);
-+	error = do_mmap_pgoff(mm, file, addr, len, prot, flags, pgoff);
-+	up_write(&mm->mmap_sem);
- 
- 	if (file)
- 		fput(file);
-@@ -69,7 +69,7 @@
- 	unsigned long prot, unsigned long flags,
- 	unsigned long fd, unsigned long pgoff)
- {
--	return do_mmap2(addr, len, prot, flags, fd, pgoff);
-+	return do_mmap2(current->mm, addr, len, prot, flags, fd, pgoff);
- }
- 
- /*
-@@ -100,7 +100,7 @@
- 	if (a.offset & ~PAGE_MASK)
- 		goto out;
- 
--	err = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
-+	err = do_mmap2(current->mm, a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
- out:
- 	return err;
- }
-diff -Naur host/include/asm-i386/processor.h host-ptrace/include/asm-i386/processor.h
---- host/include/asm-i386/processor.h	Sun Nov 10 18:47:37 2002
-+++ host-ptrace/include/asm-i386/processor.h	Mon Nov 11 17:33:30 2002
-@@ -436,6 +436,8 @@
- extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
- 
- /* Copy and release all segment info associated with a VM */
-+extern void mm_copy_segments(struct mm_struct *old_mm, 
-+			     struct mm_struct *new_mm);
- extern void copy_segments(struct task_struct *p, struct mm_struct * mm);
- extern void release_segments(struct mm_struct * mm);
- 
-diff -Naur host/include/asm-i386/ptrace.h host-ptrace/include/asm-i386/ptrace.h
---- host/include/asm-i386/ptrace.h	Sun Sep 23 19:20:51 2001
-+++ host-ptrace/include/asm-i386/ptrace.h	Sun Nov 10 18:36:22 2002
-@@ -51,6 +51,22 @@
- 
- #define PTRACE_SETOPTIONS         21
- 
-+struct ptrace_faultinfo {
-+	int is_write;
-+	unsigned long addr;
-+};
-+
-+struct ptrace_ldt {
-+	int func;
-+  	void *ptr;
-+	unsigned long bytecount;
-+};
-+
-+#define PTRACE_FAULTINFO 52
-+#define PTRACE_SIGPENDING 53
-+#define PTRACE_LDT 54
-+#define PTRACE_SWITCH_MM 55
-+
- /* options set using PTRACE_SETOPTIONS */
- #define PTRACE_O_TRACESYSGOOD     0x00000001
- 
-diff -Naur host/include/linux/mm.h host-ptrace/include/linux/mm.h
---- host/include/linux/mm.h	Fri Aug 30 15:03:44 2002
-+++ host-ptrace/include/linux/mm.h	Mon Nov 11 19:08:53 2002
-@@ -492,6 +492,9 @@
- int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, unsigned long start,
- 		int len, int write, int force, struct page **pages, struct vm_area_struct **vmas);
- 
-+extern long do_mprotect(struct mm_struct *mm, unsigned long start, 
-+			size_t len, unsigned long prot);
-+
- /*
-  * On a two-level page table, this ends up being trivial. Thus the
-  * inlining and the symmetry break with pte_alloc() that does all
-@@ -539,9 +542,10 @@
- 
- extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
- 
--extern unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
--	unsigned long len, unsigned long prot,
--	unsigned long flag, unsigned long pgoff);
-+extern unsigned long do_mmap_pgoff(struct mm_struct *mm, 
-+				   struct file *file, unsigned long addr,
-+				   unsigned long len, unsigned long prot,
-+				   unsigned long flag, unsigned long pgoff);
- 
- static inline unsigned long do_mmap(struct file *file, unsigned long addr,
- 	unsigned long len, unsigned long prot,
-@@ -551,7 +555,7 @@
- 	if ((offset + PAGE_ALIGN(len)) < offset)
- 		goto out;
- 	if (!(offset & ~PAGE_MASK))
--		ret = do_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT);
-+		ret = do_mmap_pgoff(current->mm, file, addr, len, prot, flag, offset >> PAGE_SHIFT);
- out:
- 	return ret;
- }
-diff -Naur host/include/linux/proc_mm.h host-ptrace/include/linux/proc_mm.h
---- host/include/linux/proc_mm.h	Wed Dec 31 19:00:00 1969
-+++ host-ptrace/include/linux/proc_mm.h	Mon Nov 11 17:41:09 2002
-@@ -0,0 +1,44 @@
-+/* 
-+ * Copyright (C) 2002 Jeff Dike (jdike at karaya.com)
-+ * Licensed under the GPL
-+ */
-+
-+#ifndef __PROC_MM_H
-+#define __PROC_MM_H
-+
-+#define MM_MMAP 54
-+#define MM_MUNMAP 55
-+#define MM_MPROTECT 56
-+#define MM_COPY_SEGMENTS 57
-+
-+struct mm_mmap {
-+	unsigned long addr;
-+	unsigned long len;
-+	unsigned long prot;
-+	unsigned long flags;
-+	unsigned long fd;
-+	unsigned long offset;
-+};
-+
-+struct mm_munmap {
-+	unsigned long addr;
-+	unsigned long len;	
-+};
-+
-+struct mm_mprotect {
-+	unsigned long addr;
-+	unsigned long len;
-+        unsigned int prot;
-+};
-+
-+struct proc_mm_op {
-+	int op;
-+	union {
-+		struct mm_mmap mmap;
-+		struct mm_munmap munmap;
-+	        struct mm_mprotect mprotect;
-+		int copy_segments;
-+	} u;
-+};
-+
-+#endif
-diff -Naur host/mm/Makefile host-ptrace/mm/Makefile
---- host/mm/Makefile	Fri Aug  9 15:57:31 2002
-+++ host-ptrace/mm/Makefile	Sun Nov 10 18:37:33 2002
-@@ -17,5 +17,6 @@
- 	    shmem.o
- 
- obj-$(CONFIG_HIGHMEM) += highmem.o
-+obj-$(CONFIG_PROC_MM) += proc_mm.o
- 
- include $(TOPDIR)/Rules.make
-diff -Naur host/mm/mmap.c host-ptrace/mm/mmap.c
---- host/mm/mmap.c	Fri Aug  9 15:57:31 2002
-+++ host-ptrace/mm/mmap.c	Mon Nov 11 17:24:18 2002
-@@ -390,10 +390,11 @@
- 	return 0;
- }
- 
--unsigned long do_mmap_pgoff(struct file * file, unsigned long addr, unsigned long len,
--	unsigned long prot, unsigned long flags, unsigned long pgoff)
-+unsigned long do_mmap_pgoff(struct mm_struct *mm, struct file * file, 
-+			    unsigned long addr, unsigned long len,
-+			    unsigned long prot, unsigned long flags, 
-+			    unsigned long pgoff)
- {
--	struct mm_struct * mm = current->mm;
- 	struct vm_area_struct * vma, * prev;
- 	unsigned int vm_flags;
- 	int correct_wcount = 0;
-diff -Naur host/mm/mprotect.c host-ptrace/mm/mprotect.c
---- host/mm/mprotect.c	Fri Aug  9 15:57:31 2002
-+++ host-ptrace/mm/mprotect.c	Mon Nov 11 17:47:58 2002
-@@ -264,7 +264,8 @@
- 	return 0;
- }
- 
--asmlinkage long sys_mprotect(unsigned long start, size_t len, unsigned long prot)
-+long do_mprotect(struct mm_struct *mm, unsigned long start, size_t len, 
-+		 unsigned long prot)
- {
- 	unsigned long nstart, end, tmp;
- 	struct vm_area_struct * vma, * next, * prev;
-@@ -281,9 +282,9 @@
- 	if (end == start)
- 		return 0;
- 
--	down_write(&current->mm->mmap_sem);
-+	down_write(&mm->mmap_sem);
- 
--	vma = find_vma_prev(current->mm, start, &prev);
-+	vma = find_vma_prev(mm, start, &prev);
- 	error = -ENOMEM;
- 	if (!vma || vma->vm_start > start)
- 		goto out;
-@@ -332,6 +333,11 @@
- 		prev->vm_mm->map_count--;
- 	}
- out:
--	up_write(&current->mm->mmap_sem);
-+	up_write(&mm->mmap_sem);
- 	return error;
-+}
-+
-+asmlinkage long sys_mprotect(unsigned long start, size_t len, unsigned long prot)
-+{
-+	return(do_mprotect(current->mm, start, len, prot));
- }
-diff -Naur host/mm/proc_mm.c host-ptrace/mm/proc_mm.c
---- host/mm/proc_mm.c	Wed Dec 31 19:00:00 1969
-+++ host-ptrace/mm/proc_mm.c	Mon Nov 11 19:07:52 2002
-@@ -0,0 +1,173 @@
-+/* 
-+ * Copyright (C) 2002 Jeff Dike (jdike at karaya.com)
-+ * Licensed under the GPL
-+ */
-+
-+#include "linux/proc_fs.h"
-+#include "linux/proc_mm.h"
-+#include "linux/file.h"
-+#include "asm/uaccess.h"
-+#include "asm/mmu_context.h"
-+
-+static struct file_operations proc_mm_fops;
-+
-+struct mm_struct *proc_mm_get_mm(int fd)
-+{
-+	struct mm_struct *ret = ERR_PTR(-EBADF);
-+	struct file *file;
-+
-+	file = fget(fd);
-+	if (!file)
-+		goto out;
-+
-+	ret = ERR_PTR(-EINVAL);
-+	if(file->f_op != &proc_mm_fops)
-+		goto out_fput;
-+
-+	ret = file->private_data;
-+
-+ out_fput:
-+	fput(file);
-+ out:
-+	return(ret);
-+}
-+
-+extern long do_mmap2(struct mm_struct *mm, unsigned long addr, 
-+		     unsigned long len, unsigned long prot, 
-+		     unsigned long flags, unsigned long fd,
-+		     unsigned long pgoff);
-+
-+static ssize_t write_proc_mm(struct file *file, const char *buffer,
-+			     size_t count, loff_t *ppos)
-+{
-+	struct mm_struct *mm = file->private_data;
-+	struct proc_mm_op req;
-+	int n, ret;
-+
-+	if(count > sizeof(req))
-+		return(-EINVAL);
-+
-+	n = copy_from_user(&req, buffer, count);
-+	if(n != 0)
-+		return(-EFAULT);
-+
-+	ret = count;
-+	switch(req.op){
-+	case MM_MMAP: {
-+		struct mm_mmap *map = &req.u.mmap;
-+
-+		ret = do_mmap2(mm, map->addr, map->len, map->prot, 
-+			       map->flags, map->fd, map->offset >> PAGE_SHIFT);
-+		if((ret & ~PAGE_MASK) == 0)
-+			ret = count;
-+	
-+		break;
-+	}
-+	case MM_MUNMAP: {
-+		struct mm_munmap *unmap = &req.u.munmap;
-+
-+		down_write(&mm->mmap_sem);
-+		ret = do_munmap(mm, unmap->addr, unmap->len);
-+		up_write(&mm->mmap_sem);
-+
-+		if(ret == 0)
-+			ret = count;
-+		break;
-+	}
-+	case MM_MPROTECT: {
-+		struct mm_mprotect *protect = &req.u.mprotect;
-+
-+		ret = do_mprotect(mm, protect->addr, protect->len, 
-+				  protect->prot);
-+		if(ret == 0)
-+			ret = count;
-+		break;
-+	}
-+
-+	case MM_COPY_SEGMENTS: {
-+		struct mm_struct *from = proc_mm_get_mm(req.u.copy_segments);
-+
-+		if(IS_ERR(from)){
-+			ret = PTR_ERR(from);
-+			break;
-+		}
-+
-+		mm_copy_segments(from, mm);
-+		break;
-+	}
-+	default:
-+		ret = -EINVAL;
-+		break;
-+	}
-+
-+	return(ret);
-+}
-+
-+static int open_proc_mm(struct inode *inode, struct file *file)
-+{
-+	struct mm_struct *mm = mm_alloc();
-+	int ret;
-+
-+	ret = -ENOMEM;
-+	if(mm == NULL)
-+		goto out_mem;
-+
-+	ret = init_new_context(current, mm);
-+	if(ret)
-+		goto out_free;
-+
-+	spin_lock(&mmlist_lock);
-+	list_add(&mm->mmlist, &current->mm->mmlist);
-+	mmlist_nr++;
-+	spin_unlock(&mmlist_lock);
-+
-+	file->private_data = mm;
-+
-+	return(0);
-+
-+ out_free:
-+	mmput(mm);
-+ out_mem:
-+	return(ret);
-+}
-+
-+static int release_proc_mm(struct inode *inode, struct file *file)
-+{
-+	struct mm_struct *mm = file->private_data;
-+
-+	mmput(mm);
-+	return(0);
-+}
-+
-+static struct file_operations proc_mm_fops = {
-+	.open		= open_proc_mm,
-+	.release	= release_proc_mm,
-+	.write		= write_proc_mm,
-+};
-+
-+static int make_proc_mm(void)
-+{
-+	struct proc_dir_entry *ent;
-+
-+	ent = create_proc_entry("mm", 0222, &proc_root);
-+	if(ent == NULL){
-+		printk("make_proc_mm : Failed to register /proc/mm\n");
-+		return(0);
-+	}
-+	ent->proc_fops = &proc_mm_fops;
-+
-+	return(0);
-+}
-+
-+__initcall(make_proc_mm);
-+
-+/*
-+ * Overrides for Emacs so that we follow Linus's tabbing style.
-+ * Emacs will notice this stuff at the end of the file and automatically
-+ * adjust the settings for this buffer only.  This must remain at the end
-+ * of the file.
-+ * ---------------------------------------------------------------------------
-+ * Local variables:
-+ * c-file-style: "linux"
-+ * End:
-+ */

Deleted: trunk/src/kernel-patch-skas/skas-2.6.10-v8.patch
===================================================================
--- trunk/src/kernel-patch-skas/skas-2.6.10-v8.patch	2006-08-27 15:01:30 UTC (rev 166)
+++ trunk/src/kernel-patch-skas/skas-2.6.10-v8.patch	2006-08-27 15:16:57 UTC (rev 167)
@@ -1,953 +0,0 @@
---- vanilla-linux-2.6.10-paolo/arch/i386/kernel/entry.S	2005-03-10 18:16:11.000000000 +0100
-+++ vanilla-linux-2.6.10-paolo/arch/i386/kernel/entry.S	2005-03-10 18:16:15.000000000 +0100
-@@ -222,7 +222,7 @@
- 	SAVE_ALL
- 	GET_THREAD_INFO(%ebp)
- 
--	testb $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT),TI_flags(%ebp)
-+	testb $(_TIF_SYSCALL_EMU|_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT),TI_flags(%ebp)
- 	jnz syscall_trace_entry
- 	cmpl $(nr_syscalls), %eax
- 	jae syscall_badsys
-@@ -245,8 +245,8 @@
- 	pushl %eax			# save orig_eax
- 	SAVE_ALL
- 	GET_THREAD_INFO(%ebp)
--					# system call tracing in operation
--	testb $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT),TI_flags(%ebp)
-+					# system call tracing in operation / emulation
-+	testb $(_TIF_SYSCALL_EMU|_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT),TI_flags(%ebp)
- 	jnz syscall_trace_entry
- 	cmpl $(nr_syscalls), %eax
- 	jae syscall_badsys
-@@ -307,10 +307,19 @@
- 	movl %esp, %eax
- 	xorl %edx,%edx
- 	call do_syscall_trace
-+	cmpl $0, %eax
-+	jne syscall_skip		# ret != 0 -> running under PTRACE_SYSEMU,
-+					# so must skip actual syscall
- 	movl ORIG_EAX(%esp), %eax
- 	cmpl $(nr_syscalls), %eax
- 	jnae syscall_call
- 	jmp syscall_exit
-+syscall_skip:
-+	cli				# make sure we don't miss an interrupt
-+					# setting need_resched or sigpending
-+					# between sampling and the iret
-+	movl TI_flags(%ebp), %ecx
-+	jmp work_pending
- 
- 	# perform syscall exit tracing
- 	ALIGN
---- vanilla-linux-2.6.10-paolo/arch/i386/kernel/ptrace.c	2005-03-10 18:16:15.000000000 +0100
-+++ vanilla-linux-2.6.10-paolo/arch/i386/kernel/ptrace.c	2005-03-10 18:16:16.000000000 +0100
-@@ -15,6 +15,7 @@
- #include <linux/user.h>
- #include <linux/security.h>
- #include <linux/audit.h>
-+#include <linux/proc_mm.h>
- 
- #include <asm/uaccess.h>
- #include <asm/pgtable.h>
-@@ -168,6 +169,8 @@
- void ptrace_disable(struct task_struct *child)
- { 
- 	clear_singlestep(child);
-+	clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-+	clear_tsk_thread_flag(child, TIF_SYSCALL_EMU);
- }
- 
- /*
-@@ -406,15 +409,20 @@
- 		  }
- 		  break;
- 
-+	case PTRACE_SYSEMU: /* continue and stop at next syscall, which will not be executed */
- 	case PTRACE_SYSCALL:	/* continue and stop at next (return from) syscall */
- 	case PTRACE_CONT:	/* restart after signal. */
- 		ret = -EIO;
- 		if ((unsigned long) data > _NSIG)
- 			break;
--		if (request == PTRACE_SYSCALL) {
-+		if (request == PTRACE_SYSEMU) {
-+			set_tsk_thread_flag(child, TIF_SYSCALL_EMU);
-+			clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-+		} else if (request == PTRACE_SYSCALL) {
- 			set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
--		}
--		else {
-+			clear_tsk_thread_flag(child, TIF_SYSCALL_EMU);
-+		} else {
-+			clear_tsk_thread_flag(child, TIF_SYSCALL_EMU);
- 			clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- 		}
- 		child->exit_code = data;
-@@ -439,10 +447,17 @@
- 		wake_up_process(child);
- 		break;
- 
-+	case PTRACE_SYSEMU_SINGLESTEP: /* Same as SYSEMU, but singlestep if not syscall */
- 	case PTRACE_SINGLESTEP:	/* set the trap flag. */
- 		ret = -EIO;
- 		if ((unsigned long) data > _NSIG)
- 			break;
-+
-+		if (request == PTRACE_SYSEMU_SINGLESTEP)
-+			set_tsk_thread_flag(child, TIF_SYSCALL_EMU);
-+		else
-+			clear_tsk_thread_flag(child, TIF_SYSCALL_EMU);
-+
- 		clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- 		set_singlestep(child);
- 		child->exit_code = data;
-@@ -542,6 +557,58 @@
- 					(struct user_desc __user *) data);
- 		break;
- 
-+#ifdef CONFIG_PROC_MM
-+	case PTRACE_FAULTINFO: {
-+		struct ptrace_faultinfo fault;
-+
-+		fault = ((struct ptrace_faultinfo)
-+			{ .is_write	= child->thread.error_code,
-+			  .addr		= child->thread.cr2 });
-+		ret = copy_to_user((unsigned long *) data, &fault,
-+				   sizeof(fault));
-+		if(ret)
-+			break;
-+		break;
-+	}
-+
-+	case PTRACE_SIGPENDING:
-+		ret = copy_to_user((unsigned long *) data,
-+				   &child->pending.signal,
-+				   sizeof(child->pending.signal));
-+		break;
-+
-+	case PTRACE_LDT: {
-+		struct ptrace_ldt ldt;
-+
-+		if(copy_from_user(&ldt, (unsigned long *) data,
-+				  sizeof(ldt))){
-+			ret = -EIO;
-+			break;
-+		}
-+		ret = __modify_ldt(child->mm, ldt.func, ldt.ptr, ldt.bytecount);
-+		break;
-+	}
-+
-+	case PTRACE_SWITCH_MM: {
-+		struct mm_struct *old = child->mm;
-+		struct mm_struct *new = proc_mm_get_mm(data);
-+
-+		if(IS_ERR(new)){
-+			ret = PTR_ERR(new);
-+			break;
-+		}
-+
-+		atomic_inc(&new->mm_users);
-+		task_lock(child);
-+		child->mm = new;
-+		child->active_mm = new;
-+		task_unlock(child);
-+		mmput(old);
-+		ret = 0;
-+		break;
-+	}
-+#endif
-+
- 	default:
- 		ret = ptrace_request(child, request, addr, data);
- 		break;
-@@ -557,26 +624,45 @@
-  * - triggered by current->work.syscall_trace
-  */
- __attribute__((regparm(3)))
--void do_syscall_trace(struct pt_regs *regs, int entryexit)
-+int do_syscall_trace(struct pt_regs *regs, int entryexit)
- {
-+	int is_sysemu = test_thread_flag(TIF_SYSCALL_EMU);
-+	/* With TIF_SYSCALL_EMU set we want to ignore TIF_SINGLESTEP */
-+	int is_singlestep = !is_sysemu && test_thread_flag(TIF_SINGLESTEP);
-+
- 	if (unlikely(current->audit_context)) {
--		if (!entryexit)
-+		if (!entryexit) {
- 			audit_syscall_entry(current, regs->orig_eax,
- 					    regs->ebx, regs->ecx,
- 					    regs->edx, regs->esi);
-+			/* With TIF_SYSCALL_AUDIT | TIF_SINGLESTEP &&
-+			 * !TIF_SYSCALL_EMU we come in here, but must not
-+			 * continue with ptrace_notify().
-+			 * In the SINGLESTEP && ! _AUDIT case (i.e. normal one),
-+			 * entry.S will call us only on syscall exit and not on
-+			 * the syscall entry path, so let's be consistent.
-+			 */
-+			if (is_singlestep)
-+				return 0;
-+		}
- 		else
- 			audit_syscall_exit(current, regs->eax);
- 	}
-+	/* If a process stops on the 1st tracepoint with SYSCALL_TRACE
-+	 * and then is resumed with SYSEMU_SINGLESTEP, it will come in
-+	 * here. We have to check this and return */
-+	if (is_sysemu && entryexit)
-+		return 0;
- 
- 	if (!test_thread_flag(TIF_SYSCALL_TRACE) &&
--	    !test_thread_flag(TIF_SINGLESTEP))
--		return;
-+	    !is_singlestep && !is_sysemu)
-+		return 0;
- 	if (!(current->ptrace & PT_PTRACED))
--		return;
-+		return 0;
- 	/* the 0x80 provides a way for the tracing parent to distinguish
- 	   between a syscall stop and SIGTRAP delivery */
- 	ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) &&
--				 !test_thread_flag(TIF_SINGLESTEP) ? 0x80 : 0));
-+				 !is_singlestep ? 0x80 : 0));
- 
- 	/*
- 	 * this isn't the same as continuing with a signal, but it will do
-@@ -589,2 +675,10 @@
- 	}
-+	/* != 0 if nullifying the syscall, 0 if running it normally */
-+	if ( !is_sysemu )
-+		return 0;
-+
-+	regs->orig_eax = -1; /* force skip of syscall restarting */
-+	if (unlikely(current->audit_context))
-+		audit_syscall_exit(current, regs->eax);
-+	return 1;
- }
---- vanilla-linux-2.6.10/include/asm-i386/thread_info.h~host-sysemu-2.6.7-4	2005-03-10 18:16:11.000000000 +0100
-+++ vanilla-linux-2.6.10-paolo/include/asm-i386/thread_info.h	2005-03-10 18:16:11.000000000 +0100
-@@ -139,6 +139,7 @@ register unsigned long current_stack_poi
- #define TIF_NEED_RESCHED	3	/* rescheduling necessary */
- #define TIF_SINGLESTEP		4	/* restore singlestep on return to user mode */
- #define TIF_IRET		5	/* return with iret */
-+#define TIF_SYSCALL_EMU		6	/* syscall emulation active */
- #define TIF_SYSCALL_AUDIT	7	/* syscall auditing active */
- #define TIF_POLLING_NRFLAG	16	/* true if poll_idle() is polling TIF_NEED_RESCHED */
- 
-@@ -148,12 +149,14 @@ register unsigned long current_stack_poi
- #define _TIF_NEED_RESCHED	(1<<TIF_NEED_RESCHED)
- #define _TIF_SINGLESTEP		(1<<TIF_SINGLESTEP)
- #define _TIF_IRET		(1<<TIF_IRET)
-+#define _TIF_SYSCALL_EMU	(1<<TIF_SYSCALL_EMU)
- #define _TIF_SYSCALL_AUDIT	(1<<TIF_SYSCALL_AUDIT)
- #define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
- 
- /* work to do on interrupt/exception return */
- #define _TIF_WORK_MASK \
--  (0x0000FFFF & ~(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP))
-+  (0x0000FFFF & ~(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP|\
-+		  _TIF_SYSCALL_EMU))
- #define _TIF_ALLWORK_MASK	0x0000FFFF	/* work to do on any return to u-space */
- 
- /*
---- vanilla-linux-2.6.10-paolo/include/linux/ptrace.h	2005-03-10 18:16:11.000000000 +0100
-+++ vanilla-linux-2.6.10-paolo/include/linux/ptrace.h	2005-03-10 18:16:15.000000000 +0100
-@@ -20,6 +20,8 @@
- #define PTRACE_DETACH		0x11
- 
- #define PTRACE_SYSCALL		  24
-+#define PTRACE_SYSEMU		  31
-+#define PTRACE_SYSEMU_SINGLESTEP  32
- 
- /* 0x4200-0x4300 are reserved for architecture-independent additions.  */
- #define PTRACE_SETOPTIONS	0x4200
---- vanilla-linux-2.6.10/kernel/fork.c~host-sysemu-2.6.7-4	2005-03-10 18:16:11.000000000 +0100
-+++ vanilla-linux-2.6.10-paolo/kernel/fork.c	2005-03-10 18:16:11.000000000 +0100
-@@ -926,6 +926,9 @@ static task_t *copy_process(unsigned lon
- 	 * of CLONE_PTRACE.
- 	 */
- 	clear_tsk_thread_flag(p, TIF_SYSCALL_TRACE);
-+#ifdef TIF_SYSCALL_EMU
-+	clear_tsk_thread_flag(p, TIF_SYSCALL_EMU);
-+#endif
- 
- 	/* Our parent execution domain becomes current domain
- 	   These must match for thread signalling to apply */
---- vanilla-linux-2.6.10/include/linux/mm.h~Add_generic_proc_mm_support	2005-03-10 18:16:11.000000000 +0100
-+++ vanilla-linux-2.6.10-paolo/include/linux/mm.h	2005-03-10 18:16:11.000000000 +0100
-@@ -625,6 +625,9 @@ struct shrinker;
- extern struct shrinker *set_shrinker(int, shrinker_t);
- extern void remove_shrinker(struct shrinker *shrinker);
- 
-+extern long do_mprotect(struct mm_struct *mm, unsigned long start,
-+			size_t len, unsigned long prot);
-+
- /*
-  * On a two-level page table, this ends up being trivial. Thus the
-  * inlining and the symmetry break with pte_alloc_map() that does all
-@@ -684,9 +687,15 @@ extern void exit_mmap(struct mm_struct *
- 
- extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
- 
--extern unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
-+extern unsigned long __do_mmap_pgoff(struct mm_struct *mm, struct file *file,
-+				   unsigned long addr, unsigned long len,
-+				   unsigned long prot, unsigned long flag,
-+				   unsigned long pgoff);
-+static inline unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
- 	unsigned long len, unsigned long prot,
--	unsigned long flag, unsigned long pgoff);
-+	unsigned long flag, unsigned long pgoff) {
-+	return __do_mmap_pgoff(current->mm, file, addr, len, prot, flag, pgoff);
-+}
- 
- static inline unsigned long do_mmap(struct file *file, unsigned long addr,
- 	unsigned long len, unsigned long prot,
---- vanilla-linux-2.6.10/include/linux/proc_mm.h~Add_generic_proc_mm_support	2005-03-10 18:16:11.000000000 +0100
-+++ vanilla-linux-2.6.10-paolo/include/linux/proc_mm.h	2005-03-10 18:16:11.000000000 +0100
-@@ -0,0 +1,48 @@
-+/*
-+ * Copyright (C) 2002 Jeff Dike (jdike at karaya.com)
-+ * Licensed under the GPL
-+ */
-+
-+#ifndef __PROC_MM_H
-+#define __PROC_MM_H
-+
-+#include "linux/sched.h"
-+
-+#define MM_MMAP 54
-+#define MM_MUNMAP 55
-+#define MM_MPROTECT 56
-+#define MM_COPY_SEGMENTS 57
-+
-+struct mm_mmap {
-+	unsigned long addr;
-+	unsigned long len;
-+	unsigned long prot;
-+	unsigned long flags;
-+	unsigned long fd;
-+	unsigned long offset;
-+};
-+
-+struct mm_munmap {
-+	unsigned long addr;
-+	unsigned long len;
-+};
-+
-+struct mm_mprotect {
-+	unsigned long addr;
-+	unsigned long len;
-+        unsigned int prot;
-+};
-+
-+struct proc_mm_op {
-+	int op;
-+	union {
-+		struct mm_mmap mmap;
-+		struct mm_munmap munmap;
-+	        struct mm_mprotect mprotect;
-+		int copy_segments;
-+	} u;
-+};
-+
-+extern struct mm_struct *proc_mm_get_mm(int fd);
-+
-+#endif
---- vanilla-linux-2.6.10/mm/Makefile~Add_generic_proc_mm_support	2005-03-10 18:16:11.000000000 +0100
-+++ vanilla-linux-2.6.10-paolo/mm/Makefile	2005-03-10 18:16:11.000000000 +0100
-@@ -18,3 +18,4 @@ obj-$(CONFIG_NUMA) 	+= mempolicy.o
- obj-$(CONFIG_SHMEM) += shmem.o
- obj-$(CONFIG_TINY_SHMEM) += tiny-shmem.o
- 
-+obj-$(CONFIG_PROC_MM)	+= proc_mm.o
---- vanilla-linux-2.6.10/mm/mmap.c~Add_generic_proc_mm_support	2005-03-10 18:16:11.000000000 +0100
-+++ vanilla-linux-2.6.10-paolo/mm/mmap.c	2005-03-10 18:16:11.000000000 +0100
-@@ -759,11 +759,11 @@ void __vm_stat_account(struct mm_struct 
-  * The caller must hold down_write(current->mm->mmap_sem).
-  */
- 
--unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
--			unsigned long len, unsigned long prot,
--			unsigned long flags, unsigned long pgoff)
-+unsigned long __do_mmap_pgoff(struct mm_struct *mm, struct file * file,
-+			    unsigned long addr, unsigned long len,
-+			    unsigned long prot, unsigned long flags,
-+			    unsigned long pgoff)
- {
--	struct mm_struct * mm = current->mm;
- 	struct vm_area_struct * vma, * prev;
- 	struct inode *inode;
- 	unsigned int vm_flags;
-@@ -1037,7 +1037,7 @@ unacct_error:
- 	return error;
- }
- 
--EXPORT_SYMBOL(do_mmap_pgoff);
-+EXPORT_SYMBOL(__do_mmap_pgoff);
- 
- /* Get an address range which is currently unmapped.
-  * For shmat() with addr=0.
---- vanilla-linux-2.6.10/mm/mprotect.c~Add_generic_proc_mm_support	2005-03-10 18:16:11.000000000 +0100
-+++ vanilla-linux-2.6.10-paolo/mm/mprotect.c	2005-03-10 18:16:11.000000000 +0100
-@@ -93,19 +93,20 @@ change_protection(struct vm_area_struct 
- {
- 	pgd_t *dir;
- 	unsigned long beg = start;
-+	struct mm_struct * mm = vma->vm_mm;
- 
--	dir = pgd_offset(current->mm, start);
-+	dir = pgd_offset(mm, start);
- 	flush_cache_range(vma, beg, end);
- 	if (start >= end)
- 		BUG();
--	spin_lock(&current->mm->page_table_lock);
-+	spin_lock(&mm->page_table_lock);
- 	do {
- 		change_pmd_range(dir, start, end - start, newprot);
- 		start = (start + PGDIR_SIZE) & PGDIR_MASK;
- 		dir++;
- 	} while (start && (start < end));
- 	flush_tlb_range(vma, beg, end);
--	spin_unlock(&current->mm->page_table_lock);
-+	spin_unlock(&mm->page_table_lock);
- 	return;
- }
- 
-@@ -190,8 +191,9 @@ fail:
- 	return error;
- }
- 
--asmlinkage long
--sys_mprotect(unsigned long start, size_t len, unsigned long prot)
-+long
-+do_mprotect(struct mm_struct *mm, unsigned long start, size_t len,
-+	     unsigned long prot)
- {
- 	unsigned long vm_flags, nstart, end, tmp;
- 	struct vm_area_struct *vma, *prev;
-@@ -220,9 +222,9 @@ sys_mprotect(unsigned long start, size_t
- 
- 	vm_flags = calc_vm_prot_bits(prot);
- 
--	down_write(&current->mm->mmap_sem);
-+	down_write(&mm->mmap_sem);
- 
--	vma = find_vma_prev(current->mm, start, &prev);
-+	vma = find_vma_prev(mm, start, &prev);
- 	error = -ENOMEM;
- 	if (!vma)
- 		goto out;
-@@ -288,6 +290,11 @@ sys_mprotect(unsigned long start, size_t
- 		}
- 	}
- out:
--	up_write(&current->mm->mmap_sem);
-+	up_write(&mm->mmap_sem);
- 	return error;
- }
-+
-+asmlinkage long sys_mprotect(unsigned long start, size_t len, unsigned long prot)
-+{
-+        return(do_mprotect(current->mm, start, len, prot));
-+}
---- vanilla-linux-2.6.10-paolo/mm/proc_mm.c	2005-03-10 18:16:13.000000000 +0100
-+++ vanilla-linux-2.6.10-paolo/mm/proc_mm.c	2005-03-10 18:16:13.000000000 +0100
-@@ -0,0 +1,177 @@
-+/*
-+ * Copyright (C) 2002 Jeff Dike (jdike at karaya.com)
-+ * Licensed under the GPL
-+ */
-+
-+#include "linux/mm.h"
-+#include "linux/init.h"
-+#include "linux/proc_fs.h"
-+#include "linux/proc_mm.h"
-+#include "linux/file.h"
-+#include "linux/mman.h"
-+#include "asm/uaccess.h"
-+#include "asm/mmu_context.h"
-+
-+static struct file_operations proc_mm_fops;
-+
-+struct mm_struct *proc_mm_get_mm(int fd)
-+{
-+	struct mm_struct *ret = ERR_PTR(-EBADF);
-+	struct file *file;
-+
-+	file = fget(fd);
-+	if (!file)
-+		goto out;
-+
-+	ret = ERR_PTR(-EINVAL);
-+	if(file->f_op != &proc_mm_fops)
-+		goto out_fput;
-+
-+	ret = file->private_data;
-+ out_fput:
-+	fput(file);
-+ out:
-+	return(ret);
-+}
-+
-+extern long do_mmap2(struct mm_struct *mm, unsigned long addr,
-+		     unsigned long len, unsigned long prot,
-+		     unsigned long flags, unsigned long fd,
-+		     unsigned long pgoff);
-+
-+static ssize_t write_proc_mm(struct file *file, const char *buffer,
-+			     size_t count, loff_t *ppos)
-+{
-+	struct mm_struct *mm = file->private_data;
-+	struct proc_mm_op req;
-+	int n, ret;
-+
-+	if(count > sizeof(req))
-+		return(-EINVAL);
-+
-+	n = copy_from_user(&req, buffer, count);
-+	if(n != 0)
-+		return(-EFAULT);
-+
-+	ret = count;
-+	switch(req.op){
-+	case MM_MMAP: {
-+		struct mm_mmap *map = &req.u.mmap;
-+
-+		/* Nobody ever noticed it, but do_mmap_pgoff() calls
-+		 * get_unmapped_area() which checks current->mm, if
-+		 * MAP_FIXED is not set, so mmap() could replace
-+		 * an old mapping.
-+		 */
-+		if (! (map->flags & MAP_FIXED))
-+			return(-EINVAL);
-+
-+		ret = do_mmap2(mm, map->addr, map->len, map->prot,
-+			       map->flags, map->fd, map->offset >> PAGE_SHIFT);
-+		if((ret & ~PAGE_MASK) == 0)
-+			ret = count;
-+
-+		break;
-+	}
-+	case MM_MUNMAP: {
-+		struct mm_munmap *unmap = &req.u.munmap;
-+
-+		down_write(&mm->mmap_sem);
-+		ret = do_munmap(mm, unmap->addr, unmap->len);
-+		up_write(&mm->mmap_sem);
-+
-+		if(ret == 0)
-+			ret = count;
-+		break;
-+	}
-+	case MM_MPROTECT: {
-+		struct mm_mprotect *protect = &req.u.mprotect;
-+
-+		ret = do_mprotect(mm, protect->addr, protect->len,
-+				  protect->prot);
-+		if(ret == 0)
-+			ret = count;
-+		break;
-+	}
-+
-+	case MM_COPY_SEGMENTS: {
-+		struct mm_struct *from = proc_mm_get_mm(req.u.copy_segments);
-+
-+		if(IS_ERR(from)){
-+			ret = PTR_ERR(from);
-+			break;
-+		}
-+
-+		ret = copy_context(mm, from);
-+		if(ret == 0)
-+			ret = count;
-+		break;
-+	}
-+	default:
-+		ret = -EINVAL;
-+		break;
-+	}
-+
-+	return(ret);
-+}
-+
-+static int open_proc_mm(struct inode *inode, struct file *file)
-+{
-+	struct mm_struct *mm = mm_alloc();
-+	int ret;
-+
-+	ret = -ENOMEM;
-+	if(mm == NULL)
-+		goto out_mem;
-+
-+	init_new_empty_context(mm);
-+	arch_pick_mmap_layout(mm);
-+
-+	file->private_data = mm;
-+
-+	return(0);
-+
-+ out_mem:
-+	return(ret);
-+}
-+
-+static int release_proc_mm(struct inode *inode, struct file *file)
-+{
-+	struct mm_struct *mm = file->private_data;
-+
-+	mmput(mm);
-+	return(0);
-+}
-+
-+static struct file_operations proc_mm_fops = {
-+	.open		= open_proc_mm,
-+	.release	= release_proc_mm,
-+	.write		= write_proc_mm,
-+};
-+
-+static int make_proc_mm(void)
-+{
-+	struct proc_dir_entry *ent;
-+
-+	ent = create_proc_entry("mm", 0222, &proc_root);
-+	if(ent == NULL){
-+		printk("make_proc_mm : Failed to register /proc/mm\n");
-+		return(0);
-+	}
-+	ent->proc_fops = &proc_mm_fops;
-+
-+	return(0);
-+}
-+
-+__initcall(make_proc_mm);
-+
-+/*
-+ * Overrides for Emacs so that we follow Linus's tabbing style.
-+ * Emacs will notice this stuff at the end of the file and automatically
-+ * adjust the settings for this buffer only.  This must remain at the end
-+ * of the file.
-+ * ---------------------------------------------------------------------------
-+ * Local variables:
-+ * c-file-style: "linux"
-+ * End:
-+ */
---- vanilla-linux-2.6.10/arch/um/include/skas_ptrace.h~Add_generic_proc_mm_support	2005-03-10 18:16:11.000000000 +0100
-+++ vanilla-linux-2.6.10-paolo/arch/um/include/skas_ptrace.h	2005-03-10 18:16:11.000000000 +0100
-@@ -6,6 +6,7 @@
- #ifndef __SKAS_PTRACE_H
- #define __SKAS_PTRACE_H
- 
-+#ifndef PTRACE_FAULTINFO
- struct ptrace_faultinfo {
- 	int is_write;
- 	unsigned long addr;
-@@ -21,6 +22,7 @@ struct ptrace_ldt {
- #define PTRACE_SIGPENDING 53
- #define PTRACE_LDT 54
- #define PTRACE_SWITCH_MM 55
-+#endif
- 
- #endif
- 
---- vanilla-linux-2.6.10/arch/i386/Kconfig~i386-specific	2005-03-10 18:16:12.000000000 +0100
-+++ vanilla-linux-2.6.10-paolo/arch/i386/Kconfig	2005-03-10 18:16:12.000000000 +0100
-@@ -730,6 +730,10 @@ config X86_PAE
- 	depends on HIGHMEM64G
- 	default y
- 
-+config PROC_MM
-+	bool "/proc/mm support"
-+	default y
-+
- # Common NUMA Features
- config NUMA
- 	bool "Numa Memory Allocation and Scheduler Support"
---- vanilla-linux-2.6.10-paolo/arch/i386/kernel/ldt.c	2005-03-10 18:16:14.000000000 +0100
-+++ vanilla-linux-2.6.10-paolo/arch/i386/kernel/ldt.c	2005-03-10 18:16:14.000000000 +0100
-@@ -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)
-@@ -27,11 +28,12 @@
- }
- #endif
- 
--static int alloc_ldt(mm_context_t *pc, int mincount, int reload)
-+static int alloc_ldt(struct mm_struct *mm, int mincount, int reload)
- {
- 	void *oldldt;
- 	void *newldt;
- 	int oldsize;
-+	mm_context_t * pc = &mm->context;
- 
- 	if (mincount <= pc->size)
- 		return 0;
-@@ -58,13 +60,15 @@
- #ifdef CONFIG_SMP
- 		cpumask_t mask;
- 		preempt_disable();
--		load_LDT(pc);
-+		if (&current->active_mm->context == pc)
-+			load_LDT(pc);
- 		mask = cpumask_of_cpu(smp_processor_id());
--		if (!cpus_equal(current->mm->cpu_vm_mask, mask))
-+		if (!cpus_equal(mm->cpu_vm_mask, mask))
- 			smp_call_function(flush_ldt, NULL, 1, 1);
- 		preempt_enable();
- #else
--		load_LDT(pc);
-+		if (&current->active_mm->context == pc)
-+			load_LDT(pc);
- #endif
- 	}
- 	if (oldsize) {
-@@ -76,12 +80,12 @@
- 	return 0;
- }
- 
--static inline int copy_ldt(mm_context_t *new, mm_context_t *old)
-+static inline int copy_ldt(struct mm_struct *new, struct mm_struct *old)
- {
--	int err = alloc_ldt(new, old->size, 0);
-+	int err = alloc_ldt(new, old->context.size, 0);
- 	if (err < 0)
- 		return err;
--	memcpy(new->ldt, old->ldt, old->size*LDT_ENTRY_SIZE);
-+	memcpy(new->context.ldt, old->context.ldt, old->context.size*LDT_ENTRY_SIZE);
- 	return 0;
- }
- 
-@@ -89,22 +93,24 @@
-  * we do not have to muck with descriptors here, that is
-  * done in switch_mm() as needed.
-  */
--int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
-+int copy_context(struct mm_struct *mm, struct mm_struct *old_mm)
- {
--	struct mm_struct * old_mm;
- 	int retval = 0;
- 
--	init_MUTEX(&mm->context.sem);
--	mm->context.size = 0;
--	old_mm = current->mm;
- 	if (old_mm && old_mm->context.size > 0) {
- 		down(&old_mm->context.sem);
--		retval = copy_ldt(&mm->context, &old_mm->context);
-+		retval = copy_ldt(mm, old_mm);
- 		up(&old_mm->context.sem);
- 	}
- 	return retval;
- }
- 
-+int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
-+{
-+	init_new_empty_context(mm);
-+	return copy_context(mm, current->mm);
-+}
-+
- /*
-  * No need to lock the MM as we are the last user
-  */
-@@ -121,11 +127,11 @@
- 	}
- }
- 
--static int read_ldt(void __user * ptr, unsigned long bytecount)
-+static int read_ldt(struct mm_struct * mm, void __user * ptr,
-+		    unsigned long bytecount)
- {
- 	int err;
- 	unsigned long size;
--	struct mm_struct * mm = current->mm;
- 
- 	if (!mm->context.size)
- 		return 0;
-@@ -174,9 +180,8 @@
- 	return err;
- }
- 
--static int write_ldt(void __user * ptr, unsigned long bytecount, int oldmode)
-+static int write_ldt(struct mm_struct * mm, void __user * ptr, unsigned long bytecount, int oldmode)
- {
--	struct mm_struct * mm = current->mm;
- 	__u32 entry_1, entry_2, *lp;
- 	int error;
- 	struct user_desc ldt_info;
-@@ -200,7 +205,7 @@
- 
- 	down(&mm->context.sem);
- 	if (ldt_info.entry_number >= mm->context.size) {
--		error = alloc_ldt(&current->mm->context, ldt_info.entry_number+1, 1);
-+		error = alloc_ldt(mm, ldt_info.entry_number+1, 1);
- 		if (error < 0)
- 			goto out_unlock;
- 	}
-@@ -236,20 +241,26 @@
--asmlinkage int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
-+int __modify_ldt(struct mm_struct * mm, int func, void __user *ptr,
-+	       unsigned long bytecount)
- {
- 	int ret = -ENOSYS;
- 
- 	switch (func) {
- 	case 0:
--		ret = read_ldt(ptr, bytecount);
-+		ret = read_ldt(mm, ptr, bytecount);
- 		break;
- 	case 1:
--		ret = write_ldt(ptr, bytecount, 1);
-+		ret = write_ldt(mm, ptr, bytecount, 1);
- 		break;
- 	case 2:
- 		ret = read_default_ldt(ptr, bytecount);
- 		break;
- 	case 0x11:
--		ret = write_ldt(ptr, bytecount, 0);
-+		ret = write_ldt(mm, ptr, bytecount, 0);
- 		break;
- 	}
- 	return ret;
- }
-+
-+asmlinkage int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
-+{
-+	return __modify_ldt(current->mm, func, ptr, bytecount);
-+}
---- vanilla-linux-2.6.10/arch/i386/kernel/sys_i386.c~i386-specific	2005-03-10 18:16:12.000000000 +0100
-+++ vanilla-linux-2.6.10-paolo/arch/i386/kernel/sys_i386.c	2005-03-10 18:16:12.000000000 +0100
-@@ -41,7 +41,7 @@ asmlinkage int sys_pipe(unsigned long __
- }
- 
- /* common code for old and new mmaps */
--static inline long do_mmap2(
-+long do_mmap2(struct mm_struct *mm,
- 	unsigned long addr, unsigned long len,
- 	unsigned long prot, unsigned long flags,
- 	unsigned long fd, unsigned long pgoff)
-@@ -56,9 +56,9 @@ static inline long do_mmap2(
- 			goto out;
- 	}
- 
--	down_write(&current->mm->mmap_sem);
--	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
--	up_write(&current->mm->mmap_sem);
-+	down_write(&mm->mmap_sem);
-+	error = __do_mmap_pgoff(mm, file, addr, len, prot, flags, pgoff);
-+	up_write(&mm->mmap_sem);
- 
- 	if (file)
- 		fput(file);
-@@ -70,7 +70,7 @@ asmlinkage long sys_mmap2(unsigned long 
- 	unsigned long prot, unsigned long flags,
- 	unsigned long fd, unsigned long pgoff)
- {
--	return do_mmap2(addr, len, prot, flags, fd, pgoff);
-+	return do_mmap2(current->mm, addr, len, prot, flags, fd, pgoff);
- }
- 
- /*
-@@ -101,7 +101,7 @@ asmlinkage int old_mmap(struct mmap_arg_
- 	if (a.offset & ~PAGE_MASK)
- 		goto out;
- 
--	err = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
-+	err = do_mmap2(current->mm, a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
- out:
- 	return err;
- }
---- vanilla-linux-2.6.10-paolo/include/asm-i386/desc.h	2005-03-10 18:16:12.000000000 +0100
-+++ vanilla-linux-2.6.10-paolo/include/asm-i386/desc.h	2005-03-10 18:16:14.000000000 +0100
-@@ -126,6 +126,9 @@
- 	put_cpu();
- }
- 
-+extern int __modify_ldt(struct mm_struct * mm, int func, void __user *ptr,
-+		      unsigned long bytecount);
-+
- #endif /* !__ASSEMBLY__ */
- 
- #endif
---- vanilla-linux-2.6.10/include/asm-i386/ptrace.h~i386-specific	2005-03-10 18:16:12.000000000 +0100
-+++ vanilla-linux-2.6.10-paolo/include/asm-i386/ptrace.h	2005-03-10 18:16:12.000000000 +0100
-@@ -64,4 +64,26 @@ extern unsigned long profile_pc(struct p
- #endif
- #endif
- 
-+/*For SKAS3 support.*/
-+#ifndef _LINUX_PTRACE_STRUCT_DEF
-+#define _LINUX_PTRACE_STRUCT_DEF
-+
-+#define PTRACE_FAULTINFO	  52
-+#define PTRACE_SIGPENDING	  53
-+#define PTRACE_LDT		  54
-+#define PTRACE_SWITCH_MM 	  55
-+
-+struct ptrace_faultinfo {
-+	int is_write;
-+	unsigned long addr;
-+};
-+
-+struct ptrace_ldt {
-+	int func;
-+  	void *ptr;
-+	unsigned long bytecount;
-+};
-+
-+#endif /*ifndef _LINUX_PTRACE_STRUCT_DEF*/
-+
- #endif
---- vanilla-linux-2.6.10-paolo/include/asm-i386/mmu_context.h	2005-03-10 18:16:12.000000000 +0100
-+++ vanilla-linux-2.6.10-paolo/include/asm-i386/mmu_context.h	2005-03-10 18:16:12.000000000 +0100
-@@ -6,13 +6,25 @@
- #include <asm/atomic.h>
- #include <asm/pgalloc.h>
- #include <asm/tlbflush.h>
-+#include <asm/semaphore.h>
- 
- /*
-- * Used for LDT copy/destruction.
-+ * Used for LDT initialization/destruction. You cannot copy an LDT with
-+ * init_new_context, since it thinks you are passing it a new LDT and won't
-+ * deallocate its old content.
-  */
- int init_new_context(struct task_struct *tsk, struct mm_struct *mm);
- void destroy_context(struct mm_struct *mm);
- 
-+/* LDT initialization for a clean environment - needed for SKAS.*/
-+static inline void init_new_empty_context(struct mm_struct *mm)
-+{
-+	init_MUTEX(&mm->context.sem);
-+	mm->context.size = 0;
-+}
-+
-+/* LDT copy for SKAS - for the above problem.*/
-+int copy_context(struct mm_struct *mm, struct mm_struct *old_mm);
- 
- static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
- {
-@@ -29,6 +41,10 @@
- {
- 	int cpu = smp_processor_id();
- 
-+#ifdef CONFIG_SMP
-+	prev = per_cpu(cpu_tlbstate, cpu).active_mm;
-+#endif
-+
- 	if (likely(prev != next)) {
- 		/* stop flush ipis for the previous mm */
- 		cpu_clear(cpu, prev->cpu_vm_mask);
-@@ -50,7 +66,6 @@
- #ifdef CONFIG_SMP
- 	else {
- 		per_cpu(cpu_tlbstate, cpu).state = TLBSTATE_OK;
--		BUG_ON(per_cpu(cpu_tlbstate, cpu).active_mm != next);
- 
- 		if (!cpu_test_and_set(cpu, next->cpu_vm_mask)) {
- 			/* We were in lazy tlb mode and leave_mm disabled 
---- /dev/null	2005-03-26 18:29:00.701330288 +0100
-+++ clean-linux-2.6.10-paolo/localversion-skas	2005-03-29 16:00:28.000000000 +0200
-@@ -0,0 +1 @@
-+-skas3-v8

Deleted: trunk/src/kernel-patch-skas/skas-2.6.11-v8.2.patch
===================================================================
--- trunk/src/kernel-patch-skas/skas-2.6.11-v8.2.patch	2006-08-27 15:01:30 UTC (rev 166)
+++ trunk/src/kernel-patch-skas/skas-2.6.11-v8.2.patch	2006-08-27 15:16:57 UTC (rev 167)
@@ -1,946 +0,0 @@
---- clean-linux-2.6.11-paolo/arch/i386/kernel/entry.S	2005-07-10 16:56:19.000000000 +0200
-+++ clean-linux-2.6.11-paolo/arch/i386/kernel/entry.S	2005-05-03 09:08:14.000000000 +0200
-@@ -219,7 +219,7 @@
- 	SAVE_ALL
- 	GET_THREAD_INFO(%ebp)
- 
--	testb $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT),TI_flags(%ebp)
-+	testw $(_TIF_SYSCALL_EMU|_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT),TI_flags(%ebp)
- 	jnz syscall_trace_entry
- 	cmpl $(nr_syscalls), %eax
- 	jae syscall_badsys
-@@ -242,8 +242,8 @@
- 	pushl %eax			# save orig_eax
- 	SAVE_ALL
- 	GET_THREAD_INFO(%ebp)
--					# system call tracing in operation
--	testb $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT),TI_flags(%ebp)
-+					# system call tracing in operation / emulation
-+	testw $(_TIF_SYSCALL_EMU|_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT),TI_flags(%ebp)
- 	jnz syscall_trace_entry
- 	cmpl $(nr_syscalls), %eax
- 	jae syscall_badsys
-@@ -304,6 +304,9 @@
- 	movl %esp, %eax
- 	xorl %edx,%edx
- 	call do_syscall_trace
-+	cmpl $0, %eax
-+	jne resume_userspace		# ret != 0 -> running under PTRACE_SYSEMU,
-+					# so must skip actual syscall
- 	movl ORIG_EAX(%esp), %eax
- 	cmpl $(nr_syscalls), %eax
- 	jnae syscall_call
---- clean-linux-2.6.11-paolo/arch/i386/kernel/ptrace.c	2005-07-10 16:57:36.000000000 +0200
-+++ clean-linux-2.6.11-paolo/arch/i386/kernel/ptrace.c	2005-07-10 16:55:40.000000000 +0200
-@@ -15,6 +15,7 @@
- #include <linux/user.h>
- #include <linux/security.h>
- #include <linux/audit.h>
-+#include <linux/proc_mm.h>
- 
- #include <asm/uaccess.h>
- #include <asm/pgtable.h>
-@@ -269,6 +270,8 @@
- void ptrace_disable(struct task_struct *child)
- { 
- 	clear_singlestep(child);
-+	clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-+	clear_tsk_thread_flag(child, TIF_SYSCALL_EMU);
- }
- 
- /*
-@@ -507,15 +510,20 @@
- 		  }
- 		  break;
- 
-+	case PTRACE_SYSEMU: /* continue and stop at next syscall, which will not be executed */
- 	case PTRACE_SYSCALL:	/* continue and stop at next (return from) syscall */
- 	case PTRACE_CONT:	/* restart after signal. */
- 		ret = -EIO;
- 		if ((unsigned long) data > _NSIG)
- 			break;
--		if (request == PTRACE_SYSCALL) {
-+		if (request == PTRACE_SYSEMU) {
-+			set_tsk_thread_flag(child, TIF_SYSCALL_EMU);
-+			clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-+		} else if (request == PTRACE_SYSCALL) {
- 			set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
--		}
--		else {
-+			clear_tsk_thread_flag(child, TIF_SYSCALL_EMU);
-+		} else {
-+			clear_tsk_thread_flag(child, TIF_SYSCALL_EMU);
- 			clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- 		}
- 		child->exit_code = data;
-@@ -540,10 +548,17 @@
- 		wake_up_process(child);
- 		break;
- 
-+	case PTRACE_SYSEMU_SINGLESTEP: /* Same as SYSEMU, but singlestep if not syscall */
- 	case PTRACE_SINGLESTEP:	/* set the trap flag. */
- 		ret = -EIO;
- 		if ((unsigned long) data > _NSIG)
- 			break;
-+
-+		if (request == PTRACE_SYSEMU_SINGLESTEP)
-+			set_tsk_thread_flag(child, TIF_SYSCALL_EMU);
-+		else
-+			clear_tsk_thread_flag(child, TIF_SYSCALL_EMU);
-+
- 		clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- 		set_singlestep(child);
- 		child->exit_code = data;
-@@ -643,6 +658,58 @@
- 					(struct user_desc __user *) data);
- 		break;
- 
-+#ifdef CONFIG_PROC_MM
-+	case PTRACE_FAULTINFO: {
-+		struct ptrace_faultinfo fault;
-+
-+		fault = ((struct ptrace_faultinfo)
-+			{ .is_write	= child->thread.error_code,
-+			  .addr		= child->thread.cr2 });
-+		ret = copy_to_user((unsigned long *) data, &fault,
-+				   sizeof(fault));
-+		if(ret)
-+			break;
-+		break;
-+	}
-+
-+	case PTRACE_SIGPENDING:
-+		ret = copy_to_user((unsigned long *) data,
-+				   &child->pending.signal,
-+				   sizeof(child->pending.signal));
-+		break;
-+
-+	case PTRACE_LDT: {
-+		struct ptrace_ldt ldt;
-+
-+		if(copy_from_user(&ldt, (unsigned long *) data,
-+				  sizeof(ldt))){
-+			ret = -EIO;
-+			break;
-+		}
-+		ret = __modify_ldt(child->mm, ldt.func, ldt.ptr, ldt.bytecount);
-+		break;
-+	}
-+
-+	case PTRACE_SWITCH_MM: {
-+		struct mm_struct *old = child->mm;
-+		struct mm_struct *new = proc_mm_get_mm(data);
-+
-+		if(IS_ERR(new)){
-+			ret = PTR_ERR(new);
-+			break;
-+		}
-+
-+		atomic_inc(&new->mm_users);
-+		task_lock(child);
-+		child->mm = new;
-+		child->active_mm = new;
-+		task_unlock(child);
-+		mmput(old);
-+		ret = 0;
-+		break;
-+	}
-+#endif
-+
- 	default:
- 		ret = ptrace_request(child, request, addr, data);
- 		break;
-@@ -676,29 +743,49 @@
-  * - triggered by current->work.syscall_trace
-  */
- __attribute__((regparm(3)))
--void do_syscall_trace(struct pt_regs *regs, int entryexit)
-+int do_syscall_trace(struct pt_regs *regs, int entryexit)
- {
-+	int is_sysemu = test_thread_flag(TIF_SYSCALL_EMU);
-+	/* With TIF_SYSCALL_EMU set we want to ignore TIF_SINGLESTEP */
-+	int is_singlestep = !is_sysemu && test_thread_flag(TIF_SINGLESTEP);
-+
- 	if (unlikely(current->audit_context)) {
--		if (!entryexit)
-+		if (!entryexit) {
- 			audit_syscall_entry(current, regs->orig_eax,
- 					    regs->ebx, regs->ecx,
- 					    regs->edx, regs->esi);
-+			/* With TIF_SYSCALL_AUDIT | TIF_SINGLESTEP &&
-+			 * !TIF_SYSCALL_EMU we come in here, but must not
-+			 * continue with ptrace_notify().
-+			 * In the SINGLESTEP && ! _AUDIT case (i.e. normal one),
-+			 * entry.S will call us only on syscall exit and not on
-+			 * the syscall entry path, so let's be consistent.
-+			 */
-+			if (is_singlestep)
-+				return 0;
-+		}
- 		else
- 			audit_syscall_exit(current, regs->eax);
- 	}
--
- 	if (!(current->ptrace & PT_PTRACED))
--		return;
-+		return 0;
-+
-+	/* If a process stops on the 1st tracepoint with SYSCALL_TRACE
-+	 * and then is resumed with SYSEMU_SINGLESTEP, it will come in
-+	 * here. We have to check this and return */
-+	if (is_sysemu && entryexit)
-+		return 0;
- 
- 	/* Fake a debug trap */
--	if (test_thread_flag(TIF_SINGLESTEP))
-+	if (is_singlestep)
- 		send_sigtrap(current, regs, 0);
- 
--	if (!test_thread_flag(TIF_SYSCALL_TRACE))
--		return;
-+	if (!test_thread_flag(TIF_SYSCALL_TRACE) && !is_sysemu)
-+		return 0;
- 
- 	/* the 0x80 provides a way for the tracing parent to distinguish
- 	   between a syscall stop and SIGTRAP delivery */
-+	/* Note that the debugger could change the result of test_thread_flag!*/
- 	ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) ? 0x80 : 0));
- 
- 	/*
-@@ -712,2 +799,10 @@
- 	}
-+	/* != 0 if nullifying the syscall, 0 if running it normally */
-+	if ( !is_sysemu )
-+		return 0;
-+
-+	regs->orig_eax = -1; /* force skip of syscall restarting */
-+	if (unlikely(current->audit_context))
-+		audit_syscall_exit(current, regs->eax);
-+	return 1;
- }
---- clean-linux-2.6.11-paolo/include/asm-i386/thread_info.h	2005-07-10 16:55:19.000000000 +0200
-+++ clean-linux-2.6.11-paolo/include/asm-i386/thread_info.h	2005-05-03 09:08:14.000000000 +0200
-@@ -140,6 +140,7 @@
- #define TIF_SINGLESTEP		4	/* restore singlestep on return to user mode */
- #define TIF_IRET		5	/* return with iret */
- #define TIF_SYSCALL_AUDIT	7	/* syscall auditing active */
-+#define TIF_SYSCALL_EMU		9	/* syscall emulation active */
- #define TIF_POLLING_NRFLAG	16	/* true if poll_idle() is polling TIF_NEED_RESCHED */
- #define TIF_MEMDIE		17
- 
-@@ -149,12 +150,14 @@
- #define _TIF_NEED_RESCHED	(1<<TIF_NEED_RESCHED)
- #define _TIF_SINGLESTEP		(1<<TIF_SINGLESTEP)
- #define _TIF_IRET		(1<<TIF_IRET)
-+#define _TIF_SYSCALL_EMU	(1<<TIF_SYSCALL_EMU)
- #define _TIF_SYSCALL_AUDIT	(1<<TIF_SYSCALL_AUDIT)
- #define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
- 
- /* work to do on interrupt/exception return */
- #define _TIF_WORK_MASK \
--  (0x0000FFFF & ~(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP))
-+  (0x0000FFFF & ~(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP|\
-+		  _TIF_SYSCALL_EMU))
- #define _TIF_ALLWORK_MASK	0x0000FFFF	/* work to do on any return to u-space */
- 
- /*
---- clean-linux-2.6.11-paolo/include/linux/ptrace.h	2005-07-10 16:57:37.000000000 +0200
-+++ clean-linux-2.6.11-paolo/include/linux/ptrace.h	2005-07-10 16:55:38.000000000 +0200
-@@ -20,6 +20,8 @@
- #define PTRACE_DETACH		0x11
- 
- #define PTRACE_SYSCALL		  24
-+#define PTRACE_SYSEMU		  31
-+#define PTRACE_SYSEMU_SINGLESTEP  32
- 
- /* 0x4200-0x4300 are reserved for architecture-independent additions.  */
- #define PTRACE_SETOPTIONS	0x4200
---- clean-linux-2.6.11/kernel/fork.c~host-sysemu-2.6.7-4	2005-07-10 16:55:19.000000000 +0200
-+++ clean-linux-2.6.11-paolo/kernel/fork.c	2005-07-10 16:55:19.000000000 +0200
-@@ -938,6 +938,9 @@ static task_t *copy_process(unsigned lon
- 	 * of CLONE_PTRACE.
- 	 */
- 	clear_tsk_thread_flag(p, TIF_SYSCALL_TRACE);
-+#ifdef TIF_SYSCALL_EMU
-+	clear_tsk_thread_flag(p, TIF_SYSCALL_EMU);
-+#endif
- 
- 	/* Our parent execution domain becomes current domain
- 	   These must match for thread signalling to apply */
---- clean-linux-2.6.11/include/linux/mm.h~Add_generic_proc_mm_support	2005-07-10 16:55:31.000000000 +0200
-+++ clean-linux-2.6.11-paolo/include/linux/mm.h	2005-07-10 16:55:31.000000000 +0200
-@@ -655,6 +655,9 @@ struct shrinker;
- extern struct shrinker *set_shrinker(int, shrinker_t);
- extern void remove_shrinker(struct shrinker *shrinker);
- 
-+extern long do_mprotect(struct mm_struct *mm, unsigned long start,
-+			size_t len, unsigned long prot);
-+
- /*
-  * On a two-level or three-level page table, this ends up being trivial. Thus
-  * the inlining and the symmetry break with pte_alloc_map() that does all
-@@ -730,9 +733,15 @@ extern void exit_mmap(struct mm_struct *
- 
- extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
- 
--extern unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
-+extern unsigned long __do_mmap_pgoff(struct mm_struct *mm, struct file *file,
-+				   unsigned long addr, unsigned long len,
-+				   unsigned long prot, unsigned long flag,
-+				   unsigned long pgoff);
-+static inline unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
- 	unsigned long len, unsigned long prot,
--	unsigned long flag, unsigned long pgoff);
-+	unsigned long flag, unsigned long pgoff) {
-+	return __do_mmap_pgoff(current->mm, file, addr, len, prot, flag, pgoff);
-+}
- 
- static inline unsigned long do_mmap(struct file *file, unsigned long addr,
- 	unsigned long len, unsigned long prot,
---- clean-linux-2.6.11/include/linux/proc_mm.h~Add_generic_proc_mm_support	2005-07-10 16:55:31.000000000 +0200
-+++ clean-linux-2.6.11-paolo/include/linux/proc_mm.h	2005-07-10 16:55:31.000000000 +0200
-@@ -0,0 +1,48 @@
-+/*
-+ * Copyright (C) 2002 Jeff Dike (jdike at karaya.com)
-+ * Licensed under the GPL
-+ */
-+
-+#ifndef __PROC_MM_H
-+#define __PROC_MM_H
-+
-+#include "linux/sched.h"
-+
-+#define MM_MMAP 54
-+#define MM_MUNMAP 55
-+#define MM_MPROTECT 56
-+#define MM_COPY_SEGMENTS 57
-+
-+struct mm_mmap {
-+	unsigned long addr;
-+	unsigned long len;
-+	unsigned long prot;
-+	unsigned long flags;
-+	unsigned long fd;
-+	unsigned long offset;
-+};
-+
-+struct mm_munmap {
-+	unsigned long addr;
-+	unsigned long len;
-+};
-+
-+struct mm_mprotect {
-+	unsigned long addr;
-+	unsigned long len;
-+        unsigned int prot;
-+};
-+
-+struct proc_mm_op {
-+	int op;
-+	union {
-+		struct mm_mmap mmap;
-+		struct mm_munmap munmap;
-+	        struct mm_mprotect mprotect;
-+		int copy_segments;
-+	} u;
-+};
-+
-+extern struct mm_struct *proc_mm_get_mm(int fd);
-+
-+#endif
---- clean-linux-2.6.11/mm/Makefile~Add_generic_proc_mm_support	2005-07-10 16:55:31.000000000 +0200
-+++ clean-linux-2.6.11-paolo/mm/Makefile	2005-07-10 16:55:31.000000000 +0200
-@@ -18,3 +18,4 @@ obj-$(CONFIG_NUMA) 	+= mempolicy.o
- obj-$(CONFIG_SHMEM) += shmem.o
- obj-$(CONFIG_TINY_SHMEM) += tiny-shmem.o
- 
-+obj-$(CONFIG_PROC_MM)	+= proc_mm.o
---- clean-linux-2.6.11/mm/mmap.c~Add_generic_proc_mm_support	2005-07-10 16:55:31.000000000 +0200
-+++ clean-linux-2.6.11-paolo/mm/mmap.c	2005-07-10 16:55:31.000000000 +0200
-@@ -861,11 +861,11 @@ void __vm_stat_account(struct mm_struct 
-  * The caller must hold down_write(current->mm->mmap_sem).
-  */
- 
--unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
--			unsigned long len, unsigned long prot,
--			unsigned long flags, unsigned long pgoff)
-+unsigned long __do_mmap_pgoff(struct mm_struct *mm, struct file * file,
-+			    unsigned long addr, unsigned long len,
-+			    unsigned long prot, unsigned long flags,
-+			    unsigned long pgoff)
- {
--	struct mm_struct * mm = current->mm;
- 	struct vm_area_struct * vma, * prev;
- 	struct inode *inode;
- 	unsigned int vm_flags;
-@@ -1141,7 +1141,7 @@ unacct_error:
- 	return error;
- }
- 
--EXPORT_SYMBOL(do_mmap_pgoff);
-+EXPORT_SYMBOL(__do_mmap_pgoff);
- 
- /* Get an address range which is currently unmapped.
-  * For shmat() with addr=0.
---- clean-linux-2.6.11-paolo/mm/mprotect.c	2005-07-10 16:55:31.000000000 +0200
-+++ clean-linux-2.6.11-paolo/mm/mprotect.c	2005-07-11 11:35:56.000000000 +0200
-@@ -117,7 +117,7 @@
- change_protection(struct vm_area_struct *vma, unsigned long start,
- 		unsigned long end, pgprot_t newprot)
- {
--	struct mm_struct *mm = current->mm;
-+	struct mm_struct *mm = vma->vm_mm;
- 	pgd_t *pgd;
- 	unsigned long beg = start, next;
- 	int i;
-@@ -219,8 +219,9 @@
- 	return error;
- }
- 
--asmlinkage long
--sys_mprotect(unsigned long start, size_t len, unsigned long prot)
-+long
-+do_mprotect(struct mm_struct *mm, unsigned long start, size_t len,
-+	     unsigned long prot)
- {
- 	unsigned long vm_flags, nstart, end, tmp;
- 	struct vm_area_struct *vma, *prev;
-@@ -249,9 +250,9 @@
- 
- 	vm_flags = calc_vm_prot_bits(prot);
- 
--	down_write(&current->mm->mmap_sem);
-+	down_write(&mm->mmap_sem);
- 
--	vma = find_vma_prev(current->mm, start, &prev);
-+	vma = find_vma_prev(mm, start, &prev);
- 	error = -ENOMEM;
- 	if (!vma)
- 		goto out;
-@@ -320,3 +321,12 @@
--	up_write(&current->mm->mmap_sem);
-+	up_write(&mm->mmap_sem);
- 	return error;
- }
-+
-+asmlinkage long sys_mprotect(unsigned long start, size_t len, unsigned long prot)
-+{
-+	long ret = do_mprotect(current->mm, start, len, prot);
-+	/* A tail call would reorder parameters on the stack and they would then
-+	 * be restored at the wrong places. */
-+	prevent_tail_call(ret);
-+	return ret;
-+}
---- clean-linux-2.6.11-paolo/mm/proc_mm.c	2005-07-10 16:57:39.000000000 +0200
-+++ clean-linux-2.6.11-paolo/mm/proc_mm.c	2005-07-10 16:55:34.000000000 +0200
-@@ -0,0 +1,177 @@
-+/*
-+ * Copyright (C) 2002 Jeff Dike (jdike at karaya.com)
-+ * Licensed under the GPL
-+ */
-+
-+#include "linux/mm.h"
-+#include "linux/init.h"
-+#include "linux/proc_fs.h"
-+#include "linux/proc_mm.h"
-+#include "linux/file.h"
-+#include "linux/mman.h"
-+#include "asm/uaccess.h"
-+#include "asm/mmu_context.h"
-+
-+static struct file_operations proc_mm_fops;
-+
-+struct mm_struct *proc_mm_get_mm(int fd)
-+{
-+	struct mm_struct *ret = ERR_PTR(-EBADF);
-+	struct file *file;
-+
-+	file = fget(fd);
-+	if (!file)
-+		goto out;
-+
-+	ret = ERR_PTR(-EINVAL);
-+	if(file->f_op != &proc_mm_fops)
-+		goto out_fput;
-+
-+	ret = file->private_data;
-+ out_fput:
-+	fput(file);
-+ out:
-+	return(ret);
-+}
-+
-+extern long do_mmap2(struct mm_struct *mm, unsigned long addr,
-+		     unsigned long len, unsigned long prot,
-+		     unsigned long flags, unsigned long fd,
-+		     unsigned long pgoff);
-+
-+static ssize_t write_proc_mm(struct file *file, const char *buffer,
-+			     size_t count, loff_t *ppos)
-+{
-+	struct mm_struct *mm = file->private_data;
-+	struct proc_mm_op req;
-+	int n, ret;
-+
-+	if(count > sizeof(req))
-+		return(-EINVAL);
-+
-+	n = copy_from_user(&req, buffer, count);
-+	if(n != 0)
-+		return(-EFAULT);
-+
-+	ret = count;
-+	switch(req.op){
-+	case MM_MMAP: {
-+		struct mm_mmap *map = &req.u.mmap;
-+
-+		/* Nobody ever noticed it, but do_mmap_pgoff() calls
-+		 * get_unmapped_area() which checks current->mm, if
-+		 * MAP_FIXED is not set, so mmap() could replace
-+		 * an old mapping.
-+		 */
-+		if (! (map->flags & MAP_FIXED))
-+			return(-EINVAL);
-+
-+		ret = do_mmap2(mm, map->addr, map->len, map->prot,
-+			       map->flags, map->fd, map->offset >> PAGE_SHIFT);
-+		if((ret & ~PAGE_MASK) == 0)
-+			ret = count;
-+
-+		break;
-+	}
-+	case MM_MUNMAP: {
-+		struct mm_munmap *unmap = &req.u.munmap;
-+
-+		down_write(&mm->mmap_sem);
-+		ret = do_munmap(mm, unmap->addr, unmap->len);
-+		up_write(&mm->mmap_sem);
-+
-+		if(ret == 0)
-+			ret = count;
-+		break;
-+	}
-+	case MM_MPROTECT: {
-+		struct mm_mprotect *protect = &req.u.mprotect;
-+
-+		ret = do_mprotect(mm, protect->addr, protect->len,
-+				  protect->prot);
-+		if(ret == 0)
-+			ret = count;
-+		break;
-+	}
-+
-+	case MM_COPY_SEGMENTS: {
-+		struct mm_struct *from = proc_mm_get_mm(req.u.copy_segments);
-+
-+		if(IS_ERR(from)){
-+			ret = PTR_ERR(from);
-+			break;
-+		}
-+
-+		ret = copy_context(mm, from);
-+		if(ret == 0)
-+			ret = count;
-+		break;
-+	}
-+	default:
-+		ret = -EINVAL;
-+		break;
-+	}
-+
-+	return(ret);
-+}
-+
-+static int open_proc_mm(struct inode *inode, struct file *file)
-+{
-+	struct mm_struct *mm = mm_alloc();
-+	int ret;
-+
-+	ret = -ENOMEM;
-+	if(mm == NULL)
-+		goto out_mem;
-+
-+	init_new_empty_context(mm);
-+	arch_pick_mmap_layout(mm);
-+
-+	file->private_data = mm;
-+
-+	return(0);
-+
-+ out_mem:
-+	return(ret);
-+}
-+
-+static int release_proc_mm(struct inode *inode, struct file *file)
-+{
-+	struct mm_struct *mm = file->private_data;
-+
-+	mmput(mm);
-+	return(0);
-+}
-+
-+static struct file_operations proc_mm_fops = {
-+	.open		= open_proc_mm,
-+	.release	= release_proc_mm,
-+	.write		= write_proc_mm,
-+};
-+
-+static int make_proc_mm(void)
-+{
-+	struct proc_dir_entry *ent;
-+
-+	ent = create_proc_entry("mm", 0222, &proc_root);
-+	if(ent == NULL){
-+		printk("make_proc_mm : Failed to register /proc/mm\n");
-+		return(0);
-+	}
-+	ent->proc_fops = &proc_mm_fops;
-+
-+	return(0);
-+}
-+
-+__initcall(make_proc_mm);
-+
-+/*
-+ * Overrides for Emacs so that we follow Linus's tabbing style.
-+ * Emacs will notice this stuff at the end of the file and automatically
-+ * adjust the settings for this buffer only.  This must remain at the end
-+ * of the file.
-+ * ---------------------------------------------------------------------------
-+ * Local variables:
-+ * c-file-style: "linux"
-+ * End:
-+ */
---- clean-linux-2.6.11/arch/um/include/skas_ptrace.h~Add_generic_proc_mm_support	2005-07-10 16:55:31.000000000 +0200
-+++ clean-linux-2.6.11-paolo/arch/um/include/skas_ptrace.h	2005-07-10 16:55:31.000000000 +0200
-@@ -6,6 +6,7 @@
- #ifndef __SKAS_PTRACE_H
- #define __SKAS_PTRACE_H
- 
-+#ifndef PTRACE_FAULTINFO
- struct ptrace_faultinfo {
- 	int is_write;
- 	unsigned long addr;
-@@ -21,6 +22,7 @@ struct ptrace_ldt {
- #define PTRACE_SIGPENDING 53
- #define PTRACE_LDT 54
- #define PTRACE_SWITCH_MM 55
-+#endif
- 
- #endif
- 
---- clean-linux-2.6.11/arch/i386/Kconfig~i386-specific	2005-07-10 16:55:32.000000000 +0200
-+++ clean-linux-2.6.11-paolo/arch/i386/Kconfig	2005-07-10 16:55:32.000000000 +0200
-@@ -745,6 +745,10 @@ config X86_PAE
- 	depends on HIGHMEM64G
- 	default y
- 
-+config PROC_MM
-+	bool "/proc/mm support"
-+	default y
-+
- # Common NUMA Features
- config NUMA
- 	bool "Numa Memory Allocation and Scheduler Support"
---- clean-linux-2.6.11-paolo/arch/i386/kernel/ldt.c	2005-07-10 16:55:35.000000000 +0200
-+++ clean-linux-2.6.11-paolo/arch/i386/kernel/ldt.c	2005-07-11 11:35:56.000000000 +0200
-@@ -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)
-@@ -27,11 +28,12 @@
- }
- #endif
- 
--static int alloc_ldt(mm_context_t *pc, int mincount, int reload)
-+static int alloc_ldt(struct mm_struct *mm, int mincount, int reload)
- {
- 	void *oldldt;
- 	void *newldt;
- 	int oldsize;
-+	mm_context_t * pc = &mm->context;
- 
- 	if (mincount <= pc->size)
- 		return 0;
-@@ -58,13 +60,15 @@
- #ifdef CONFIG_SMP
- 		cpumask_t mask;
- 		preempt_disable();
--		load_LDT(pc);
-+		if (&current->active_mm->context == pc)
-+			load_LDT(pc);
- 		mask = cpumask_of_cpu(smp_processor_id());
--		if (!cpus_equal(current->mm->cpu_vm_mask, mask))
-+		if (!cpus_equal(mm->cpu_vm_mask, mask))
- 			smp_call_function(flush_ldt, NULL, 1, 1);
- 		preempt_enable();
- #else
--		load_LDT(pc);
-+		if (&current->active_mm->context == pc)
-+			load_LDT(pc);
- #endif
- 	}
- 	if (oldsize) {
-@@ -76,12 +80,12 @@
- 	return 0;
- }
- 
--static inline int copy_ldt(mm_context_t *new, mm_context_t *old)
-+static inline int copy_ldt(struct mm_struct *new, struct mm_struct *old)
- {
--	int err = alloc_ldt(new, old->size, 0);
-+	int err = alloc_ldt(new, old->context.size, 0);
- 	if (err < 0)
- 		return err;
--	memcpy(new->ldt, old->ldt, old->size*LDT_ENTRY_SIZE);
-+	memcpy(new->context.ldt, old->context.ldt, old->context.size*LDT_ENTRY_SIZE);
- 	return 0;
- }
- 
-@@ -89,22 +93,24 @@
-  * we do not have to muck with descriptors here, that is
-  * done in switch_mm() as needed.
-  */
--int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
-+int copy_context(struct mm_struct *mm, struct mm_struct *old_mm)
- {
--	struct mm_struct * old_mm;
- 	int retval = 0;
- 
--	init_MUTEX(&mm->context.sem);
--	mm->context.size = 0;
--	old_mm = current->mm;
- 	if (old_mm && old_mm->context.size > 0) {
- 		down(&old_mm->context.sem);
--		retval = copy_ldt(&mm->context, &old_mm->context);
-+		retval = copy_ldt(mm, old_mm);
- 		up(&old_mm->context.sem);
- 	}
- 	return retval;
- }
- 
-+int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
-+{
-+	init_new_empty_context(mm);
-+	return copy_context(mm, current->mm);
-+}
-+
- /*
-  * No need to lock the MM as we are the last user
-  */
-@@ -121,11 +127,11 @@
- 	}
- }
- 
--static int read_ldt(void __user * ptr, unsigned long bytecount)
-+static int read_ldt(struct mm_struct * mm, void __user * ptr,
-+		    unsigned long bytecount)
- {
- 	int err;
- 	unsigned long size;
--	struct mm_struct * mm = current->mm;
- 
- 	if (!mm->context.size)
- 		return 0;
-@@ -174,9 +180,8 @@
- 	return err;
- }
- 
--static int write_ldt(void __user * ptr, unsigned long bytecount, int oldmode)
-+static int write_ldt(struct mm_struct * mm, void __user * ptr, unsigned long bytecount, int oldmode)
- {
--	struct mm_struct * mm = current->mm;
- 	__u32 entry_1, entry_2, *lp;
- 	int error;
- 	struct user_desc ldt_info;
-@@ -200,7 +205,7 @@
- 
- 	down(&mm->context.sem);
- 	if (ldt_info.entry_number >= mm->context.size) {
--		error = alloc_ldt(&current->mm->context, ldt_info.entry_number+1, 1);
-+		error = alloc_ldt(mm, ldt_info.entry_number+1, 1);
- 		if (error < 0)
- 			goto out_unlock;
- 	}
-@@ -236,20 +241,30 @@
--asmlinkage int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
-+int __modify_ldt(struct mm_struct * mm, int func, void __user *ptr,
-+	       unsigned long bytecount)
- {
- 	int ret = -ENOSYS;
- 
- 	switch (func) {
- 	case 0:
--		ret = read_ldt(ptr, bytecount);
-+		ret = read_ldt(mm, ptr, bytecount);
- 		break;
- 	case 1:
--		ret = write_ldt(ptr, bytecount, 1);
-+		ret = write_ldt(mm, ptr, bytecount, 1);
- 		break;
- 	case 2:
- 		ret = read_default_ldt(ptr, bytecount);
- 		break;
- 	case 0x11:
--		ret = write_ldt(ptr, bytecount, 0);
-+		ret = write_ldt(mm, ptr, bytecount, 0);
- 		break;
- 	}
- 	return ret;
- }
-+
-+asmlinkage int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
-+{
-+	int ret = __modify_ldt(current->mm, func, ptr, bytecount);
-+	/* A tail call would reorder parameters on the stack and they would then
-+	 * be restored at the wrong places. */
-+	prevent_tail_call(ret);
-+	return ret;
-+}
---- clean-linux-2.6.11-paolo/arch/i386/kernel/sys_i386.c	2005-07-10 16:57:34.000000000 +0200
-+++ clean-linux-2.6.11-paolo/arch/i386/kernel/sys_i386.c	2005-07-10 16:56:25.000000000 +0200
-@@ -41,7 +41,7 @@
- }
- 
- /* common code for old and new mmaps */
--static inline long do_mmap2(
-+long do_mmap2(struct mm_struct *mm,
- 	unsigned long addr, unsigned long len,
- 	unsigned long prot, unsigned long flags,
- 	unsigned long fd, unsigned long pgoff)
-@@ -56,9 +56,9 @@
- 			goto out;
- 	}
- 
--	down_write(&current->mm->mmap_sem);
--	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
--	up_write(&current->mm->mmap_sem);
-+	down_write(&mm->mmap_sem);
-+	error = __do_mmap_pgoff(mm, file, addr, len, prot, flags, pgoff);
-+	up_write(&mm->mmap_sem);
- 
- 	if (file)
- 		fput(file);
-@@ -70,7 +70,12 @@
- 	unsigned long prot, unsigned long flags,
- 	unsigned long fd, unsigned long pgoff)
- {
--	return do_mmap2(addr, len, prot, flags, fd, pgoff);
-+	long ret = do_mmap2(current->mm, addr, len, prot, flags, fd, pgoff);
-+
-+	/* A tail call would reorder parameters on the stack and they would then
-+	 * be restored at the wrong places. */
-+	prevent_tail_call(ret);
-+	return ret;
- }
- 
- /*
-@@ -101,7 +106,10 @@
- 	if (a.offset & ~PAGE_MASK)
- 		goto out;
- 
--	err = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
-+	err = do_mmap2(current->mm, a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
-+	/* A tail call would reorder parameters on the stack and they would then
-+	 * be restored at the wrong places. */
-+	prevent_tail_call(err);
- out:
- 	return err;
- }
---- clean-linux-2.6.11/include/asm-i386/desc.h~i386-specific	2005-07-10 16:55:32.000000000 +0200
-+++ clean-linux-2.6.11-paolo/include/asm-i386/desc.h	2005-07-10 16:55:32.000000000 +0200
-@@ -135,6 +135,9 @@ static inline unsigned long get_desc_bas
- 	return base;
- }
- 
-+extern int __modify_ldt(struct mm_struct * mm, int func, void __user *ptr,
-+		      unsigned long bytecount);
-+
- #endif /* !__ASSEMBLY__ */
- 
- #endif
---- clean-linux-2.6.11/include/asm-i386/ptrace.h~i386-specific	2005-07-10 16:55:32.000000000 +0200
-+++ clean-linux-2.6.11-paolo/include/asm-i386/ptrace.h	2005-07-10 16:55:32.000000000 +0200
-@@ -66,4 +66,26 @@ extern unsigned long profile_pc(struct p
- #endif
- #endif
- 
-+/*For SKAS3 support.*/
-+#ifndef _LINUX_PTRACE_STRUCT_DEF
-+#define _LINUX_PTRACE_STRUCT_DEF
-+
-+#define PTRACE_FAULTINFO	  52
-+#define PTRACE_SIGPENDING	  53
-+#define PTRACE_LDT		  54
-+#define PTRACE_SWITCH_MM 	  55
-+
-+struct ptrace_faultinfo {
-+	int is_write;
-+	unsigned long addr;
-+};
-+
-+struct ptrace_ldt {
-+	int func;
-+  	void *ptr;
-+	unsigned long bytecount;
-+};
-+
-+#endif /*ifndef _LINUX_PTRACE_STRUCT_DEF*/
-+
- #endif
---- clean-linux-2.6.11-paolo/include/asm-i386/mmu_context.h	2005-07-10 16:57:40.000000000 +0200
-+++ clean-linux-2.6.11-paolo/include/asm-i386/mmu_context.h	2005-07-10 16:55:33.000000000 +0200
-@@ -6,13 +6,25 @@
- #include <asm/atomic.h>
- #include <asm/pgalloc.h>
- #include <asm/tlbflush.h>
-+#include <asm/semaphore.h>
- 
- /*
-- * Used for LDT copy/destruction.
-+ * Used for LDT initialization/destruction. You cannot copy an LDT with
-+ * init_new_context, since it thinks you are passing it a new LDT and won't
-+ * deallocate its old content.
-  */
- int init_new_context(struct task_struct *tsk, struct mm_struct *mm);
- void destroy_context(struct mm_struct *mm);
- 
-+/* LDT initialization for a clean environment - needed for SKAS.*/
-+static inline void init_new_empty_context(struct mm_struct *mm)
-+{
-+	init_MUTEX(&mm->context.sem);
-+	mm->context.size = 0;
-+}
-+
-+/* LDT copy for SKAS - for the above problem.*/
-+int copy_context(struct mm_struct *mm, struct mm_struct *old_mm);
- 
- static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
- {
-@@ -29,6 +41,10 @@
- {
- 	int cpu = smp_processor_id();
- 
-+#ifdef CONFIG_SMP
-+	prev = per_cpu(cpu_tlbstate, cpu).active_mm;
-+#endif
-+
- 	if (likely(prev != next)) {
- 		/* stop flush ipis for the previous mm */
- 		cpu_clear(cpu, prev->cpu_vm_mask);
-@@ -50,7 +66,6 @@
- #ifdef CONFIG_SMP
- 	else {
- 		per_cpu(cpu_tlbstate, cpu).state = TLBSTATE_OK;
--		BUG_ON(per_cpu(cpu_tlbstate, cpu).active_mm != next);
- 
- 		if (!cpu_test_and_set(cpu, next->cpu_vm_mask)) {
- 			/* We were in lazy tlb mode and leave_mm disabled 
---- clean-linux-2.6.11-paolo/localversion-skas	2005-07-10 16:56:52.000000000 +0200
-+++ clean-linux-2.6.11-paolo/localversion-skas	2005-07-11 11:36:04.000000000 +0200
-@@ -0,0 +1 @@
-+-skas3-v8.2

Deleted: trunk/src/kernel-patch-skas/skas-2.6.12-v9-pre7.patch
===================================================================
--- trunk/src/kernel-patch-skas/skas-2.6.12-v9-pre7.patch	2006-08-27 15:01:30 UTC (rev 166)
+++ trunk/src/kernel-patch-skas/skas-2.6.12-v9-pre7.patch	2006-08-27 15:16:57 UTC (rev 167)
@@ -1,1989 +0,0 @@
---- linux-2.6.12-paolo/arch/i386/kernel/entry.S	2005-05-08 19:52:15.000000000 +0200
-+++ vanilla-linux-2.6.12-paolo/arch/i386/kernel/entry.S	2005-07-08 12:26:20.000000000 +0200
-@@ -203,7 +203,7 @@
- 	GET_THREAD_INFO(%ebp)
- 
- 	/* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */
--	testw $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),TI_flags(%ebp)
-+	testw $(_TIF_SYSCALL_EMU|_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT),TI_flags(%ebp)
- 	jnz syscall_trace_entry
- 	cmpl $(nr_syscalls), %eax
- 	jae syscall_badsys
-@@ -226,9 +226,9 @@
- 	pushl %eax			# save orig_eax
- 	SAVE_ALL
- 	GET_THREAD_INFO(%ebp)
--					# system call tracing in operation
-+					# system call tracing in operation / emulation
- 	/* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */
--	testw $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),TI_flags(%ebp)
-+	testw $(_TIF_SYSCALL_EMU|_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT),TI_flags(%ebp)
- 	jnz syscall_trace_entry
- 	cmpl $(nr_syscalls), %eax
- 	jae syscall_badsys
-@@ -338,6 +338,9 @@
- 	movl %esp, %eax
- 	xorl %edx,%edx
- 	call do_syscall_trace
-+	cmpl $0, %eax
-+	jne resume_userspace		# ret != 0 -> running under PTRACE_SYSEMU,
-+					# so must skip actual syscall
- 	movl ORIG_EAX(%esp), %eax
- 	cmpl $(nr_syscalls), %eax
- 	jnae syscall_call
---- linux-2.6.git-paolo/arch/i386/kernel/ptrace.c	2005-05-25 00:57:34.000000000 +0200
-+++ linux-2.6.git-paolo/arch/i386/kernel/ptrace.c	2005-05-21 18:00:55.000000000 +0200
-@@ -17,6 +17,7 @@
- #include <linux/audit.h>
- #include <linux/seccomp.h>
- #include <linux/signal.h>
-+#include <linux/proc_mm.h>
- 
- #include <asm/uaccess.h>
- #include <asm/pgtable.h>
-@@ -271,6 +272,8 @@
- void ptrace_disable(struct task_struct *child)
- { 
- 	clear_singlestep(child);
-+	clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-+	clear_tsk_thread_flag(child, TIF_SYSCALL_EMU);
- }
- 
- /*
-@@ -509,15 +512,20 @@
- 		  }
- 		  break;
- 
-+	case PTRACE_SYSEMU: /* continue and stop at next syscall, which will not be executed */
- 	case PTRACE_SYSCALL:	/* continue and stop at next (return from) syscall */
- 	case PTRACE_CONT:	/* restart after signal. */
- 		ret = -EIO;
- 		if (!valid_signal(data))
- 			break;
--		if (request == PTRACE_SYSCALL) {
-+		if (request == PTRACE_SYSEMU) {
-+			set_tsk_thread_flag(child, TIF_SYSCALL_EMU);
-+			clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-+		} else if (request == PTRACE_SYSCALL) {
- 			set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
--		}
--		else {
-+			clear_tsk_thread_flag(child, TIF_SYSCALL_EMU);
-+		} else {
-+			clear_tsk_thread_flag(child, TIF_SYSCALL_EMU);
- 			clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- 		}
- 		child->exit_code = data;
-@@ -542,10 +550,17 @@
- 		wake_up_process(child);
- 		break;
- 
-+	case PTRACE_SYSEMU_SINGLESTEP: /* Same as SYSEMU, but singlestep if not syscall */
- 	case PTRACE_SINGLESTEP:	/* set the trap flag. */
- 		ret = -EIO;
- 		if (!valid_signal(data))
- 			break;
-+
-+		if (request == PTRACE_SYSEMU_SINGLESTEP)
-+			set_tsk_thread_flag(child, TIF_SYSCALL_EMU);
-+		else
-+			clear_tsk_thread_flag(child, TIF_SYSCALL_EMU);
-+
- 		clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- 		set_singlestep(child);
- 		child->exit_code = data;
-@@ -645,6 +660,70 @@
- 					(struct user_desc __user *) data);
- 		break;
- 
-+#ifdef CONFIG_PROC_MM
-+	case PTRACE_EX_FAULTINFO: {
-+		struct ptrace_ex_faultinfo fault;
-+
-+		fault = ((struct ptrace_ex_faultinfo)
-+			{ .is_write	= child->thread.error_code,
-+			  .addr		= child->thread.cr2,
-+			  .trap_no	= child->thread.trap_no });
-+		ret = copy_to_user((unsigned long *) data, &fault,
-+				   sizeof(fault));
-+		if(ret)
-+			break;
-+		break;
-+	}
-+
-+	case PTRACE_FAULTINFO: {
-+		struct ptrace_faultinfo fault;
-+
-+		fault = ((struct ptrace_faultinfo)
-+			{ .is_write	= child->thread.error_code,
-+			  .addr		= child->thread.cr2 });
-+		ret = copy_to_user((unsigned long *) data, &fault,
-+				   sizeof(fault));
-+		if(ret)
-+			break;
-+		break;
-+	}
-+
-+	case PTRACE_LDT: {
-+		struct ptrace_ldt ldt;
-+
-+		if(copy_from_user(&ldt, (unsigned long *) data,
-+				  sizeof(ldt))){
-+			ret = -EIO;
-+			break;
-+		}
-+		ret = __modify_ldt(child->mm, ldt.func, ldt.ptr, ldt.bytecount);
-+		break;
-+	}
-+
-+	case PTRACE_SWITCH_MM: {
-+		struct mm_struct *old = child->mm;
-+		struct mm_struct *new = proc_mm_get_mm(data);
-+
-+		if(IS_ERR(new)){
-+			ret = PTR_ERR(new);
-+			break;
-+		}
-+
-+		atomic_inc(&new->mm_users);
-+
-+		lock_fix_dumpable_setting(child, new);
-+
-+		child->mm = new;
-+		child->active_mm = new;
-+
-+		task_unlock(child);
-+
-+		mmput(old);
-+		ret = 0;
-+		break;
-+	}
-+#endif
-+
- 	default:
- 		ret = ptrace_request(child, request, addr, data);
- 		break;
-@@ -678,26 +757,48 @@
-  * - triggered by current->work.syscall_trace
-  */
- __attribute__((regparm(3)))
--void do_syscall_trace(struct pt_regs *regs, int entryexit)
-+int do_syscall_trace(struct pt_regs *regs, int entryexit)
- {
-+	int is_sysemu = test_thread_flag(TIF_SYSCALL_EMU), ret = 0;
-+	/* With TIF_SYSCALL_EMU set we want to ignore TIF_SINGLESTEP */
-+	int is_singlestep = !is_sysemu && test_thread_flag(TIF_SINGLESTEP);
-+
- 	/* do the secure computing check first */
- 	secure_computing(regs->orig_eax);
- 
--	if (unlikely(current->audit_context) && entryexit)
--		audit_syscall_exit(current, AUDITSC_RESULT(regs->eax), regs->eax);
-+	if (unlikely(current->audit_context)) {
-+		if (entryexit)
-+			audit_syscall_exit(current, AUDITSC_RESULT(regs->eax), regs->eax);
-+		/* With TIF_SYSCALL_AUDIT | TIF_SINGLESTEP &&
-+		 * !TIF_SYSCALL_EMU we come in here, but must not
-+		 * continue with ptrace_notify().
-+		 * In the SINGLESTEP && ! _AUDIT case (i.e. normal one),
-+		 * entry.S will call us only on syscall exit and not on
-+		 * the syscall entry path, so let's be consistent.
-+		 */
-+		else if (is_singlestep)
-+			goto out;
-+	}
- 
- 	if (!(current->ptrace & PT_PTRACED))
- 		goto out;
- 
-+	/* If a process stops on the 1st tracepoint with SYSCALL_TRACE
-+	 * and then is resumed with SYSEMU_SINGLESTEP, it will come in
-+	 * here. We have to check this and return */
-+	if (is_sysemu && entryexit)
-+		return 0;
-+
- 	/* Fake a debug trap */
--	if (test_thread_flag(TIF_SINGLESTEP))
-+	if (is_singlestep)
- 		send_sigtrap(current, regs, 0);
- 
--	if (!test_thread_flag(TIF_SYSCALL_TRACE))
-+	if (!test_thread_flag(TIF_SYSCALL_TRACE) && !is_sysemu)
- 		goto out;
- 
- 	/* the 0x80 provides a way for the tracing parent to distinguish
- 	   between a syscall stop and SIGTRAP delivery */
-+	/* Note that the debugger could change the result of test_thread_flag!*/
- 	ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) ? 0x80 : 0));
- 
- 	/*
-@@ -711,7 +812,14 @@
- 	}
-+	ret = is_sysemu;
-  out:
- 	if (unlikely(current->audit_context) && !entryexit)
- 		audit_syscall_entry(current, AUDIT_ARCH_I386, regs->orig_eax,
- 				    regs->ebx, regs->ecx, regs->edx, regs->esi);
-+	if (ret == 0)
-+		return 0;
- 
-+	regs->orig_eax = -1; /* force skip of syscall restarting */
-+	if (unlikely(current->audit_context))
-+		audit_syscall_exit(current, AUDITSC_RESULT(regs->eax), regs->eax);
-+	return 1;
- }
---- linux-2.6.12-paolo/include/asm-i386/thread_info.h	2005-05-08 19:16:10.000000000 +0200
-+++ linux-2.6.git-paolo/include/asm-i386/thread_info.h	2005-05-06 16:26:26.000000000 +0200
-@@ -141,6 +141,7 @@
- #define TIF_IRET		5	/* return with iret */
- #define TIF_SYSCALL_AUDIT	7	/* syscall auditing active */
- #define TIF_SECCOMP		8	/* secure computing */
-+#define TIF_SYSCALL_EMU		9	/* syscall emulation active */
- #define TIF_POLLING_NRFLAG	16	/* true if poll_idle() is polling TIF_NEED_RESCHED */
- #define TIF_MEMDIE		17
- 
-@@ -150,13 +151,15 @@
- #define _TIF_NEED_RESCHED	(1<<TIF_NEED_RESCHED)
- #define _TIF_SINGLESTEP		(1<<TIF_SINGLESTEP)
- #define _TIF_IRET		(1<<TIF_IRET)
-+#define _TIF_SYSCALL_EMU	(1<<TIF_SYSCALL_EMU)
- #define _TIF_SYSCALL_AUDIT	(1<<TIF_SYSCALL_AUDIT)
- #define _TIF_SECCOMP		(1<<TIF_SECCOMP)
- #define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
- 
- /* work to do on interrupt/exception return */
- #define _TIF_WORK_MASK \
--  (0x0000FFFF & ~(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP|_TIF_SECCOMP))
-+  (0x0000FFFF & ~(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP|\
-+		  _TIF_SECCOMP|_TIF_SYSCALL_EMU))
- /* work to do on any return to u-space */
- #define _TIF_ALLWORK_MASK	(0x0000FFFF & ~_TIF_SECCOMP)
- 
---- linux-2.6.12-paolo/include/linux/ptrace.h	2005-05-08 19:16:10.000000000 +0200
-+++ linux-2.6.12-paolo/include/linux/ptrace.h	2005-05-08 19:57:03.000000000 +0200
-@@ -20,6 +20,8 @@
- #define PTRACE_DETACH		0x11
- 
- #define PTRACE_SYSCALL		  24
-+#define PTRACE_SYSEMU		  31
-+#define PTRACE_SYSEMU_SINGLESTEP  32
- 
- /* 0x4200-0x4300 are reserved for architecture-independent additions.  */
- #define PTRACE_SETOPTIONS	0x4200
---- linux-2.6.12/kernel/fork.c~host-sysemu-2.6.7-4	2005-05-08 19:16:10.000000000 +0200
-+++ linux-2.6.12-paolo/kernel/fork.c	2005-05-08 19:16:10.000000000 +0200
-@@ -989,6 +989,9 @@ static task_t *copy_process(unsigned lon
- 	 * of CLONE_PTRACE.
- 	 */
- 	clear_tsk_thread_flag(p, TIF_SYSCALL_TRACE);
-+#ifdef TIF_SYSCALL_EMU
-+	clear_tsk_thread_flag(p, TIF_SYSCALL_EMU);
-+#endif
- 
- 	/* Our parent execution domain becomes current domain
- 	   These must match for thread signalling to apply */
---- linux-2.6.git/include/linux/mm.h~Add_generic_proc_mm_support	2005-05-19 15:40:16.000000000 +0200
-+++ linux-2.6.git-paolo/include/linux/mm.h	2005-05-19 15:40:16.000000000 +0200
-@@ -654,6 +654,9 @@ struct shrinker;
- extern struct shrinker *set_shrinker(int, shrinker_t);
- extern void remove_shrinker(struct shrinker *shrinker);
- 
-+extern long do_mprotect(struct mm_struct *mm, unsigned long start,
-+			size_t len, unsigned long prot);
-+
- /*
-  * On a two-level or three-level page table, this ends up being trivial. Thus
-  * the inlining and the symmetry break with pte_alloc_map() that does all
-@@ -730,9 +733,15 @@ extern int may_expand_vm(struct mm_struc
- 
- extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
- 
--extern unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
-+extern unsigned long __do_mmap_pgoff(struct mm_struct *mm, struct file *file,
-+				   unsigned long addr, unsigned long len,
-+				   unsigned long prot, unsigned long flag,
-+				   unsigned long pgoff);
-+static inline unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
- 	unsigned long len, unsigned long prot,
--	unsigned long flag, unsigned long pgoff);
-+	unsigned long flag, unsigned long pgoff) {
-+	return __do_mmap_pgoff(current->mm, file, addr, len, prot, flag, pgoff);
-+}
- 
- static inline unsigned long do_mmap(struct file *file, unsigned long addr,
- 	unsigned long len, unsigned long prot,
---- linux-2.6.git-paolo/include/linux/proc_mm.h	2005-06-02 05:03:04.000000000 +0200
-+++ linux-2.6.git-paolo/include/linux/proc_mm.h	2005-06-02 05:02:46.000000000 +0200
-@@ -0,0 +1,114 @@
-+/*
-+ * Copyright (C) 2002 Jeff Dike (jdike at karaya.com)
-+ * Licensed under the GPL
-+ */
-+
-+#ifndef __PROC_MM_H
-+#define __PROC_MM_H
-+
-+#include <linux/config.h>
-+#include <linux/sched.h>
-+#include <linux/compiler.h>
-+
-+/* The differences between this one and do_mmap are that:
-+ * - we must perform controls for userspace-supplied params (which are
-+ *   arch-specific currently). And also fget(fd) if needed and so on...
-+ * - we must accept the struct mm_struct on which to act as first param, and the
-+ *   offset in byte rather than page units as last param.
-+ */
-+static inline long __do_mmap(struct mm_struct *mm, unsigned long addr,
-+		     unsigned long len, unsigned long prot,
-+		     unsigned long flags, unsigned long fd,
-+		     unsigned long off);
-+
-+/* This header can be used only on archs defining CONFIG_PROC_MM in their
-+ * configs, so asm/proc_mm.h can still exist only for the needed archs.
-+ * Including it only in the x86-64 case does not make sense.*/
-+#include <asm/proc_mm.h>
-+
-+/*XXX: this is defined on x86_64, but not on every 64-bit arch (not on sh64).*/
-+#ifdef CONFIG_64BIT
-+
-+#define write_proc_mm write_proc_mm_emul
-+#define write_proc_mm64 write_proc_mm_native
-+
-+/* It would make more sense to do this mapping the reverse direction, to map the
-+ * called name to the defined one and not the reverse. Like the 2nd example
-+ */
-+/*#define proc_mm_get_mm proc_mm_get_mm_emul
-+#define proc_mm_get_mm64 proc_mm_get_mm_native*/
-+
-+#define proc_mm_get_mm_emul proc_mm_get_mm
-+#define proc_mm_get_mm_native proc_mm_get_mm64
-+
-+#else
-+
-+#define write_proc_mm write_proc_mm_native
-+#undef write_proc_mm64
-+
-+/*#define proc_mm_get_mm proc_mm_get_mm_native
-+#undef proc_mm_get_mm64*/
-+
-+#define proc_mm_get_mm_native proc_mm_get_mm
-+#undef proc_mm_get_mm_emul
-+
-+#endif
-+
-+#define MM_MMAP 54
-+#define MM_MUNMAP 55
-+#define MM_MPROTECT 56
-+#define MM_COPY_SEGMENTS 57
-+
-+struct mm_mmap {
-+	unsigned long addr;
-+	unsigned long len;
-+	unsigned long prot;
-+	unsigned long flags;
-+	unsigned long fd;
-+	unsigned long offset;
-+};
-+
-+struct mm_munmap {
-+	unsigned long addr;
-+	unsigned long len;
-+};
-+
-+struct mm_mprotect {
-+	unsigned long addr;
-+	unsigned long len;
-+        unsigned int prot;
-+};
-+
-+struct proc_mm_op {
-+	int op;
-+	union {
-+		struct mm_mmap mmap;
-+		struct mm_munmap munmap;
-+	        struct mm_mprotect mprotect;
-+		int copy_segments;
-+	} u;
-+};
-+
-+extern struct mm_struct *proc_mm_get_mm(int fd);
-+
-+/* Cope with older kernels */
-+#ifndef __acquires
-+#define __acquires(x)
-+#endif
-+
-+#ifdef CONFIG_PROC_MM_DUMPABLE
-+/*
-+ * Since we take task_lock of child and it's needed also by the caller, we
-+ * return with it locked.
-+ */
-+extern void lock_fix_dumpable_setting(struct task_struct * child,
-+		struct mm_struct* new) __acquires(child->alloc_lock);
-+#else
-+static inline void lock_fix_dumpable_setting(struct task_struct * child,
-+		struct mm_struct* new) __acquires(child->alloc_lock)
-+{
-+	task_lock(child);
-+}
-+#endif
-+
-+#endif
---- linux-2.6.git-paolo/mm/Makefile	2005-05-19 15:40:16.000000000 +0200
-+++ linux-2.6.git-paolo/mm/Makefile	2005-05-21 18:00:57.000000000 +0200
-@@ -20,0 +21,5 @@
-+obj-$(CONFIG_PROC_MM)	+= proc_mm.o
-+
-+ifeq ($(CONFIG_PROC_MM),y)
-+obj-m			+= proc_mm-mod.o
-+endif
---- linux-2.6.git/mm/mmap.c~Add_generic_proc_mm_support	2005-05-19 15:40:16.000000000 +0200
-+++ linux-2.6.git-paolo/mm/mmap.c	2005-05-19 15:40:16.000000000 +0200
-@@ -864,11 +864,11 @@ void __vm_stat_account(struct mm_struct 
-  * The caller must hold down_write(current->mm->mmap_sem).
-  */
- 
--unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
--			unsigned long len, unsigned long prot,
--			unsigned long flags, unsigned long pgoff)
-+unsigned long __do_mmap_pgoff(struct mm_struct *mm, struct file * file,
-+			    unsigned long addr, unsigned long len,
-+			    unsigned long prot, unsigned long flags,
-+			    unsigned long pgoff)
- {
--	struct mm_struct * mm = current->mm;
- 	struct vm_area_struct * vma, * prev;
- 	struct inode *inode;
- 	unsigned int vm_flags;
-@@ -1143,7 +1143,7 @@ unacct_error:
- 	return error;
- }
- 
--EXPORT_SYMBOL(do_mmap_pgoff);
-+EXPORT_SYMBOL(__do_mmap_pgoff);
- 
- /* Get an address range which is currently unmapped.
-  * For shmat() with addr=0.
---- linux-2.6.git-paolo/mm/mprotect.c	2005-05-19 15:40:16.000000000 +0200
-+++ vanilla-linux-2.6.12-paolo/mm/mprotect.c	2005-07-10 20:08:24.000000000 +0200
-@@ -177,8 +177,9 @@
- 	return error;
- }
- 
--asmlinkage long
--sys_mprotect(unsigned long start, size_t len, unsigned long prot)
-+long
-+do_mprotect(struct mm_struct *mm, unsigned long start, size_t len,
-+	     unsigned long prot)
- {
- 	unsigned long vm_flags, nstart, end, tmp, reqprot;
- 	struct vm_area_struct *vma, *prev;
-@@ -209,9 +210,9 @@
- 
- 	vm_flags = calc_vm_prot_bits(prot);
- 
--	down_write(&current->mm->mmap_sem);
-+	down_write(&mm->mmap_sem);
- 
--	vma = find_vma_prev(current->mm, start, &prev);
-+	vma = find_vma_prev(mm, start, &prev);
- 	error = -ENOMEM;
- 	if (!vma)
- 		goto out;
-@@ -280,3 +281,12 @@
--	up_write(&current->mm->mmap_sem);
-+	up_write(&mm->mmap_sem);
- 	return error;
- }
-+
-+asmlinkage long sys_mprotect(unsigned long start, size_t len, unsigned long prot)
-+{
-+	long ret = do_mprotect(current->mm, start, len, prot);
-+	/* A tail call would reorder parameters on the stack and they would then
-+	 * be restored at the wrong places. */
-+	prevent_tail_call(ret);
-+	return ret;
-+}
---- linux-2.6.git-paolo/mm/proc_mm.c	2005-06-02 05:03:04.000000000 +0200
-+++ linux-2.6.git-paolo/mm/proc_mm.c	2005-06-02 05:02:46.000000000 +0200
-@@ -0,0 +1,300 @@
-+/*
-+ * Copyright (C) 2002 Jeff Dike (jdike at karaya.com)
-+ * Licensed under the GPL
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/compiler.h>
-+#include <linux/mm.h>
-+#include <linux/init.h>
-+#include <linux/proc_fs.h>
-+#include <linux/proc_mm.h>
-+#include <linux/file.h>
-+#include <linux/mman.h>
-+#include <asm/uaccess.h>
-+#include <asm/mmu_context.h>
-+
-+#ifdef CONFIG_PROC_MM_DUMPABLE
-+/* Checks if a task must be considered dumpable
-+ *
-+ * XXX: copied from fs/proc/base.c, removed task_lock, added rmb(): this must be
-+ * called with task_lock(task) held. */
-+static int task_dumpable(struct task_struct *task)
-+{
-+	int dumpable = 0;
-+	struct mm_struct *mm;
-+
-+	mm = task->mm;
-+	if (mm) {
-+		rmb();
-+		dumpable = mm->dumpable;
-+	}
-+	return dumpable;
-+}
-+
-+/*
-+ * This is to be used in PTRACE_SWITCH_MM handling. We are going to set
-+ * child->mm to new, and we must first correctly set new->dumpable.
-+ * Since we take task_lock of child and it's needed also by the caller, we
-+ * return with it locked.
-+ */
-+void lock_fix_dumpable_setting(struct task_struct* child, struct mm_struct* new)
-+	__acquires(child->alloc_lock)
-+{
-+	int dumpable = 1;
-+
-+	/* We must be safe.
-+	 * If the child is ptraced from a non-dumpable process,
-+	 * let's not be dumpable. If the child is non-dumpable itself,
-+	 * copy this property across mm's.
-+	 *
-+	 * Don't try to be smart for the opposite case and turn
-+	 * child->mm->dumpable to 1: I've not made sure it is safe.
-+	 */
-+
-+	task_lock(current);
-+	if (unlikely(!task_dumpable(current))) {
-+		dumpable = 0;
-+	}
-+	task_unlock(current);
-+
-+	task_lock(child);
-+	if (likely(dumpable) && unlikely(!task_dumpable(child))) {
-+		dumpable = 0;
-+	}
-+
-+	if (!dumpable) {
-+		new->dumpable = 0;
-+		wmb();
-+	}
-+}
-+#endif
-+
-+/* Naming conventions are a mess, so I note them down.
-+ *
-+ * Things ending in _mm can be for everything. It's only for
-+ * {open,release}_proc_mm.
-+ *
-+ * For the rest:
-+ *
-+ * _mm means /proc/mm, _mm64 means /proc/mm64. This is for the infrastructure
-+ * only (for instance proc_mm_get_mm checks whether the file is /proc/mm or
-+ * /proc/mm64; for instance the /proc handling).
-+ *
-+ * While for what is conversion dependant, we use the suffix _native and _emul.
-+ * In some cases, there is a mapping between these ones (defined by
-+ * <asm/proc_mm.h>).
-+ */
-+
-+/*These two are common to everything.*/
-+static int open_proc_mm(struct inode *inode, struct file *file)
-+{
-+	struct mm_struct *mm = mm_alloc();
-+	int ret;
-+
-+	ret = -ENOMEM;
-+	if(mm == NULL)
-+		goto out_mem;
-+
-+	init_new_empty_context(mm);
-+	arch_pick_mmap_layout(mm);
-+#ifdef CONFIG_PROC_MM_DUMPABLE
-+	mm->dumpable = current->mm->dumpable;
-+	wmb();
-+#endif
-+
-+	file->private_data = mm;
-+
-+	return 0;
-+
-+out_mem:
-+	return ret;
-+}
-+
-+static int release_proc_mm(struct inode *inode, struct file *file)
-+{
-+	struct mm_struct *mm = file->private_data;
-+
-+	mmput(mm);
-+	return 0;
-+}
-+
-+static struct file_operations proc_mm_fops;
-+
-+struct mm_struct *proc_mm_get_mm_native(int fd);
-+
-+static ssize_t write_proc_mm_native(struct file *file, const char *buffer,
-+			     size_t count, loff_t *ppos)
-+{
-+	struct mm_struct *mm = file->private_data;
-+	struct proc_mm_op req;
-+	int n, ret;
-+
-+	if(count > sizeof(req))
-+		return(-EINVAL);
-+
-+	n = copy_from_user(&req, buffer, count);
-+	if(n != 0)
-+		return(-EFAULT);
-+
-+	ret = count;
-+	switch(req.op){
-+	case MM_MMAP: {
-+		struct mm_mmap *map = &req.u.mmap;
-+
-+		/* Nobody ever noticed it, but do_mmap_pgoff() calls
-+		 * get_unmapped_area() which checks current->mm, if
-+		 * MAP_FIXED is not set, so mmap() could replace
-+		 * an old mapping.
-+		 */
-+		if (! (map->flags & MAP_FIXED))
-+			return(-EINVAL);
-+
-+		ret = __do_mmap(mm, map->addr, map->len, map->prot,
-+			       map->flags, map->fd, map->offset);
-+		if((ret & ~PAGE_MASK) == 0)
-+			ret = count;
-+
-+		break;
-+	}
-+	case MM_MUNMAP: {
-+		struct mm_munmap *unmap = &req.u.munmap;
-+
-+		down_write(&mm->mmap_sem);
-+		ret = do_munmap(mm, unmap->addr, unmap->len);
-+		up_write(&mm->mmap_sem);
-+
-+		if(ret == 0)
-+			ret = count;
-+		break;
-+	}
-+	case MM_MPROTECT: {
-+		struct mm_mprotect *protect = &req.u.mprotect;
-+
-+		ret = do_mprotect(mm, protect->addr, protect->len,
-+				  protect->prot);
-+		if(ret == 0)
-+			ret = count;
-+		break;
-+	}
-+
-+	case MM_COPY_SEGMENTS: {
-+		struct mm_struct *from = proc_mm_get_mm_native(req.u.copy_segments);
-+
-+		if(IS_ERR(from)){
-+			ret = PTR_ERR(from);
-+			break;
-+		}
-+
-+		ret = copy_context(mm, from);
-+		if(ret == 0)
-+			ret = count;
-+		break;
-+	}
-+	default:
-+		ret = -EINVAL;
-+		break;
-+	}
-+
-+	return ret;
-+}
-+
-+/*These three are all for /proc/mm.*/
-+struct mm_struct *proc_mm_get_mm(int fd)
-+{
-+	struct mm_struct *ret = ERR_PTR(-EBADF);
-+	struct file *file;
-+
-+	file = fget(fd);
-+	if (!file)
-+		goto out;
-+
-+	ret = ERR_PTR(-EINVAL);
-+	if(file->f_op != &proc_mm_fops)
-+		goto out_fput;
-+
-+	ret = file->private_data;
-+out_fput:
-+	fput(file);
-+out:
-+	return(ret);
-+}
-+
-+static struct file_operations proc_mm_fops = {
-+	.open		= open_proc_mm,
-+	.release	= release_proc_mm,
-+	.write		= write_proc_mm,
-+};
-+
-+/*Macro-ify it to avoid the duplication.*/
-+static int make_proc_mm(void)
-+{
-+	struct proc_dir_entry *ent;
-+
-+	ent = create_proc_entry("mm", 0222, &proc_root);
-+	if(ent == NULL){
-+		printk("make_proc_mm : Failed to register /proc/mm\n");
-+		return(0);
-+	}
-+	ent->proc_fops = &proc_mm_fops;
-+
-+	return 0;
-+}
-+
-+__initcall(make_proc_mm);
-+
-+/*XXX: change the option.*/
-+#ifdef CONFIG_64BIT
-+static struct file_operations proc_mm64_fops = {
-+	.open		= open_proc_mm,
-+	.release	= release_proc_mm,
-+	.write		= write_proc_mm64,
-+};
-+
-+static int make_proc_mm64(void)
-+{
-+	struct proc_dir_entry *ent;
-+
-+	ent = create_proc_entry("mm64", 0222, &proc_root);
-+	if(ent == NULL){
-+		printk("make_proc_mm : Failed to register /proc/mm64\n");
-+		return(0);
-+	}
-+	ent->proc_fops = &proc_mm64_fops;
-+
-+	return 0;
-+}
-+
-+__initcall(make_proc_mm64);
-+
-+struct mm_struct *proc_mm_get_mm64(int fd)
-+{
-+	struct mm_struct *ret = ERR_PTR(-EBADF);
-+	struct file *file;
-+
-+	file = fget(fd);
-+	if (!file)
-+		goto out;
-+
-+	ret = ERR_PTR(-EINVAL);
-+	/*This is the only change.*/
-+	if(file->f_op != &proc_mm64_fops)
-+		goto out_fput;
-+
-+	ret = file->private_data;
-+out_fput:
-+	fput(file);
-+out:
-+	return(ret);
-+}
-+#endif
-+/*
-+ * Overrides for Emacs so that we follow Linus's tabbing style.
-+ * Emacs will notice this stuff at the end of the file and automatically
-+ * adjust the settings for this buffer only.  This must remain at the end
-+ * of the file.
-+ * ---------------------------------------------------------------------------
-+ * Local variables:
-+ * c-file-style: "linux"
-+ * End:
-+ */
---- linux-2.6.git/arch/um/include/skas_ptrace.h~Add_generic_proc_mm_support	2005-05-19 15:40:16.000000000 +0200
-+++ linux-2.6.git-paolo/arch/um/include/skas_ptrace.h	2005-05-19 15:40:16.000000000 +0200
-@@ -6,6 +6,8 @@
- #ifndef __SKAS_PTRACE_H
- #define __SKAS_PTRACE_H
- 
-+#ifndef PTRACE_FAULTINFO
-+
- #define PTRACE_FAULTINFO 52
- #define PTRACE_SWITCH_MM 55
- 
-@@ -13,6 +15,8 @@
- 
- #endif
- 
-+#endif
-+
- /*
-  * Overrides for Emacs so that we follow Linus's tabbing style.
-  * Emacs will notice this stuff at the end of the file and automatically
---- linux-2.6.12-paolo/arch/i386/Kconfig	2005-05-08 19:47:37.000000000 +0200
-+++ linux-2.6.git-paolo/arch/i386/Kconfig	2005-06-02 05:02:46.000000000 +0200
-@@ -769,6 +769,26 @@
- 	depends on HIGHMEM64G
- 	default y
- 
-+config PROC_MM
-+	bool "/proc/mm support"
-+	default y
-+
-+config PROC_MM_DUMPABLE
-+	bool "Make UML childs /proc/<pid> completely browsable"
-+	default n
-+	help
-+	  If in doubt, say N.
-+
-+	  This fiddles with some settings to make sure /proc/<pid> is completely
-+	  browsable by who started UML, at the expense of some additional
-+	  locking (maybe this could slow down the runned UMLs of a few percents,
-+	  I've not tested this).
-+
-+	  Also, if there is a bug in this feature, there is some little
-+	  possibility to do privilege escalation if you have UML installed
-+	  setuid (which you shouldn't have done) or if UML changes uid on
-+	  startup (which will be a good thing, when enabled) ...
-+
- # Common NUMA Features
- config NUMA
- 	bool "Numa Memory Allocation and Scheduler Support"
---- linux-2.6.11-paolo/arch/i386/kernel/ldt.c	2005-02-10 13:25:39.841170200 +0100
-+++ vanilla-linux-2.6.12-paolo/arch/i386/kernel/ldt.c	2005-07-10 20:08:06.000000000 +0200
-@@ -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)
-@@ -27,11 +28,12 @@
- }
- #endif
- 
--static int alloc_ldt(mm_context_t *pc, int mincount, int reload)
-+static int alloc_ldt(struct mm_struct *mm, int mincount, int reload)
- {
- 	void *oldldt;
- 	void *newldt;
- 	int oldsize;
-+	mm_context_t * pc = &mm->context;
- 
- 	if (mincount <= pc->size)
- 		return 0;
-@@ -58,13 +60,15 @@
- #ifdef CONFIG_SMP
- 		cpumask_t mask;
- 		preempt_disable();
--		load_LDT(pc);
-+		if (&current->active_mm->context == pc)
-+			load_LDT(pc);
- 		mask = cpumask_of_cpu(smp_processor_id());
--		if (!cpus_equal(current->mm->cpu_vm_mask, mask))
-+		if (!cpus_equal(mm->cpu_vm_mask, mask))
- 			smp_call_function(flush_ldt, NULL, 1, 1);
- 		preempt_enable();
- #else
--		load_LDT(pc);
-+		if (&current->active_mm->context == pc)
-+			load_LDT(pc);
- #endif
- 	}
- 	if (oldsize) {
-@@ -76,12 +80,12 @@
- 	return 0;
- }
- 
--static inline int copy_ldt(mm_context_t *new, mm_context_t *old)
-+static inline int copy_ldt(struct mm_struct *new, struct mm_struct *old)
- {
--	int err = alloc_ldt(new, old->size, 0);
-+	int err = alloc_ldt(new, old->context.size, 0);
- 	if (err < 0)
- 		return err;
--	memcpy(new->ldt, old->ldt, old->size*LDT_ENTRY_SIZE);
-+	memcpy(new->context.ldt, old->context.ldt, old->context.size*LDT_ENTRY_SIZE);
- 	return 0;
- }
- 
-@@ -89,22 +93,24 @@
-  * we do not have to muck with descriptors here, that is
-  * done in switch_mm() as needed.
-  */
--int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
-+int copy_context(struct mm_struct *mm, struct mm_struct *old_mm)
- {
--	struct mm_struct * old_mm;
- 	int retval = 0;
- 
--	init_MUTEX(&mm->context.sem);
--	mm->context.size = 0;
--	old_mm = current->mm;
- 	if (old_mm && old_mm->context.size > 0) {
- 		down(&old_mm->context.sem);
--		retval = copy_ldt(&mm->context, &old_mm->context);
-+		retval = copy_ldt(mm, old_mm);
- 		up(&old_mm->context.sem);
- 	}
- 	return retval;
- }
- 
-+int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
-+{
-+	init_new_empty_context(mm);
-+	return copy_context(mm, current->mm);
-+}
-+
- /*
-  * No need to lock the MM as we are the last user
-  */
-@@ -121,11 +127,11 @@
- 	}
- }
- 
--static int read_ldt(void __user * ptr, unsigned long bytecount)
-+static int read_ldt(struct mm_struct * mm, void __user * ptr,
-+		    unsigned long bytecount)
- {
- 	int err;
- 	unsigned long size;
--	struct mm_struct * mm = current->mm;
- 
- 	if (!mm->context.size)
- 		return 0;
-@@ -174,9 +180,8 @@
- 	return err;
- }
- 
--static int write_ldt(void __user * ptr, unsigned long bytecount, int oldmode)
-+static int write_ldt(struct mm_struct * mm, void __user * ptr, unsigned long bytecount, int oldmode)
- {
--	struct mm_struct * mm = current->mm;
- 	__u32 entry_1, entry_2, *lp;
- 	int error;
- 	struct user_desc ldt_info;
-@@ -200,7 +205,7 @@
- 
- 	down(&mm->context.sem);
- 	if (ldt_info.entry_number >= mm->context.size) {
--		error = alloc_ldt(&current->mm->context, ldt_info.entry_number+1, 1);
-+		error = alloc_ldt(mm, ldt_info.entry_number+1, 1);
- 		if (error < 0)
- 			goto out_unlock;
- 	}
-@@ -236,20 +241,30 @@
--asmlinkage int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
-+int __modify_ldt(struct mm_struct * mm, int func, void __user *ptr,
-+	       unsigned long bytecount)
- {
- 	int ret = -ENOSYS;
- 
- 	switch (func) {
- 	case 0:
--		ret = read_ldt(ptr, bytecount);
-+		ret = read_ldt(mm, ptr, bytecount);
- 		break;
- 	case 1:
--		ret = write_ldt(ptr, bytecount, 1);
-+		ret = write_ldt(mm, ptr, bytecount, 1);
- 		break;
- 	case 2:
- 		ret = read_default_ldt(ptr, bytecount);
- 		break;
- 	case 0x11:
--		ret = write_ldt(ptr, bytecount, 0);
-+		ret = write_ldt(mm, ptr, bytecount, 0);
- 		break;
- 	}
- 	return ret;
- }
-+
-+asmlinkage int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
-+{
-+	int ret = __modify_ldt(current->mm, func, ptr, bytecount);
-+	/* A tail call would reorder parameters on the stack and they would then
-+	 * be restored at the wrong places. */
-+	prevent_tail_call(ret);
-+	return ret;
-+}
---- linux-2.6.12-paolo/arch/i386/kernel/sys_i386.c	2005-05-08 19:47:37.000000000 +0200
-+++ vanilla-linux-2.6.12-paolo/arch/i386/kernel/sys_i386.c	2005-07-10 16:06:02.000000000 +0200
-@@ -41,7 +41,7 @@
- }
- 
- /* common code for old and new mmaps */
--static inline long do_mmap2(
-+long do_mmap2(struct mm_struct *mm,
- 	unsigned long addr, unsigned long len,
- 	unsigned long prot, unsigned long flags,
- 	unsigned long fd, unsigned long pgoff)
-@@ -56,9 +56,9 @@
- 			goto out;
- 	}
- 
--	down_write(&current->mm->mmap_sem);
--	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
--	up_write(&current->mm->mmap_sem);
-+	down_write(&mm->mmap_sem);
-+	error = __do_mmap_pgoff(mm, file, addr, len, prot, flags, pgoff);
-+	up_write(&mm->mmap_sem);
- 
- 	if (file)
- 		fput(file);
-@@ -70,7 +70,12 @@
- 	unsigned long prot, unsigned long flags,
- 	unsigned long fd, unsigned long pgoff)
- {
--	return do_mmap2(addr, len, prot, flags, fd, pgoff);
-+	long ret = do_mmap2(current->mm, addr, len, prot, flags, fd, pgoff);
-+
-+	/* A tail call would reorder parameters on the stack and they would then
-+	 * be restored at the wrong places. */
-+	prevent_tail_call(ret);
-+	return ret;
- }
- 
- /*
-@@ -101,7 +106,10 @@
- 	if (a.offset & ~PAGE_MASK)
- 		goto out;
- 
--	err = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
-+	err = do_mmap2(current->mm, a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
-+	/* A tail call would reorder parameters on the stack and they would then
-+	 * be restored at the wrong places. */
-+	prevent_tail_call(err);
- out:
- 	return err;
- }
---- linux-2.6.12/include/asm-i386/desc.h~i386-specific	2005-05-08 19:47:37.000000000 +0200
-+++ linux-2.6.12-paolo/include/asm-i386/desc.h	2005-05-08 19:47:37.000000000 +0200
-@@ -139,6 +139,9 @@ static inline unsigned long get_desc_bas
- 	return base;
- }
- 
-+extern int __modify_ldt(struct mm_struct * mm, int func, void __user *ptr,
-+		      unsigned long bytecount);
-+
- #endif /* !__ASSEMBLY__ */
- 
- #endif
---- linux-2.6.git-paolo/include/asm-i386/ptrace.h	2005-05-25 00:57:34.000000000 +0200
-+++ linux-2.6.git-paolo/include/asm-i386/ptrace.h	2005-05-21 18:00:55.000000000 +0200
-@@ -68,2 +68,31 @@
- 
-+/*For SKAS3 support.*/
-+#ifndef _LINUX_PTRACE_STRUCT_DEF
-+#define _LINUX_PTRACE_STRUCT_DEF
-+
-+#define PTRACE_FAULTINFO	  52
-+/* 53 was used for PTRACE_SIGPENDING, don't reuse it. */
-+#define PTRACE_LDT		  54
-+#define PTRACE_SWITCH_MM 	  55
-+#define PTRACE_EX_FAULTINFO	  56
-+
-+struct ptrace_faultinfo {
-+	int is_write;
-+	unsigned long addr;
-+};
-+
-+struct ptrace_ex_faultinfo {
-+	int is_write;
-+	unsigned long addr;
-+	int trap_no;
-+};
-+
-+struct ptrace_ldt {
-+	int func;
-+  	void *ptr;
-+	unsigned long bytecount;
-+};
-+
-+#endif /*ifndef _LINUX_PTRACE_STRUCT_DEF*/
-+
- #endif
---- linux-2.6.12-paolo/include/asm-i386/mmu_context.h	2005-05-08 19:48:07.000000000 +0200
-+++ linux-2.6.12-paolo/include/asm-i386/mmu_context.h	2005-05-08 19:35:02.000000000 +0200
-@@ -6,13 +6,25 @@
- #include <asm/atomic.h>
- #include <asm/pgalloc.h>
- #include <asm/tlbflush.h>
-+#include <asm/semaphore.h>
- 
- /*
-- * Used for LDT copy/destruction.
-+ * Used for LDT initialization/destruction. You cannot copy an LDT with
-+ * init_new_context, since it thinks you are passing it a new LDT and won't
-+ * deallocate its old content.
-  */
- int init_new_context(struct task_struct *tsk, struct mm_struct *mm);
- void destroy_context(struct mm_struct *mm);
- 
-+/* LDT initialization for a clean environment - needed for SKAS.*/
-+static inline void init_new_empty_context(struct mm_struct *mm)
-+{
-+	init_MUTEX(&mm->context.sem);
-+	mm->context.size = 0;
-+}
-+
-+/* LDT copy for SKAS - for the above problem.*/
-+int copy_context(struct mm_struct *mm, struct mm_struct *old_mm);
- 
- static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
- {
-@@ -29,6 +41,10 @@
- {
- 	int cpu = smp_processor_id();
- 
-+#ifdef CONFIG_SMP
-+	prev = per_cpu(cpu_tlbstate, cpu).active_mm;
-+#endif
-+
- 	if (likely(prev != next)) {
- 		/* stop flush ipis for the previous mm */
- 		cpu_clear(cpu, prev->cpu_vm_mask);
-@@ -50,7 +66,6 @@
- #ifdef CONFIG_SMP
- 	else {
- 		per_cpu(cpu_tlbstate, cpu).state = TLBSTATE_OK;
--		BUG_ON(per_cpu(cpu_tlbstate, cpu).active_mm != next);
- 
- 		if (!cpu_test_and_set(cpu, next->cpu_vm_mask)) {
- 			/* We were in lazy tlb mode and leave_mm disabled 
---- vanilla-linux-2.6.12-paolo/localversion-skas	2005-07-10 11:36:59.000000000 +0200
-+++ vanilla-linux-2.6.12-paolo/localversion-skas	2005-07-11 11:51:53.000000000 +0200
-@@ -0,0 +1 @@
-+-skas3-v9-pre7
---- linux-2.6.git-paolo/arch/x86_64/mm/proc_mm.c	2005-06-02 05:03:04.000000000 +0200
-+++ linux-2.6.git-paolo/arch/x86_64/mm/proc_mm.c	2005-05-15 18:32:11.000000000 +0200
-@@ -0,0 +1,85 @@
-+#include <linux/proc_mm.h>
-+#include <linux/mm.h>
-+#include <linux/init.h>
-+#include <linux/proc_fs.h>
-+#include <linux/file.h>
-+#include <linux/mman.h>
-+#include <asm/uaccess.h>
-+#include <asm/mmu_context.h>
-+
-+ssize_t write_proc_mm_emul(struct file *file, const char *buffer,
-+			     size_t count, loff_t *ppos)
-+{
-+	struct mm_struct *mm = file->private_data;
-+	struct proc_mm_op32 req;
-+	int n, ret;
-+
-+	if(count > sizeof(req))
-+		return(-EINVAL);
-+
-+	n = copy_from_user(&req, buffer, count);
-+	if(n != 0)
-+		return(-EFAULT);
-+
-+	ret = count;
-+	switch(req.op){
-+	case MM_MMAP: {
-+		struct mm_mmap32 *map = &req.u.mmap;
-+
-+		/* Nobody ever noticed it, but do_mmap_pgoff() calls
-+		 * get_unmapped_area() which checks current->mm, if
-+		 * MAP_FIXED is not set, so mmap() could replace
-+		 * an old mapping.
-+		 */
-+		if (! (map->flags & MAP_FIXED))
-+			return(-EINVAL);
-+
-+		ret = __do_mmap(mm, map->addr, map->len, map->prot,
-+			       map->flags, map->fd, map->offset);
-+		if((ret & ~PAGE_MASK) == 0)
-+			ret = count;
-+
-+		break;
-+	}
-+	case MM_MUNMAP: {
-+		struct mm_munmap32 *unmap = &req.u.munmap;
-+
-+		down_write(&mm->mmap_sem);
-+		ret = do_munmap(mm, unmap->addr, unmap->len);
-+		up_write(&mm->mmap_sem);
-+
-+		if(ret == 0)
-+			ret = count;
-+		break;
-+	}
-+	case MM_MPROTECT: {
-+		struct mm_mprotect32 *protect = &req.u.mprotect;
-+
-+		ret = do_mprotect(mm, protect->addr, protect->len,
-+				  protect->prot);
-+		if(ret == 0)
-+			ret = count;
-+		break;
-+	}
-+
-+	case MM_COPY_SEGMENTS: {
-+		struct mm_struct *from = proc_mm_get_mm_emul(req.u.copy_segments);
-+
-+		if(IS_ERR(from)){
-+			ret = PTR_ERR(from);
-+			break;
-+		}
-+
-+		ret = copy_context(mm, from);
-+		if(ret == 0)
-+			ret = count;
-+		break;
-+	}
-+	default:
-+		ret = -EINVAL;
-+		break;
-+	}
-+
-+	return ret;
-+}
-+
---- /dev/null	2005-05-28 23:34:14.051125088 +0200
-+++ linux-2.6.git-paolo/include/asm-x86_64/proc_mm.h	2005-06-02 05:03:04.000000000 +0200
-@@ -0,0 +1,56 @@
-+#ifndef __ASM_PROC_MM
-+#define __ASM_PROC_MM
-+#include <linux/types.h>
-+
-+#include <asm/compat.h>
-+
-+struct mm_mmap32 {
-+	compat_ulong_t addr;
-+	compat_ulong_t len;
-+	compat_ulong_t prot;
-+	compat_ulong_t flags;
-+	compat_ulong_t fd;
-+	compat_ulong_t offset;
-+};
-+
-+struct mm_munmap32 {
-+	compat_ulong_t addr;
-+	compat_ulong_t len;
-+};
-+
-+struct mm_mprotect32 {
-+	compat_ulong_t addr;
-+	compat_ulong_t len;
-+        compat_uint_t prot;
-+};
-+
-+struct proc_mm_op32 {
-+	compat_int_t op;
-+	union {
-+		struct mm_mmap32 mmap;
-+		struct mm_munmap32 munmap;
-+	        struct mm_mprotect32 mprotect;
-+		compat_int_t copy_segments;
-+	} u;
-+};
-+
-+extern ssize_t write_proc_mm_emul(struct file *file, const char *buffer,
-+			     size_t count, loff_t *ppos);
-+
-+extern long do64_mmap(struct mm_struct *mm, unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags,
-+	unsigned long fd, unsigned long off);
-+
-+static inline long __do_mmap(struct mm_struct *mm, unsigned long addr,
-+		     unsigned long len, unsigned long prot,
-+		     unsigned long flags, unsigned long fd,
-+		     unsigned long off)
-+{
-+	/* The latter one is stricter, since will actually check that off is page
-+	 * aligned. The first one skipped the check. */
-+
-+	/* return do32_mmap2(mm, addr, len, prot, flags, fd, off >>
-+	 * PAGE_SHIFT);*/
-+	return do64_mmap(mm, addr, len, prot, flags, fd, off);
-+}
-+
-+#endif /* __ASM_PROC_MM */
---- linux-2.6.git-paolo/arch/x86_64/Kconfig	2005-06-02 05:03:04.000000000 +0200
-+++ linux-2.6.git-paolo/arch/x86_64/Kconfig	2005-06-02 05:02:46.000000000 +0200
-@@ -347,6 +347,26 @@
- 	  of memory and any 32-bit devices. Don't turn on unless you know what you
- 	  are doing.
- 
-+config PROC_MM
-+	bool "/proc/mm support"
-+	default y
-+
-+config PROC_MM_DUMPABLE
-+	bool "Make UML childs /proc/<pid> completely browsable"
-+	default n
-+	help
-+	  If in doubt, say N.
-+
-+	  This fiddles with some settings to make sure /proc/<pid> is completely
-+	  browsable by who started UML, at the expense of some additional
-+	  locking (maybe this could slow down the runned UMLs of a few percents,
-+	  I've not tested this).
-+
-+	  Also, if there is a bug in this feature, there is some little
-+	  possibility to do privilege escalation if you have UML installed
-+	  setuid (which you shouldn't have done) or if UML changes uid on
-+	  startup (which will be a good thing, when enabled) ...
-+
- config X86_MCE
- 	bool "Machine check support" if EMBEDDED
- 	default y
---- linux-2.6.git-paolo/arch/x86_64/ia32/ptrace32.c	2005-05-25 00:57:34.000000000 +0200
-+++ linux-2.6.git-paolo/arch/x86_64/ia32/ptrace32.c	2005-05-21 18:00:55.000000000 +0200
-@@ -18,6 +18,8 @@
- #include <linux/unistd.h>
- #include <linux/mm.h>
- #include <linux/ptrace.h>
-+#include <linux/types.h>
-+#include <linux/proc_mm.h>
- #include <asm/ptrace.h>
- #include <asm/compat.h>
- #include <asm/uaccess.h>
-@@ -27,6 +29,7 @@
- #include <asm/debugreg.h>
- #include <asm/i387.h>
- #include <asm/fpu32.h>
-+#include <asm/desc.h>
- 
- /* determines which flags the user has access to. */
- /* 1 = access 0 = no access */
-@@ -251,6 +254,11 @@
- 	case PTRACE_SETFPXREGS:
- 	case PTRACE_GETFPXREGS:
- 	case PTRACE_GETEVENTMSG:
-+#ifdef CONFIG_PROC_MM
-+	case PTRACE_FAULTINFO:
-+	case PTRACE_LDT:
-+	case PTRACE_SWITCH_MM:
-+#endif
- 		break;
- 	} 
- 
-@@ -363,6 +371,65 @@
- 		ret = 0; 
- 		break;
- 	}
-+#ifdef CONFIG_PROC_MM
-+	case PTRACE_EX_FAULTINFO: {
-+		struct ptrace_ex_faultinfo32 fault;
-+
-+		fault = ((struct ptrace_ex_faultinfo32)
-+			{ .is_write	= (compat_int_t) child->thread.error_code,
-+			  .addr		= (compat_uptr_t) child->thread.cr2,
-+			  .trap_no	= (compat_int_t) child->thread.trap_no });
-+		ret = copy_to_user((unsigned long *) datap, &fault,
-+				   sizeof(fault));
-+		break;
-+	}
-+
-+	case PTRACE_FAULTINFO: {
-+		struct ptrace_faultinfo32 fault;
-+
-+		fault = ((struct ptrace_faultinfo32)
-+			{ .is_write	= (compat_int_t) child->thread.error_code,
-+			  .addr		= (compat_uptr_t) child->thread.cr2 });
-+		ret = copy_to_user((unsigned long *) datap, &fault,
-+				   sizeof(fault));
-+		break;
-+	}
-+
-+	case PTRACE_LDT: {
-+		struct ptrace_ldt32 ldt;
-+
-+		if(copy_from_user(&ldt, (unsigned long *) datap,
-+				  sizeof(ldt))){
-+			ret = -EIO;
-+			break;
-+		}
-+		ret = __modify_ldt(child->mm, ldt.func, compat_ptr(ldt.ptr), ldt.bytecount);
-+		break;
-+	}
-+
-+	case PTRACE_SWITCH_MM: {
-+		struct mm_struct *old = child->mm;
-+		struct mm_struct *new = proc_mm_get_mm(data);
-+
-+		if(IS_ERR(new)){
-+			ret = PTR_ERR(new);
-+			break;
-+		}
-+
-+		atomic_inc(&new->mm_users);
-+
-+		lock_fix_dumpable_setting(child, new);
-+
-+		child->mm = new;
-+		child->active_mm = new;
-+
-+		task_unlock(child);
-+
-+		mmput(old);
-+		ret = 0;
-+		break;
-+	}
-+#endif
- 
- 	case PTRACE_GETEVENTMSG:
- 		ret = put_user(child->ptrace_message,(unsigned int __user *)compat_ptr(data));
---- linux-2.6.git/include/asm-x86_64/mmu_context.h~x86-64-specific-addition	2005-06-02 05:03:04.000000000 +0200
-+++ linux-2.6.git-paolo/include/asm-x86_64/mmu_context.h	2005-06-02 05:03:04.000000000 +0200
-@@ -8,13 +8,28 @@
- #include <asm/pda.h>
- #include <asm/pgtable.h>
- #include <asm/tlbflush.h>
-+#include <asm/semaphore.h>
- 
- /*
-  * possibly do the LDT unload here?
-+ * Used for LDT initialization/destruction. You cannot copy an LDT with
-+ * init_new_context, since it thinks you are passing it a new LDT and won't
-+ * deallocate its old content.
-  */
-+
- int init_new_context(struct task_struct *tsk, struct mm_struct *mm);
- void destroy_context(struct mm_struct *mm);
- 
-+/* LDT initialization for a clean environment - needed for SKAS.*/
-+static inline void init_new_empty_context(struct mm_struct *mm)
-+{
-+	init_MUTEX(&mm->context.sem);
-+	mm->context.size = 0;
-+}
-+
-+/* LDT copy for SKAS - for the above problem.*/
-+int copy_context(struct mm_struct *mm, struct mm_struct *old_mm);
-+
- #ifdef CONFIG_SMP
- 
- static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
-@@ -37,6 +52,9 @@ static inline void switch_mm(struct mm_s
- 			     struct task_struct *tsk)
- {
- 	unsigned cpu = smp_processor_id();
-+#ifdef CONFIG_SMP
-+	prev = read_pda(active_mm);
-+#endif
- 	if (likely(prev != next)) {
- 		/* stop flush ipis for the previous mm */
- 		clear_bit(cpu, &prev->cpu_vm_mask);
-@@ -53,8 +71,6 @@ static inline void switch_mm(struct mm_s
- #ifdef CONFIG_SMP
- 	else {
- 		write_pda(mmu_state, TLBSTATE_OK);
--		if (read_pda(active_mm) != next)
--			out_of_line_bug();
- 		if(!test_and_set_bit(cpu, &next->cpu_vm_mask)) {
- 			/* We were in lazy tlb mode and leave_mm disabled 
- 			 * tlb flush IPI delivery. We must reload CR3
---- linux-2.6.git/arch/x86_64/ia32/sys_ia32.c~x86-64-specific-addition	2005-06-02 05:03:04.000000000 +0200
-+++ linux-2.6.git-paolo/arch/x86_64/ia32/sys_ia32.c	2005-06-02 05:03:04.000000000 +0200
-@@ -832,11 +832,10 @@ sys32_adjtimex(struct timex32 __user *ut
- 	return ret;
- }
- 
--asmlinkage long sys32_mmap2(unsigned long addr, unsigned long len,
--	unsigned long prot, unsigned long flags,
-+long do32_mmap2(struct mm_struct *mm, unsigned long addr,
-+	unsigned long len, unsigned long prot, unsigned long flags,
- 	unsigned long fd, unsigned long pgoff)
- {
--	struct mm_struct *mm = current->mm;
- 	unsigned long error;
- 	struct file * file = NULL;
- 
-@@ -848,7 +847,7 @@ asmlinkage long sys32_mmap2(unsigned lon
- 	}
- 
- 	down_write(&mm->mmap_sem);
--	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-+	error = __do_mmap_pgoff(mm, file, addr, len, prot, flags, pgoff);
- 	up_write(&mm->mmap_sem);
- 
- 	if (file)
-@@ -856,6 +855,15 @@ asmlinkage long sys32_mmap2(unsigned lon
- 	return error;
- }
- 
-+/* XXX: this wrapper can be probably removed, we can simply use the 64-bit
-+ * version.*/
-+asmlinkage long sys32_mmap2(unsigned long addr, unsigned long len,
-+	unsigned long prot, unsigned long flags,
-+	unsigned long fd, unsigned long pgoff)
-+{
-+	return do32_mmap2(current->mm, addr, len, prot, flags, fd, pgoff);
-+}
-+
- asmlinkage long sys32_olduname(struct oldold_utsname __user * name)
- {
- 	int error;
---- linux-2.6.git-paolo/arch/x86_64/kernel/ldt.c	2005-06-02 05:03:04.000000000 +0200
-+++ linux-2.6.11-paolo/arch/x86_64/kernel/ldt.c	2005-03-05 19:49:55.120753864 +0100
-@@ -22,6 +22,7 @@
- #include <asm/ldt.h>
- #include <asm/desc.h>
- #include <asm/proto.h>
-+#include <asm/mmu_context.h>
- 
- #ifdef CONFIG_SMP /* avoids "defined but not used" warnig */
- static void flush_ldt(void *null)
-@@ -31,11 +32,12 @@
- }
- #endif
- 
--static int alloc_ldt(mm_context_t *pc, unsigned mincount, int reload)
-+static int alloc_ldt(struct mm_struct *mm, unsigned mincount, int reload)
- {
- 	void *oldldt;
- 	void *newldt;
- 	unsigned oldsize;
-+	mm_context_t * pc = &mm->context;
- 
- 	if (mincount <= (unsigned)pc->size)
- 		return 0;
-@@ -64,12 +66,14 @@
- 
- 		preempt_disable();
- 		mask = cpumask_of_cpu(smp_processor_id());
--		load_LDT(pc);
--		if (!cpus_equal(current->mm->cpu_vm_mask, mask))
-+		if (&current->active_mm->context == pc)
-+			load_LDT(pc);
-+		if (!cpus_equal(mm->cpu_vm_mask, mask))
- 			smp_call_function(flush_ldt, NULL, 1, 1);
- 		preempt_enable();
- #else
--		load_LDT(pc);
-+		if (&current->active_mm->context == pc)
-+			load_LDT(pc);
- #endif
- 	}
- 	if (oldsize) {
-@@ -81,12 +85,12 @@
- 	return 0;
- }
- 
--static inline int copy_ldt(mm_context_t *new, mm_context_t *old)
-+static inline int copy_ldt(struct mm_struct *new, struct mm_struct *old)
- {
--	int err = alloc_ldt(new, old->size, 0);
-+	int err = alloc_ldt(new, old->context.size, 0);
- 	if (err < 0)
- 		return err;
--	memcpy(new->ldt, old->ldt, old->size*LDT_ENTRY_SIZE);
-+	memcpy(new->context.ldt, old->context.ldt, old->context.size*LDT_ENTRY_SIZE);
- 	return 0;
- }
- 
-@@ -94,22 +98,24 @@
-  * we do not have to muck with descriptors here, that is
-  * done in switch_mm() as needed.
-  */
--int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
-+int copy_context(struct mm_struct *mm, struct mm_struct *old_mm)
- {
--	struct mm_struct * old_mm;
- 	int retval = 0;
- 
--	init_MUTEX(&mm->context.sem);
--	mm->context.size = 0;
--	old_mm = current->mm;
- 	if (old_mm && old_mm->context.size > 0) {
- 		down(&old_mm->context.sem);
--		retval = copy_ldt(&mm->context, &old_mm->context);
-+		retval = copy_ldt(mm, old_mm);
- 		up(&old_mm->context.sem);
- 	}
- 	return retval;
- }
- 
-+int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
-+{
-+	init_new_empty_context(mm);
-+	return copy_context(mm, current->mm);
-+}
-+
- /*
-  * 
-  * Don't touch the LDT register - we're already in the next thread.
-@@ -125,11 +131,10 @@
- 	}
- }
- 
--static int read_ldt(void __user * ptr, unsigned long bytecount)
-+static int read_ldt(struct mm_struct * mm, void __user * ptr, unsigned long bytecount)
- {
- 	int err;
- 	unsigned long size;
--	struct mm_struct * mm = current->mm;
- 
- 	if (!mm->context.size)
- 		return 0;
-@@ -170,10 +175,8 @@
- 	return bytecount; 
- }
- 
--static int write_ldt(void __user * ptr, unsigned long bytecount, int oldmode)
-+static int write_ldt(struct mm_struct * mm, void __user * ptr, unsigned long bytecount, int oldmode)
- {
--	struct task_struct *me = current;
--	struct mm_struct * mm = me->mm;
- 	__u32 entry_1, entry_2, *lp;
- 	int error;
- 	struct user_desc ldt_info;
-@@ -198,7 +201,7 @@
- 
- 	down(&mm->context.sem);
- 	if (ldt_info.entry_number >= (unsigned)mm->context.size) {
--		error = alloc_ldt(&current->mm->context, ldt_info.entry_number+1, 1);
-+		error = alloc_ldt(mm, ldt_info.entry_number+1, 1);
- 		if (error < 0)
- 			goto out_unlock;
- 	}
-@@ -234,20 +237,26 @@
--asmlinkage int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
-+int __modify_ldt(struct mm_struct * mm, int func, void __user *ptr,
-+		unsigned long bytecount)
- {
- 	int ret = -ENOSYS;
- 
- 	switch (func) {
- 	case 0:
--		ret = read_ldt(ptr, bytecount);
-+		ret = read_ldt(mm, ptr, bytecount);
- 		break;
- 	case 1:
--		ret = write_ldt(ptr, bytecount, 1);
-+		ret = write_ldt(mm, ptr, bytecount, 1);
- 		break;
- 	case 2:
- 		ret = read_default_ldt(ptr, bytecount);
- 		break;
- 	case 0x11:
--		ret = write_ldt(ptr, bytecount, 0);
-+		ret = write_ldt(mm, ptr, bytecount, 0);
- 		break;
- 	}
- 	return ret;
- }
-+
-+asmlinkage int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
-+{
-+	return __modify_ldt(current->mm, func, ptr, bytecount);
-+}
---- linux-2.6.git/include/asm-x86_64/desc.h~x86-64-specific-addition	2005-06-02 05:03:04.000000000 +0200
-+++ linux-2.6.git-paolo/include/asm-x86_64/desc.h	2005-06-02 05:03:04.000000000 +0200
-@@ -212,6 +212,9 @@ static inline void load_LDT(mm_context_t
- 
- extern struct desc_ptr idt_descr;
- 
-+extern int __modify_ldt(struct mm_struct * mm, int func, void __user *ptr,
-+		unsigned long bytecount);
-+
- #endif /* !__ASSEMBLY__ */
- 
- #endif
---- linux-2.6.git-paolo/include/asm-x86_64/ptrace.h	2005-05-25 00:57:34.000000000 +0200
-+++ linux-2.6.git-paolo/include/asm-x86_64/ptrace.h	2005-05-21 18:00:55.000000000 +0200
-@@ -64,6 +64,59 @@
- /* top of stack page */ 
- };
- 
-+/* Stolen from
-+#include <linux/compat.h>; we can't include it because
-+there is a nasty ciclic include chain.
-+*/
-+
-+#include <asm/types.h>
-+
-+#define		compat_int_t	s32
-+#define		compat_long_t	s32
-+#define		compat_uint_t	u32
-+#define		compat_ulong_t	u32
-+#define		compat_uptr_t	u32
-+
-+struct ptrace_faultinfo32 {
-+	compat_int_t is_write;
-+	compat_ulong_t addr;
-+};
-+
-+struct ptrace_ex_faultinfo32 {
-+	compat_int_t is_write;
-+	compat_ulong_t addr;
-+	compat_int_t trap_no;
-+};
-+
-+struct ptrace_ldt32 {
-+	compat_int_t func;
-+	compat_uptr_t ptr; /*Actually a void pointer on i386, but must be converted.*/
-+	compat_ulong_t bytecount;
-+};
-+
-+struct ptrace_faultinfo {
-+	int is_write;
-+	unsigned long addr;
-+};
-+
-+struct ptrace_ex_faultinfo {
-+	int is_write;
-+	unsigned long addr;
-+	int trap_no;
-+};
-+
-+struct ptrace_ldt {
-+	int func;
-+  	void *ptr;
-+	unsigned long bytecount;
-+};
-+
-+#undef	compat_int_t
-+#undef	compat_long_t
-+#undef	compat_uint_t
-+#undef	compat_ulong_t
-+#undef	compat_uptr_t
-+
- #endif
- 
- /* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
-@@ -74,6 +127,12 @@
- #define PTRACE_GETFPXREGS         18
- #define PTRACE_SETFPXREGS         19
- 
-+#define PTRACE_FAULTINFO 52
-+/* 53 was used for PTRACE_SIGPENDING, don't reuse it. */
-+#define PTRACE_LDT 54
-+#define PTRACE_SWITCH_MM 55
-+#define PTRACE_EX_FAULTINFO	  56
-+
- /* only useful for access 32bit programs */
- #define PTRACE_GET_THREAD_AREA    25
- #define PTRACE_SET_THREAD_AREA    26
---- linux-2.6.git/arch/x86_64/mm/Makefile~x86-64-specific-addition	2005-06-02 05:03:04.000000000 +0200
-+++ linux-2.6.git-paolo/arch/x86_64/mm/Makefile	2005-06-02 05:03:04.000000000 +0200
-@@ -7,5 +7,6 @@ obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpag
- obj-$(CONFIG_DISCONTIGMEM) += numa.o
- obj-$(CONFIG_K8_NUMA) += k8topology.o
- obj-$(CONFIG_ACPI_NUMA) += srat.o
-+obj-$(CONFIG_PROC_MM) += proc_mm.o
- 
- hugetlbpage-y = ../../i386/mm/hugetlbpage.o
---- linux-2.6.git-paolo/arch/x86_64/kernel/ptrace.c	2005-05-25 00:57:34.000000000 +0200
-+++ linux-2.6.git-paolo/arch/x86_64/kernel/ptrace.c	2005-05-21 18:00:55.000000000 +0200
-@@ -19,6 +19,7 @@
- #include <linux/audit.h>
- #include <linux/seccomp.h>
- #include <linux/signal.h>
-+#include <linux/proc_mm.h>
- 
- #include <asm/uaccess.h>
- #include <asm/pgtable.h>
-@@ -601,6 +602,79 @@
- 		break;
- 	}
- 
-+#ifdef CONFIG_PROC_MM
-+	case PTRACE_EX_FAULTINFO: {
-+		struct ptrace_ex_faultinfo fault;
-+
-+		/* I checked in thread_struct comments that error_code and cr2
-+		 * are still part of the "fault info" section, so I guess that
-+		 * things are unchanged for now. Still to check manuals. BB*/
-+		fault = ((struct ptrace_ex_faultinfo)
-+			{ .is_write	= child->thread.error_code,
-+			  .addr		= child->thread.cr2,
-+			  .trap_no	= child->thread.trap_no });
-+		ret = copy_to_user((unsigned long *) data, &fault,
-+				   sizeof(fault));
-+		if(ret)
-+			break;
-+		break;
-+	}
-+
-+	/*Don't extend this broken interface to x86-64*/
-+#if 0
-+	case PTRACE_FAULTINFO: {
-+		struct ptrace_faultinfo fault;
-+
-+		/* I checked in thread_struct comments that error_code and cr2
-+		 * are still part of the "fault info" section, so I guess that
-+		 * things are unchanged for now. Still to check manuals. BB*/
-+		fault = ((struct ptrace_faultinfo)
-+			{ .is_write	= child->thread.error_code,
-+			  .addr		= child->thread.cr2 });
-+		ret = copy_to_user((unsigned long *) data, &fault,
-+				   sizeof(fault));
-+		if(ret)
-+			break;
-+		break;
-+	}
-+#endif
-+
-+	case PTRACE_LDT: {
-+		struct ptrace_ldt ldt;
-+
-+		if(copy_from_user(&ldt, (unsigned long *) data,
-+				  sizeof(ldt))){
-+			ret = -EIO;
-+			break;
-+		}
-+		ret = __modify_ldt(child->mm, ldt.func, ldt.ptr, ldt.bytecount);
-+		break;
-+	}
-+
-+	case PTRACE_SWITCH_MM: {
-+		struct mm_struct *old = child->mm;
-+		struct mm_struct *new = proc_mm_get_mm64(data);
-+
-+		if(IS_ERR(new)){
-+			ret = PTR_ERR(new);
-+			break;
-+		}
-+
-+		atomic_inc(&new->mm_users);
-+
-+		lock_fix_dumpable_setting(child, new);
-+
-+		child->mm = new;
-+		child->active_mm = new;
-+
-+		task_unlock(child);
-+
-+		mmput(old);
-+		ret = 0;
-+		break;
-+	}
-+#endif
-+
- 	default:
- 		ret = ptrace_request(child, request, addr, data);
- 		break;
---- linux-2.6.git/arch/x86_64/kernel/sys_x86_64.c~x86-64-specific-addition	2005-06-02 05:03:04.000000000 +0200
-+++ linux-2.6.git-paolo/arch/x86_64/kernel/sys_x86_64.c	2005-06-02 05:03:04.000000000 +0200
-@@ -19,6 +19,7 @@
- 
- #include <asm/uaccess.h>
- #include <asm/ia32.h>
-+#include <asm/proc_mm.h>
- 
- /*
-  * sys_pipe() is the normal C calling standard for creating
-@@ -37,7 +38,7 @@ asmlinkage long sys_pipe(int __user *fil
- 	return error;
- }
- 
--asmlinkage long sys_mmap(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags,
-+long do64_mmap(struct mm_struct *mm, unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags,
- 	unsigned long fd, unsigned long off)
- {
- 	long error;
-@@ -55,9 +56,9 @@ asmlinkage long sys_mmap(unsigned long a
- 		if (!file)
- 			goto out;
- 	}
--	down_write(&current->mm->mmap_sem);
--	error = do_mmap_pgoff(file, addr, len, prot, flags, off >> PAGE_SHIFT);
--	up_write(&current->mm->mmap_sem);
-+	down_write(&mm->mmap_sem);
-+	error = __do_mmap_pgoff(mm, file, addr, len, prot, flags, off >> PAGE_SHIFT);
-+	up_write(&mm->mmap_sem);
- 
- 	if (file)
- 		fput(file);
-@@ -65,6 +66,12 @@ out:
- 	return error;
- }
- 
-+asmlinkage long sys_mmap(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags,
-+	unsigned long fd, unsigned long off)
-+{
-+	return do64_mmap(current->mm, addr, len, prot, flags, fd, off);
-+}
-+
- static void find_start_end(unsigned long flags, unsigned long *begin,
- 			   unsigned long *end)
- {
---- /dev/null	2005-05-28 23:34:14.051125088 +0200
-+++ linux-2.6.git-paolo/include/asm-i386/proc_mm.h	2005-06-02 05:03:04.000000000 +0200
-@@ -0,0 +1,18 @@
-+#ifndef __ASM_PROC_MM
-+#define __ASM_PROC_MM
-+
-+#include <asm/page.h>
-+
-+extern long do_mmap2(struct mm_struct *mm, unsigned long addr,
-+		unsigned long len, unsigned long prot, unsigned long flags,
-+		unsigned long fd, unsigned long pgoff);
-+
-+static inline long __do_mmap(struct mm_struct *mm, unsigned long addr,
-+		     unsigned long len, unsigned long prot,
-+		     unsigned long flags, unsigned long fd,
-+		     unsigned long off)
-+{
-+	return do_mmap2(mm, addr, len, prot, flags, fd, off >> PAGE_SHIFT);
-+}
-+
-+#endif /* __ASM_PROC_MM */
---- /dev/null	2005-05-20 16:07:16.788013064 +0200
-+++ linux-2.6.git-paolo/mm/proc_mm-mod.c	2005-05-21 18:00:57.000000000 +0200
-@@ -0,0 +1,51 @@
-+#include <linux/config.h>
-+#include <linux/kernel.h>
-+#include <linux/proc_mm.h>
-+#include <linux/ptrace.h>
-+#include <linux/module.h>
-+
-+#ifdef CONFIG_64BIT
-+#define PRINT_OFFSET(type, member) \
-+	printk(KERN_DEBUG "struct " #type "32->" #member " \t: %ld\n", (long) offsetof(struct type ## 32, member))
-+#else
-+#define PRINT_OFFSET(type, member) \
-+	printk(KERN_DEBUG "struct " #type "->" #member " \t: %ld\n", (long) offsetof(struct type, member))
-+#endif
-+
-+static int debug_printoffsets(void)
-+{
-+	printk(KERN_DEBUG "Skas core structures layout BEGIN:\n");
-+	PRINT_OFFSET(mm_mmap, addr);
-+	PRINT_OFFSET(mm_mmap, len);
-+	PRINT_OFFSET(mm_mmap, prot);
-+	PRINT_OFFSET(mm_mmap, flags);
-+	PRINT_OFFSET(mm_mmap, fd);
-+	PRINT_OFFSET(mm_mmap, offset);
-+
-+	PRINT_OFFSET(mm_munmap, addr);
-+	PRINT_OFFSET(mm_munmap, len);
-+
-+	PRINT_OFFSET(mm_mprotect, addr);
-+	PRINT_OFFSET(mm_mprotect, len);
-+	PRINT_OFFSET(mm_mprotect, prot);
-+
-+	PRINT_OFFSET(proc_mm_op, op);
-+	PRINT_OFFSET(proc_mm_op, u);
-+	PRINT_OFFSET(proc_mm_op, u.mmap);
-+	PRINT_OFFSET(proc_mm_op, u.munmap);
-+	PRINT_OFFSET(proc_mm_op, u.mprotect);
-+	PRINT_OFFSET(proc_mm_op, u.copy_segments);
-+
-+	PRINT_OFFSET(ptrace_faultinfo, is_write);
-+	PRINT_OFFSET(ptrace_faultinfo, addr);
-+
-+	PRINT_OFFSET(ptrace_ldt, func);
-+	PRINT_OFFSET(ptrace_ldt, ptr);
-+	PRINT_OFFSET(ptrace_ldt, bytecount);
-+	printk(KERN_DEBUG "Skas core structures layout END.\n");
-+
-+	return 0;
-+}
-+#undef PRINT_OFFSET
-+
-+module_init(debug_printoffsets);

Deleted: trunk/src/kernel-patch-skas/skas-2.6.13-rc7-v9-pre7.patch
===================================================================
--- trunk/src/kernel-patch-skas/skas-2.6.13-rc7-v9-pre7.patch	2006-08-27 15:01:30 UTC (rev 166)
+++ trunk/src/kernel-patch-skas/skas-2.6.13-rc7-v9-pre7.patch	2006-08-27 15:16:57 UTC (rev 167)
@@ -1,1994 +0,0 @@
---- linux-2.6.git-paolo/arch/i386/kernel/ptrace.c	2005-07-28 19:40:10.000000000 +0200
-+++ linux-2.6.git-paolo/arch/i386/kernel/ptrace.c	2005-07-28 19:40:18.000000000 +0200
-@@ -17,6 +17,7 @@
- #include <linux/audit.h>
- #include <linux/seccomp.h>
- #include <linux/signal.h>
-+#include <linux/proc_mm.h>
- 
- #include <asm/uaccess.h>
- #include <asm/pgtable.h>
-@@ -271,6 +272,8 @@
- void ptrace_disable(struct task_struct *child)
- { 
- 	clear_singlestep(child);
-+	clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-+	clear_tsk_thread_flag(child, TIF_SYSCALL_EMU);
- }
- 
- /*
-@@ -509,15 +512,20 @@
- 		  }
- 		  break;
- 
-+	case PTRACE_SYSEMU: /* continue and stop at next syscall, which will not be executed */
- 	case PTRACE_SYSCALL:	/* continue and stop at next (return from) syscall */
- 	case PTRACE_CONT:	/* restart after signal. */
- 		ret = -EIO;
- 		if (!valid_signal(data))
- 			break;
--		if (request == PTRACE_SYSCALL) {
-+		if (request == PTRACE_SYSEMU) {
-+			set_tsk_thread_flag(child, TIF_SYSCALL_EMU);
-+			clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-+		} else if (request == PTRACE_SYSCALL) {
- 			set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
--		}
--		else {
-+			clear_tsk_thread_flag(child, TIF_SYSCALL_EMU);
-+		} else {
-+			clear_tsk_thread_flag(child, TIF_SYSCALL_EMU);
- 			clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- 		}
- 		child->exit_code = data;
-@@ -542,10 +550,17 @@
- 		wake_up_process(child);
- 		break;
- 
-+	case PTRACE_SYSEMU_SINGLESTEP: /* Same as SYSEMU, but singlestep if not syscall */
- 	case PTRACE_SINGLESTEP:	/* set the trap flag. */
- 		ret = -EIO;
- 		if (!valid_signal(data))
- 			break;
-+
-+		if (request == PTRACE_SYSEMU_SINGLESTEP)
-+			set_tsk_thread_flag(child, TIF_SYSCALL_EMU);
-+		else
-+			clear_tsk_thread_flag(child, TIF_SYSCALL_EMU);
-+
- 		clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- 		set_singlestep(child);
- 		child->exit_code = data;
-@@ -645,6 +660,70 @@
- 					(struct user_desc __user *) data);
- 		break;
- 
-+#ifdef CONFIG_PROC_MM
-+	case PTRACE_EX_FAULTINFO: {
-+		struct ptrace_ex_faultinfo fault;
-+
-+		fault = ((struct ptrace_ex_faultinfo)
-+			{ .is_write	= child->thread.error_code,
-+			  .addr		= child->thread.cr2,
-+			  .trap_no	= child->thread.trap_no });
-+		ret = copy_to_user((unsigned long *) data, &fault,
-+				   sizeof(fault));
-+		if(ret)
-+			break;
-+		break;
-+	}
-+
-+	case PTRACE_FAULTINFO: {
-+		struct ptrace_faultinfo fault;
-+
-+		fault = ((struct ptrace_faultinfo)
-+			{ .is_write	= child->thread.error_code,
-+			  .addr		= child->thread.cr2 });
-+		ret = copy_to_user((unsigned long *) data, &fault,
-+				   sizeof(fault));
-+		if(ret)
-+			break;
-+		break;
-+	}
-+
-+	case PTRACE_LDT: {
-+		struct ptrace_ldt ldt;
-+
-+		if(copy_from_user(&ldt, (unsigned long *) data,
-+				  sizeof(ldt))){
-+			ret = -EIO;
-+			break;
-+		}
-+		ret = __modify_ldt(child->mm, ldt.func, ldt.ptr, ldt.bytecount);
-+		break;
-+	}
-+
-+	case PTRACE_SWITCH_MM: {
-+		struct mm_struct *old = child->mm;
-+		struct mm_struct *new = proc_mm_get_mm(data);
-+
-+		if(IS_ERR(new)){
-+			ret = PTR_ERR(new);
-+			break;
-+		}
-+
-+		atomic_inc(&new->mm_users);
-+
-+		lock_fix_dumpable_setting(child, new);
-+
-+		child->mm = new;
-+		child->active_mm = new;
-+
-+		task_unlock(child);
-+
-+		mmput(old);
-+		ret = 0;
-+		break;
-+	}
-+#endif
-+
- 	default:
- 		ret = ptrace_request(child, request, addr, data);
- 		break;
-@@ -678,26 +757,52 @@
-  * - triggered by current->work.syscall_trace
-  */
- __attribute__((regparm(3)))
--void do_syscall_trace(struct pt_regs *regs, int entryexit)
-+int do_syscall_trace(struct pt_regs *regs, int entryexit)
- {
-+	int is_sysemu = test_thread_flag(TIF_SYSCALL_EMU), ret = 0;
-+	/* With TIF_SYSCALL_EMU set we want to ignore TIF_SINGLESTEP for syscall
-+	 * interception. */
-+	int is_singlestep = !is_sysemu && test_thread_flag(TIF_SINGLESTEP);
-+
- 	/* do the secure computing check first */
- 	secure_computing(regs->orig_eax);
- 
--	if (unlikely(current->audit_context) && entryexit)
--		audit_syscall_exit(current, AUDITSC_RESULT(regs->eax), regs->eax);
-+	if (unlikely(current->audit_context)) {
-+		if (entryexit)
-+			audit_syscall_exit(current, AUDITSC_RESULT(regs->eax), regs->eax);
-+		/* Debug traps, when using PTRACE_SINGLESTEP, must be sent only
-+		 * on the syscall exit path. Normally, when TIF_SYSCALL_AUDIT is
-+		 * not used, entry.S will call us only on syscall exit, not
-+		 * entry; so when TIF_SYSCALL_AUDIT is used we must avoid
-+		 * calling send_sigtrap() on syscall entry.
-+		 *
-+		 * Note that when PTRACE_SYSEMU_SINGLESTEP is used,
-+		 * is_singlestep is false, despite his name, so we will still do
-+		 * the correct thing.
-+		 */
-+		else if (is_singlestep)
-+			goto out;
-+	}
- 
- 	if (!(current->ptrace & PT_PTRACED))
- 		goto out;
- 
-+	/* If a process stops on the 1st tracepoint with SYSCALL_TRACE
-+	 * and then is resumed with SYSEMU_SINGLESTEP, it will come in
-+	 * here. We have to check this and return */
-+	if (is_sysemu && entryexit)
-+		return 0;
-+
- 	/* Fake a debug trap */
--	if (test_thread_flag(TIF_SINGLESTEP))
-+	if (is_singlestep)
- 		send_sigtrap(current, regs, 0);
- 
--	if (!test_thread_flag(TIF_SYSCALL_TRACE))
-+	if (!test_thread_flag(TIF_SYSCALL_TRACE) && !is_sysemu)
- 		goto out;
- 
- 	/* the 0x80 provides a way for the tracing parent to distinguish
- 	   between a syscall stop and SIGTRAP delivery */
-+	/* Note that the debugger could change the result of test_thread_flag!*/
- 	ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) ? 0x80 : 0));
- 
- 	/*
-@@ -711,7 +816,14 @@
- 	}
-+	ret = is_sysemu;
-  out:
- 	if (unlikely(current->audit_context) && !entryexit)
- 		audit_syscall_entry(current, AUDIT_ARCH_I386, regs->orig_eax,
- 				    regs->ebx, regs->ecx, regs->edx, regs->esi);
-+	if (ret == 0)
-+		return 0;
- 
-+	regs->orig_eax = -1; /* force skip of syscall restarting */
-+	if (unlikely(current->audit_context))
-+		audit_syscall_exit(current, AUDITSC_RESULT(regs->eax), regs->eax);
-+	return 1;
- }
---- linux-2.6.git-paolo/arch/i386/kernel/entry.S	2005-08-26 20:59:11.000000000 +0200
-+++ linux-2.6.git-paolo/arch/i386/kernel/entry.S	2005-07-31 20:03:19.000000000 +0200
-@@ -203,7 +203,7 @@
- 	GET_THREAD_INFO(%ebp)
- 
- 	/* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */
--	testw $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),TI_flags(%ebp)
-+	testw $(_TIF_SYSCALL_EMU|_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT),TI_flags(%ebp)
- 	jnz syscall_trace_entry
- 	cmpl $(nr_syscalls), %eax
- 	jae syscall_badsys
-@@ -226,9 +226,9 @@
- 	pushl %eax			# save orig_eax
- 	SAVE_ALL
- 	GET_THREAD_INFO(%ebp)
--					# system call tracing in operation
-+					# system call tracing in operation / emulation
- 	/* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */
--	testw $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),TI_flags(%ebp)
-+	testw $(_TIF_SYSCALL_EMU|_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT),TI_flags(%ebp)
- 	jnz syscall_trace_entry
- 	cmpl $(nr_syscalls), %eax
- 	jae syscall_badsys
-@@ -338,6 +338,9 @@
- 	movl %esp, %eax
- 	xorl %edx,%edx
- 	call do_syscall_trace
-+	cmpl $0, %eax
-+	jne resume_userspace		# ret != 0 -> running under PTRACE_SYSEMU,
-+					# so must skip actual syscall
- 	movl ORIG_EAX(%esp), %eax
- 	cmpl $(nr_syscalls), %eax
- 	jnae syscall_call
---- linux-2.6.git-paolo/include/asm-i386/thread_info.h	2005-07-26 20:24:57.000000000 +0200
-+++ linux-2.6.git-paolo/include/asm-i386/thread_info.h	2005-05-06 16:26:26.000000000 +0200
-@@ -141,6 +141,7 @@
- #define TIF_IRET		5	/* return with iret */
- #define TIF_SYSCALL_AUDIT	7	/* syscall auditing active */
- #define TIF_SECCOMP		8	/* secure computing */
-+#define TIF_SYSCALL_EMU		9	/* syscall emulation active */
- #define TIF_POLLING_NRFLAG	16	/* true if poll_idle() is polling TIF_NEED_RESCHED */
- #define TIF_MEMDIE		17
- 
-@@ -150,13 +151,15 @@
- #define _TIF_NEED_RESCHED	(1<<TIF_NEED_RESCHED)
- #define _TIF_SINGLESTEP		(1<<TIF_SINGLESTEP)
- #define _TIF_IRET		(1<<TIF_IRET)
-+#define _TIF_SYSCALL_EMU	(1<<TIF_SYSCALL_EMU)
- #define _TIF_SYSCALL_AUDIT	(1<<TIF_SYSCALL_AUDIT)
- #define _TIF_SECCOMP		(1<<TIF_SECCOMP)
- #define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
- 
- /* work to do on interrupt/exception return */
- #define _TIF_WORK_MASK \
--  (0x0000FFFF & ~(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP|_TIF_SECCOMP))
-+  (0x0000FFFF & ~(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP|\
-+		  _TIF_SECCOMP|_TIF_SYSCALL_EMU))
- /* work to do on any return to u-space */
- #define _TIF_ALLWORK_MASK	(0x0000FFFF & ~_TIF_SECCOMP)
- 
---- linux-2.6.git-paolo/include/linux/ptrace.h	2005-07-26 20:39:57.000000000 +0200
-+++ linux-2.6.git-paolo/include/linux/ptrace.h	2005-07-26 20:27:45.000000000 +0200
-@@ -20,6 +20,8 @@
- #define PTRACE_DETACH		0x11
- 
- #define PTRACE_SYSCALL		  24
-+#define PTRACE_SYSEMU		  31
-+#define PTRACE_SYSEMU_SINGLESTEP  32
- 
- /* 0x4200-0x4300 are reserved for architecture-independent additions.  */
- #define PTRACE_SETOPTIONS	0x4200
---- linux-2.6.git/kernel/fork.c~host-sysemu	2005-07-26 20:24:57.000000000 +0200
-+++ linux-2.6.git-paolo/kernel/fork.c	2005-07-26 20:24:57.000000000 +0200
-@@ -994,6 +994,9 @@ static task_t *copy_process(unsigned lon
- 	 * of CLONE_PTRACE.
- 	 */
- 	clear_tsk_thread_flag(p, TIF_SYSCALL_TRACE);
-+#ifdef TIF_SYSCALL_EMU
-+	clear_tsk_thread_flag(p, TIF_SYSCALL_EMU);
-+#endif
- 
- 	/* Our parent execution domain becomes current domain
- 	   These must match for thread signalling to apply */
---- linux-2.6.git/include/linux/mm.h~Add_generic_proc_mm_support	2005-08-21 21:43:06.000000000 +0200
-+++ linux-2.6.git-paolo/include/linux/mm.h	2005-08-21 21:43:06.000000000 +0200
-@@ -759,6 +759,9 @@ struct shrinker;
- extern struct shrinker *set_shrinker(int, shrinker_t);
- extern void remove_shrinker(struct shrinker *shrinker);
- 
-+extern long do_mprotect(struct mm_struct *mm, unsigned long start,
-+			size_t len, unsigned long prot);
-+
- /*
-  * On a two-level or three-level page table, this ends up being trivial. Thus
-  * the inlining and the symmetry break with pte_alloc_map() that does all
-@@ -841,9 +844,15 @@ extern int may_expand_vm(struct mm_struc
- 
- extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
- 
--extern unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
-+extern unsigned long __do_mmap_pgoff(struct mm_struct *mm, struct file *file,
-+				   unsigned long addr, unsigned long len,
-+				   unsigned long prot, unsigned long flag,
-+				   unsigned long pgoff);
-+static inline unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
- 	unsigned long len, unsigned long prot,
--	unsigned long flag, unsigned long pgoff);
-+	unsigned long flag, unsigned long pgoff) {
-+	return __do_mmap_pgoff(current->mm, file, addr, len, prot, flag, pgoff);
-+}
- 
- static inline unsigned long do_mmap(struct file *file, unsigned long addr,
- 	unsigned long len, unsigned long prot,
---- linux-2.6.git-paolo/include/linux/proc_mm.h	2005-07-31 18:56:20.000000000 +0200
-+++ linux-2.6.git-paolo/include/linux/proc_mm.h	2005-08-21 21:44:05.000000000 +0200
-@@ -0,0 +1,114 @@
-+/*
-+ * Copyright (C) 2002 Jeff Dike (jdike at karaya.com)
-+ * Licensed under the GPL
-+ */
-+
-+#ifndef __PROC_MM_H
-+#define __PROC_MM_H
-+
-+#include <linux/config.h>
-+#include <linux/sched.h>
-+#include <linux/compiler.h>
-+
-+/* The differences between this one and do_mmap are that:
-+ * - we must perform controls for userspace-supplied params (which are
-+ *   arch-specific currently). And also fget(fd) if needed and so on...
-+ * - we must accept the struct mm_struct on which to act as first param, and the
-+ *   offset in byte rather than page units as last param.
-+ */
-+static inline long __do_mmap(struct mm_struct *mm, unsigned long addr,
-+		     unsigned long len, unsigned long prot,
-+		     unsigned long flags, unsigned long fd,
-+		     unsigned long off);
-+
-+/* This header can be used only on archs defining CONFIG_PROC_MM in their
-+ * configs, so asm/proc_mm.h can still exist only for the needed archs.
-+ * Including it only in the x86-64 case does not make sense.*/
-+#include <asm/proc_mm.h>
-+
-+/*XXX: this is defined on x86_64, but not on every 64-bit arch (not on sh64).*/
-+#ifdef CONFIG_64BIT
-+
-+#define write_proc_mm write_proc_mm_emul
-+#define write_proc_mm64 write_proc_mm_native
-+
-+/* It would make more sense to do this mapping the reverse direction, to map the
-+ * called name to the defined one and not the reverse. Like the 2nd example
-+ */
-+/*#define proc_mm_get_mm proc_mm_get_mm_emul
-+#define proc_mm_get_mm64 proc_mm_get_mm_native*/
-+
-+#define proc_mm_get_mm_emul proc_mm_get_mm
-+#define proc_mm_get_mm_native proc_mm_get_mm64
-+
-+#else
-+
-+#define write_proc_mm write_proc_mm_native
-+#undef write_proc_mm64
-+
-+/*#define proc_mm_get_mm proc_mm_get_mm_native
-+#undef proc_mm_get_mm64*/
-+
-+#define proc_mm_get_mm_native proc_mm_get_mm
-+#undef proc_mm_get_mm_emul
-+
-+#endif
-+
-+#define MM_MMAP 54
-+#define MM_MUNMAP 55
-+#define MM_MPROTECT 56
-+#define MM_COPY_SEGMENTS 57
-+
-+struct mm_mmap {
-+	unsigned long addr;
-+	unsigned long len;
-+	unsigned long prot;
-+	unsigned long flags;
-+	unsigned long fd;
-+	unsigned long offset;
-+};
-+
-+struct mm_munmap {
-+	unsigned long addr;
-+	unsigned long len;
-+};
-+
-+struct mm_mprotect {
-+	unsigned long addr;
-+	unsigned long len;
-+        unsigned int prot;
-+};
-+
-+struct proc_mm_op {
-+	int op;
-+	union {
-+		struct mm_mmap mmap;
-+		struct mm_munmap munmap;
-+	        struct mm_mprotect mprotect;
-+		int copy_segments;
-+	} u;
-+};
-+
-+extern struct mm_struct *proc_mm_get_mm(int fd);
-+
-+/* Cope with older kernels */
-+#ifndef __acquires
-+#define __acquires(x)
-+#endif
-+
-+#ifdef CONFIG_PROC_MM_DUMPABLE
-+/*
-+ * Since we take task_lock of child and it's needed also by the caller, we
-+ * return with it locked.
-+ */
-+extern void lock_fix_dumpable_setting(struct task_struct * child,
-+		struct mm_struct* new) __acquires(child->alloc_lock);
-+#else
-+static inline void lock_fix_dumpable_setting(struct task_struct * child,
-+		struct mm_struct* new) __acquires(child->alloc_lock)
-+{
-+	task_lock(child);
-+}
-+#endif
-+
-+#endif
---- linux-2.6.git-paolo/mm/Makefile	2005-08-21 21:43:06.000000000 +0200
-+++ linux-2.6.git-paolo/mm/Makefile	2005-07-04 18:50:00.000000000 +0200
-@@ -22,0 +23,6 @@
-+
-+obj-$(CONFIG_PROC_MM)	+= proc_mm.o
-+
-+ifeq ($(CONFIG_PROC_MM),y)
-+obj-m			+= proc_mm-mod.o
-+endif
---- linux-2.6.git/mm/mmap.c~Add_generic_proc_mm_support	2005-08-21 21:43:06.000000000 +0200
-+++ linux-2.6.git-paolo/mm/mmap.c	2005-08-21 21:43:06.000000000 +0200
-@@ -868,11 +868,11 @@ void __vm_stat_account(struct mm_struct 
-  * The caller must hold down_write(current->mm->mmap_sem).
-  */
- 
--unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
--			unsigned long len, unsigned long prot,
--			unsigned long flags, unsigned long pgoff)
-+unsigned long __do_mmap_pgoff(struct mm_struct *mm, struct file * file,
-+			    unsigned long addr, unsigned long len,
-+			    unsigned long prot, unsigned long flags,
-+			    unsigned long pgoff)
- {
--	struct mm_struct * mm = current->mm;
- 	struct vm_area_struct * vma, * prev;
- 	struct inode *inode;
- 	unsigned int vm_flags;
-@@ -1147,7 +1147,7 @@ unacct_error:
- 	return error;
- }
- 
--EXPORT_SYMBOL(do_mmap_pgoff);
-+EXPORT_SYMBOL(__do_mmap_pgoff);
- 
- /* Get an address range which is currently unmapped.
-  * For shmat() with addr=0.
---- linux-2.6.git-paolo/mm/mprotect.c	2005-08-21 21:43:06.000000000 +0200
-+++ linux-2.6.git-broken-paolo/mm/mprotect.c	2005-07-13 19:28:33.000000000 +0200
-@@ -177,8 +177,9 @@
- 	return error;
- }
- 
--asmlinkage long
--sys_mprotect(unsigned long start, size_t len, unsigned long prot)
-+long
-+do_mprotect(struct mm_struct *mm, unsigned long start, size_t len,
-+	     unsigned long prot)
- {
- 	unsigned long vm_flags, nstart, end, tmp, reqprot;
- 	struct vm_area_struct *vma, *prev;
-@@ -209,9 +210,9 @@
- 
- 	vm_flags = calc_vm_prot_bits(prot);
- 
--	down_write(&current->mm->mmap_sem);
-+	down_write(&mm->mmap_sem);
- 
--	vma = find_vma_prev(current->mm, start, &prev);
-+	vma = find_vma_prev(mm, start, &prev);
- 	error = -ENOMEM;
- 	if (!vma)
- 		goto out;
-@@ -280,3 +281,12 @@
--	up_write(&current->mm->mmap_sem);
-+	up_write(&mm->mmap_sem);
- 	return error;
- }
-+
-+asmlinkage long sys_mprotect(unsigned long start, size_t len, unsigned long prot)
-+{
-+	long ret = do_mprotect(current->mm, start, len, prot);
-+	/* A tail call would reorder parameters on the stack and they would then
-+	 * be restored at the wrong places. */
-+	prevent_tail_call(ret);
-+	return ret;
-+}
---- linux-2.6.git-paolo/mm/proc_mm.c	2005-07-31 18:56:20.000000000 +0200
-+++ linux-2.6.git-paolo/mm/proc_mm.c	2005-08-21 21:44:05.000000000 +0200
-@@ -0,0 +1,300 @@
-+/*
-+ * Copyright (C) 2002 Jeff Dike (jdike at karaya.com)
-+ * Licensed under the GPL
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/compiler.h>
-+#include <linux/mm.h>
-+#include <linux/init.h>
-+#include <linux/proc_fs.h>
-+#include <linux/proc_mm.h>
-+#include <linux/file.h>
-+#include <linux/mman.h>
-+#include <asm/uaccess.h>
-+#include <asm/mmu_context.h>
-+
-+#ifdef CONFIG_PROC_MM_DUMPABLE
-+/* Checks if a task must be considered dumpable
-+ *
-+ * XXX: copied from fs/proc/base.c, removed task_lock, added rmb(): this must be
-+ * called with task_lock(task) held. */
-+static int task_dumpable(struct task_struct *task)
-+{
-+	int dumpable = 0;
-+	struct mm_struct *mm;
-+
-+	mm = task->mm;
-+	if (mm) {
-+		rmb();
-+		dumpable = mm->dumpable;
-+	}
-+	return dumpable;
-+}
-+
-+/*
-+ * This is to be used in PTRACE_SWITCH_MM handling. We are going to set
-+ * child->mm to new, and we must first correctly set new->dumpable.
-+ * Since we take task_lock of child and it's needed also by the caller, we
-+ * return with it locked.
-+ */
-+void lock_fix_dumpable_setting(struct task_struct* child, struct mm_struct* new)
-+	__acquires(child->alloc_lock)
-+{
-+	int dumpable = 1;
-+
-+	/* We must be safe.
-+	 * If the child is ptraced from a non-dumpable process,
-+	 * let's not be dumpable. If the child is non-dumpable itself,
-+	 * copy this property across mm's.
-+	 *
-+	 * Don't try to be smart for the opposite case and turn
-+	 * child->mm->dumpable to 1: I've not made sure it is safe.
-+	 */
-+
-+	task_lock(current);
-+	if (unlikely(!task_dumpable(current))) {
-+		dumpable = 0;
-+	}
-+	task_unlock(current);
-+
-+	task_lock(child);
-+	if (likely(dumpable) && unlikely(!task_dumpable(child))) {
-+		dumpable = 0;
-+	}
-+
-+	if (!dumpable) {
-+		new->dumpable = 0;
-+		wmb();
-+	}
-+}
-+#endif
-+
-+/* Naming conventions are a mess, so I note them down.
-+ *
-+ * Things ending in _mm can be for everything. It's only for
-+ * {open,release}_proc_mm.
-+ *
-+ * For the rest:
-+ *
-+ * _mm means /proc/mm, _mm64 means /proc/mm64. This is for the infrastructure
-+ * only (for instance proc_mm_get_mm checks whether the file is /proc/mm or
-+ * /proc/mm64; for instance the /proc handling).
-+ *
-+ * While for what is conversion dependant, we use the suffix _native and _emul.
-+ * In some cases, there is a mapping between these ones (defined by
-+ * <asm/proc_mm.h>).
-+ */
-+
-+/*These two are common to everything.*/
-+static int open_proc_mm(struct inode *inode, struct file *file)
-+{
-+	struct mm_struct *mm = mm_alloc();
-+	int ret;
-+
-+	ret = -ENOMEM;
-+	if(mm == NULL)
-+		goto out_mem;
-+
-+	init_new_empty_context(mm);
-+	arch_pick_mmap_layout(mm);
-+#ifdef CONFIG_PROC_MM_DUMPABLE
-+	mm->dumpable = current->mm->dumpable;
-+	wmb();
-+#endif
-+
-+	file->private_data = mm;
-+
-+	return 0;
-+
-+out_mem:
-+	return ret;
-+}
-+
-+static int release_proc_mm(struct inode *inode, struct file *file)
-+{
-+	struct mm_struct *mm = file->private_data;
-+
-+	mmput(mm);
-+	return 0;
-+}
-+
-+static struct file_operations proc_mm_fops;
-+
-+struct mm_struct *proc_mm_get_mm_native(int fd);
-+
-+static ssize_t write_proc_mm_native(struct file *file, const char *buffer,
-+			     size_t count, loff_t *ppos)
-+{
-+	struct mm_struct *mm = file->private_data;
-+	struct proc_mm_op req;
-+	int n, ret;
-+
-+	if(count > sizeof(req))
-+		return(-EINVAL);
-+
-+	n = copy_from_user(&req, buffer, count);
-+	if(n != 0)
-+		return(-EFAULT);
-+
-+	ret = count;
-+	switch(req.op){
-+	case MM_MMAP: {
-+		struct mm_mmap *map = &req.u.mmap;
-+
-+		/* Nobody ever noticed it, but do_mmap_pgoff() calls
-+		 * get_unmapped_area() which checks current->mm, if
-+		 * MAP_FIXED is not set, so mmap() could replace
-+		 * an old mapping.
-+		 */
-+		if (! (map->flags & MAP_FIXED))
-+			return(-EINVAL);
-+
-+		ret = __do_mmap(mm, map->addr, map->len, map->prot,
-+			       map->flags, map->fd, map->offset);
-+		if((ret & ~PAGE_MASK) == 0)
-+			ret = count;
-+
-+		break;
-+	}
-+	case MM_MUNMAP: {
-+		struct mm_munmap *unmap = &req.u.munmap;
-+
-+		down_write(&mm->mmap_sem);
-+		ret = do_munmap(mm, unmap->addr, unmap->len);
-+		up_write(&mm->mmap_sem);
-+
-+		if(ret == 0)
-+			ret = count;
-+		break;
-+	}
-+	case MM_MPROTECT: {
-+		struct mm_mprotect *protect = &req.u.mprotect;
-+
-+		ret = do_mprotect(mm, protect->addr, protect->len,
-+				  protect->prot);
-+		if(ret == 0)
-+			ret = count;
-+		break;
-+	}
-+
-+	case MM_COPY_SEGMENTS: {
-+		struct mm_struct *from = proc_mm_get_mm_native(req.u.copy_segments);
-+
-+		if(IS_ERR(from)){
-+			ret = PTR_ERR(from);
-+			break;
-+		}
-+
-+		ret = copy_context(mm, from);
-+		if(ret == 0)
-+			ret = count;
-+		break;
-+	}
-+	default:
-+		ret = -EINVAL;
-+		break;
-+	}
-+
-+	return ret;
-+}
-+
-+/*These three are all for /proc/mm.*/
-+struct mm_struct *proc_mm_get_mm(int fd)
-+{
-+	struct mm_struct *ret = ERR_PTR(-EBADF);
-+	struct file *file;
-+
-+	file = fget(fd);
-+	if (!file)
-+		goto out;
-+
-+	ret = ERR_PTR(-EINVAL);
-+	if(file->f_op != &proc_mm_fops)
-+		goto out_fput;
-+
-+	ret = file->private_data;
-+out_fput:
-+	fput(file);
-+out:
-+	return(ret);
-+}
-+
-+static struct file_operations proc_mm_fops = {
-+	.open		= open_proc_mm,
-+	.release	= release_proc_mm,
-+	.write		= write_proc_mm,
-+};
-+
-+/*Macro-ify it to avoid the duplication.*/
-+static int make_proc_mm(void)
-+{
-+	struct proc_dir_entry *ent;
-+
-+	ent = create_proc_entry("mm", 0222, &proc_root);
-+	if(ent == NULL){
-+		printk("make_proc_mm : Failed to register /proc/mm\n");
-+		return(0);
-+	}
-+	ent->proc_fops = &proc_mm_fops;
-+
-+	return 0;
-+}
-+
-+__initcall(make_proc_mm);
-+
-+/*XXX: change the option.*/
-+#ifdef CONFIG_64BIT
-+static struct file_operations proc_mm64_fops = {
-+	.open		= open_proc_mm,
-+	.release	= release_proc_mm,
-+	.write		= write_proc_mm64,
-+};
-+
-+static int make_proc_mm64(void)
-+{
-+	struct proc_dir_entry *ent;
-+
-+	ent = create_proc_entry("mm64", 0222, &proc_root);
-+	if(ent == NULL){
-+		printk("make_proc_mm : Failed to register /proc/mm64\n");
-+		return(0);
-+	}
-+	ent->proc_fops = &proc_mm64_fops;
-+
-+	return 0;
-+}
-+
-+__initcall(make_proc_mm64);
-+
-+struct mm_struct *proc_mm_get_mm64(int fd)
-+{
-+	struct mm_struct *ret = ERR_PTR(-EBADF);
-+	struct file *file;
-+
-+	file = fget(fd);
-+	if (!file)
-+		goto out;
-+
-+	ret = ERR_PTR(-EINVAL);
-+	/*This is the only change.*/
-+	if(file->f_op != &proc_mm64_fops)
-+		goto out_fput;
-+
-+	ret = file->private_data;
-+out_fput:
-+	fput(file);
-+out:
-+	return(ret);
-+}
-+#endif
-+/*
-+ * Overrides for Emacs so that we follow Linus's tabbing style.
-+ * Emacs will notice this stuff at the end of the file and automatically
-+ * adjust the settings for this buffer only.  This must remain at the end
-+ * of the file.
-+ * ---------------------------------------------------------------------------
-+ * Local variables:
-+ * c-file-style: "linux"
-+ * End:
-+ */
---- linux-2.6.git/arch/um/include/skas_ptrace.h~Add_generic_proc_mm_support	2005-08-21 21:43:06.000000000 +0200
-+++ linux-2.6.git-paolo/arch/um/include/skas_ptrace.h	2005-08-21 21:43:06.000000000 +0200
-@@ -6,6 +6,8 @@
- #ifndef __SKAS_PTRACE_H
- #define __SKAS_PTRACE_H
- 
-+#ifndef PTRACE_FAULTINFO
-+
- #define PTRACE_FAULTINFO 52
- #define PTRACE_SWITCH_MM 55
- 
-@@ -13,6 +15,8 @@
- 
- #endif
- 
-+#endif
-+
- /*
-  * Overrides for Emacs so that we follow Linus's tabbing style.
-  * Emacs will notice this stuff at the end of the file and automatically
---- linux-2.6.git-paolo/arch/i386/Kconfig	2005-08-21 21:43:37.000000000 +0200
-+++ linux-2.6.git-paolo/arch/i386/Kconfig	2005-08-21 21:44:05.000000000 +0200
-@@ -748,6 +748,26 @@
- 	depends on HIGHMEM64G
- 	default y
- 
-+config PROC_MM
-+	bool "/proc/mm support"
-+	default y
-+
-+config PROC_MM_DUMPABLE
-+	bool "Make UML childs /proc/<pid> completely browsable"
-+	default n
-+	help
-+	  If in doubt, say N.
-+
-+	  This fiddles with some settings to make sure /proc/<pid> is completely
-+	  browsable by who started UML, at the expense of some additional
-+	  locking (maybe this could slow down the runned UMLs of a few percents,
-+	  I've not tested this).
-+
-+	  Also, if there is a bug in this feature, there is some little
-+	  possibility to do privilege escalation if you have UML installed
-+	  setuid (which you shouldn't have done) or if UML changes uid on
-+	  startup (which will be a good thing, when enabled) ...
-+
- # Common NUMA Features
- config NUMA
- 	bool "Numa Memory Allocation and Scheduler Support"
---- linux-2.6.git-paolo/arch/i386/kernel/ldt.c	2005-07-04 18:48:33.000000000 +0200
-+++ linux-2.6.git-broken-paolo/arch/i386/kernel/ldt.c	2005-07-13 19:28:33.000000000 +0200
-@@ -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)
-@@ -27,11 +28,12 @@
- }
- #endif
- 
--static int alloc_ldt(mm_context_t *pc, int mincount, int reload)
-+static int alloc_ldt(struct mm_struct *mm, int mincount, int reload)
- {
- 	void *oldldt;
- 	void *newldt;
- 	int oldsize;
-+	mm_context_t * pc = &mm->context;
- 
- 	if (mincount <= pc->size)
- 		return 0;
-@@ -58,13 +60,15 @@
- #ifdef CONFIG_SMP
- 		cpumask_t mask;
- 		preempt_disable();
--		load_LDT(pc);
-+		if (&current->active_mm->context == pc)
-+			load_LDT(pc);
- 		mask = cpumask_of_cpu(smp_processor_id());
--		if (!cpus_equal(current->mm->cpu_vm_mask, mask))
-+		if (!cpus_equal(mm->cpu_vm_mask, mask))
- 			smp_call_function(flush_ldt, NULL, 1, 1);
- 		preempt_enable();
- #else
--		load_LDT(pc);
-+		if (&current->active_mm->context == pc)
-+			load_LDT(pc);
- #endif
- 	}
- 	if (oldsize) {
-@@ -76,12 +80,12 @@
- 	return 0;
- }
- 
--static inline int copy_ldt(mm_context_t *new, mm_context_t *old)
-+static inline int copy_ldt(struct mm_struct *new, struct mm_struct *old)
- {
--	int err = alloc_ldt(new, old->size, 0);
-+	int err = alloc_ldt(new, old->context.size, 0);
- 	if (err < 0)
- 		return err;
--	memcpy(new->ldt, old->ldt, old->size*LDT_ENTRY_SIZE);
-+	memcpy(new->context.ldt, old->context.ldt, old->context.size*LDT_ENTRY_SIZE);
- 	return 0;
- }
- 
-@@ -89,22 +93,24 @@
-  * we do not have to muck with descriptors here, that is
-  * done in switch_mm() as needed.
-  */
--int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
-+int copy_context(struct mm_struct *mm, struct mm_struct *old_mm)
- {
--	struct mm_struct * old_mm;
- 	int retval = 0;
- 
--	init_MUTEX(&mm->context.sem);
--	mm->context.size = 0;
--	old_mm = current->mm;
- 	if (old_mm && old_mm->context.size > 0) {
- 		down(&old_mm->context.sem);
--		retval = copy_ldt(&mm->context, &old_mm->context);
-+		retval = copy_ldt(mm, old_mm);
- 		up(&old_mm->context.sem);
- 	}
- 	return retval;
- }
- 
-+int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
-+{
-+	init_new_empty_context(mm);
-+	return copy_context(mm, current->mm);
-+}
-+
- /*
-  * No need to lock the MM as we are the last user
-  */
-@@ -121,11 +127,11 @@
- 	}
- }
- 
--static int read_ldt(void __user * ptr, unsigned long bytecount)
-+static int read_ldt(struct mm_struct * mm, void __user * ptr,
-+		    unsigned long bytecount)
- {
- 	int err;
- 	unsigned long size;
--	struct mm_struct * mm = current->mm;
- 
- 	if (!mm->context.size)
- 		return 0;
-@@ -174,9 +180,8 @@
- 	return err;
- }
- 
--static int write_ldt(void __user * ptr, unsigned long bytecount, int oldmode)
-+static int write_ldt(struct mm_struct * mm, void __user * ptr, unsigned long bytecount, int oldmode)
- {
--	struct mm_struct * mm = current->mm;
- 	__u32 entry_1, entry_2, *lp;
- 	int error;
- 	struct user_desc ldt_info;
-@@ -200,7 +205,7 @@
- 
- 	down(&mm->context.sem);
- 	if (ldt_info.entry_number >= mm->context.size) {
--		error = alloc_ldt(&current->mm->context, ldt_info.entry_number+1, 1);
-+		error = alloc_ldt(mm, ldt_info.entry_number+1, 1);
- 		if (error < 0)
- 			goto out_unlock;
- 	}
-@@ -236,20 +241,30 @@
--asmlinkage int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
-+int __modify_ldt(struct mm_struct * mm, int func, void __user *ptr,
-+	       unsigned long bytecount)
- {
- 	int ret = -ENOSYS;
- 
- 	switch (func) {
- 	case 0:
--		ret = read_ldt(ptr, bytecount);
-+		ret = read_ldt(mm, ptr, bytecount);
- 		break;
- 	case 1:
--		ret = write_ldt(ptr, bytecount, 1);
-+		ret = write_ldt(mm, ptr, bytecount, 1);
- 		break;
- 	case 2:
- 		ret = read_default_ldt(ptr, bytecount);
- 		break;
- 	case 0x11:
--		ret = write_ldt(ptr, bytecount, 0);
-+		ret = write_ldt(mm, ptr, bytecount, 0);
- 		break;
- 	}
- 	return ret;
- }
-+
-+asmlinkage int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
-+{
-+	int ret = __modify_ldt(current->mm, func, ptr, bytecount);
-+	/* A tail call would reorder parameters on the stack and they would then
-+	 * be restored at the wrong places. */
-+	prevent_tail_call(ret);
-+	return ret;
-+}
---- linux-2.6.git-paolo/arch/i386/kernel/sys_i386.c	2005-08-21 21:43:37.000000000 +0200
-+++ linux-2.6.git-broken-paolo/arch/i386/kernel/sys_i386.c	2005-07-13 19:28:18.000000000 +0200
-@@ -41,7 +41,7 @@
- }
- 
- /* common code for old and new mmaps */
--static inline long do_mmap2(
-+long do_mmap2(struct mm_struct *mm,
- 	unsigned long addr, unsigned long len,
- 	unsigned long prot, unsigned long flags,
- 	unsigned long fd, unsigned long pgoff)
-@@ -56,9 +56,9 @@
- 			goto out;
- 	}
- 
--	down_write(&current->mm->mmap_sem);
--	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
--	up_write(&current->mm->mmap_sem);
-+	down_write(&mm->mmap_sem);
-+	error = __do_mmap_pgoff(mm, file, addr, len, prot, flags, pgoff);
-+	up_write(&mm->mmap_sem);
- 
- 	if (file)
- 		fput(file);
-@@ -70,7 +70,12 @@
- 	unsigned long prot, unsigned long flags,
- 	unsigned long fd, unsigned long pgoff)
- {
--	return do_mmap2(addr, len, prot, flags, fd, pgoff);
-+	long ret = do_mmap2(current->mm, addr, len, prot, flags, fd, pgoff);
-+
-+	/* A tail call would reorder parameters on the stack and they would then
-+	 * be restored at the wrong places. */
-+	prevent_tail_call(ret);
-+	return ret;
- }
- 
- /*
-@@ -101,7 +106,10 @@
- 	if (a.offset & ~PAGE_MASK)
- 		goto out;
- 
--	err = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
-+	err = do_mmap2(current->mm, a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
-+	/* A tail call would reorder parameters on the stack and they would then
-+	 * be restored at the wrong places. */
-+	prevent_tail_call(err);
- out:
- 	return err;
- }
---- linux-2.6.git/include/asm-i386/desc.h~i386-specific	2005-08-21 21:43:37.000000000 +0200
-+++ linux-2.6.git-paolo/include/asm-i386/desc.h	2005-08-21 21:43:37.000000000 +0200
-@@ -139,6 +139,9 @@ static inline unsigned long get_desc_bas
- 	return base;
- }
- 
-+extern int __modify_ldt(struct mm_struct * mm, int func, void __user *ptr,
-+		      unsigned long bytecount);
-+
- #endif /* !__ASSEMBLY__ */
- 
- #endif
---- linux-2.6.git-paolo/include/asm-i386/ptrace.h	2005-07-28 19:40:10.000000000 +0200
-+++ linux-2.6.git-paolo/include/asm-i386/ptrace.h	2005-07-28 19:40:18.000000000 +0200
-@@ -79,2 +79,31 @@
- 
-+/*For SKAS3 support.*/
-+#ifndef _LINUX_PTRACE_STRUCT_DEF
-+#define _LINUX_PTRACE_STRUCT_DEF
-+
-+#define PTRACE_FAULTINFO	  52
-+/* 53 was used for PTRACE_SIGPENDING, don't reuse it. */
-+#define PTRACE_LDT		  54
-+#define PTRACE_SWITCH_MM 	  55
-+#define PTRACE_EX_FAULTINFO	  56
-+
-+struct ptrace_faultinfo {
-+	int is_write;
-+	unsigned long addr;
-+};
-+
-+struct ptrace_ex_faultinfo {
-+	int is_write;
-+	unsigned long addr;
-+	int trap_no;
-+};
-+
-+struct ptrace_ldt {
-+	int func;
-+  	void *ptr;
-+	unsigned long bytecount;
-+};
-+
-+#endif /*ifndef _LINUX_PTRACE_STRUCT_DEF*/
-+
- #endif
---- linux-2.6.git-paolo/include/asm-i386/mmu_context.h	2005-08-21 21:43:37.000000000 +0200
-+++ linux-2.6.git-paolo/include/asm-i386/mmu_context.h	2005-07-04 18:48:25.000000000 +0200
-@@ -6,13 +6,25 @@
- #include <asm/atomic.h>
- #include <asm/pgalloc.h>
- #include <asm/tlbflush.h>
-+#include <asm/semaphore.h>
- 
- /*
-- * Used for LDT copy/destruction.
-+ * Used for LDT initialization/destruction. You cannot copy an LDT with
-+ * init_new_context, since it thinks you are passing it a new LDT and won't
-+ * deallocate its old content.
-  */
- int init_new_context(struct task_struct *tsk, struct mm_struct *mm);
- void destroy_context(struct mm_struct *mm);
- 
-+/* LDT initialization for a clean environment - needed for SKAS.*/
-+static inline void init_new_empty_context(struct mm_struct *mm)
-+{
-+	init_MUTEX(&mm->context.sem);
-+	mm->context.size = 0;
-+}
-+
-+/* LDT copy for SKAS - for the above problem.*/
-+int copy_context(struct mm_struct *mm, struct mm_struct *old_mm);
- 
- static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
- {
-@@ -29,6 +41,10 @@
- {
- 	int cpu = smp_processor_id();
- 
-+#ifdef CONFIG_SMP
-+	prev = per_cpu(cpu_tlbstate, cpu).active_mm;
-+#endif
-+
- 	if (likely(prev != next)) {
- 		/* stop flush ipis for the previous mm */
- 		cpu_clear(cpu, prev->cpu_vm_mask);
-@@ -50,7 +66,6 @@
- #ifdef CONFIG_SMP
- 	else {
- 		per_cpu(cpu_tlbstate, cpu).state = TLBSTATE_OK;
--		BUG_ON(per_cpu(cpu_tlbstate, cpu).active_mm != next);
- 
- 		if (!cpu_test_and_set(cpu, next->cpu_vm_mask)) {
- 			/* We were in lazy tlb mode and leave_mm disabled 
---- linux-2.6.git-broken-paolo/localversion-skas	2005-07-13 19:30:11.000000000 +0200
-+++ linux-2.6.git-broken-paolo/localversion-skas	2005-07-13 19:30:14.000000000 +0200
-@@ -0,0 +1 @@
-+-skas3-v9-pre7
---- linux-2.6.git-paolo/arch/x86_64/mm/proc_mm.c	2005-07-31 18:56:20.000000000 +0200
-+++ linux-2.6.git-paolo/arch/x86_64/mm/proc_mm.c	2005-05-15 18:32:11.000000000 +0200
-@@ -0,0 +1,85 @@
-+#include <linux/proc_mm.h>
-+#include <linux/mm.h>
-+#include <linux/init.h>
-+#include <linux/proc_fs.h>
-+#include <linux/file.h>
-+#include <linux/mman.h>
-+#include <asm/uaccess.h>
-+#include <asm/mmu_context.h>
-+
-+ssize_t write_proc_mm_emul(struct file *file, const char *buffer,
-+			     size_t count, loff_t *ppos)
-+{
-+	struct mm_struct *mm = file->private_data;
-+	struct proc_mm_op32 req;
-+	int n, ret;
-+
-+	if(count > sizeof(req))
-+		return(-EINVAL);
-+
-+	n = copy_from_user(&req, buffer, count);
-+	if(n != 0)
-+		return(-EFAULT);
-+
-+	ret = count;
-+	switch(req.op){
-+	case MM_MMAP: {
-+		struct mm_mmap32 *map = &req.u.mmap;
-+
-+		/* Nobody ever noticed it, but do_mmap_pgoff() calls
-+		 * get_unmapped_area() which checks current->mm, if
-+		 * MAP_FIXED is not set, so mmap() could replace
-+		 * an old mapping.
-+		 */
-+		if (! (map->flags & MAP_FIXED))
-+			return(-EINVAL);
-+
-+		ret = __do_mmap(mm, map->addr, map->len, map->prot,
-+			       map->flags, map->fd, map->offset);
-+		if((ret & ~PAGE_MASK) == 0)
-+			ret = count;
-+
-+		break;
-+	}
-+	case MM_MUNMAP: {
-+		struct mm_munmap32 *unmap = &req.u.munmap;
-+
-+		down_write(&mm->mmap_sem);
-+		ret = do_munmap(mm, unmap->addr, unmap->len);
-+		up_write(&mm->mmap_sem);
-+
-+		if(ret == 0)
-+			ret = count;
-+		break;
-+	}
-+	case MM_MPROTECT: {
-+		struct mm_mprotect32 *protect = &req.u.mprotect;
-+
-+		ret = do_mprotect(mm, protect->addr, protect->len,
-+				  protect->prot);
-+		if(ret == 0)
-+			ret = count;
-+		break;
-+	}
-+
-+	case MM_COPY_SEGMENTS: {
-+		struct mm_struct *from = proc_mm_get_mm_emul(req.u.copy_segments);
-+
-+		if(IS_ERR(from)){
-+			ret = PTR_ERR(from);
-+			break;
-+		}
-+
-+		ret = copy_context(mm, from);
-+		if(ret == 0)
-+			ret = count;
-+		break;
-+	}
-+	default:
-+		ret = -EINVAL;
-+		break;
-+	}
-+
-+	return ret;
-+}
-+
---- /dev/null	2005-07-20 02:59:33.000000000 +0200
-+++ linux-2.6.git-paolo/include/asm-x86_64/proc_mm.h	2005-07-31 18:56:20.000000000 +0200
-@@ -0,0 +1,56 @@
-+#ifndef __ASM_PROC_MM
-+#define __ASM_PROC_MM
-+#include <linux/types.h>
-+
-+#include <asm/compat.h>
-+
-+struct mm_mmap32 {
-+	compat_ulong_t addr;
-+	compat_ulong_t len;
-+	compat_ulong_t prot;
-+	compat_ulong_t flags;
-+	compat_ulong_t fd;
-+	compat_ulong_t offset;
-+};
-+
-+struct mm_munmap32 {
-+	compat_ulong_t addr;
-+	compat_ulong_t len;
-+};
-+
-+struct mm_mprotect32 {
-+	compat_ulong_t addr;
-+	compat_ulong_t len;
-+        compat_uint_t prot;
-+};
-+
-+struct proc_mm_op32 {
-+	compat_int_t op;
-+	union {
-+		struct mm_mmap32 mmap;
-+		struct mm_munmap32 munmap;
-+	        struct mm_mprotect32 mprotect;
-+		compat_int_t copy_segments;
-+	} u;
-+};
-+
-+extern ssize_t write_proc_mm_emul(struct file *file, const char *buffer,
-+			     size_t count, loff_t *ppos);
-+
-+extern long do64_mmap(struct mm_struct *mm, unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags,
-+	unsigned long fd, unsigned long off);
-+
-+static inline long __do_mmap(struct mm_struct *mm, unsigned long addr,
-+		     unsigned long len, unsigned long prot,
-+		     unsigned long flags, unsigned long fd,
-+		     unsigned long off)
-+{
-+	/* The latter one is stricter, since will actually check that off is page
-+	 * aligned. The first one skipped the check. */
-+
-+	/* return do32_mmap2(mm, addr, len, prot, flags, fd, off >>
-+	 * PAGE_SHIFT);*/
-+	return do64_mmap(mm, addr, len, prot, flags, fd, off);
-+}
-+
-+#endif /* __ASM_PROC_MM */
---- linux-2.6.git-paolo/arch/x86_64/Kconfig	2005-07-31 18:56:20.000000000 +0200
-+++ linux-2.6.git-paolo/arch/x86_64/Kconfig	2005-08-21 21:44:05.000000000 +0200
-@@ -355,6 +355,26 @@
- 	  of memory and any 32-bit devices. Don't turn on unless you know what you
- 	  are doing.
- 
-+config PROC_MM
-+	bool "/proc/mm support"
-+	default y
-+
-+config PROC_MM_DUMPABLE
-+	bool "Make UML childs /proc/<pid> completely browsable"
-+	default n
-+	help
-+	  If in doubt, say N.
-+
-+	  This fiddles with some settings to make sure /proc/<pid> is completely
-+	  browsable by who started UML, at the expense of some additional
-+	  locking (maybe this could slow down the runned UMLs of a few percents,
-+	  I've not tested this).
-+
-+	  Also, if there is a bug in this feature, there is some little
-+	  possibility to do privilege escalation if you have UML installed
-+	  setuid (which you shouldn't have done) or if UML changes uid on
-+	  startup (which will be a good thing, when enabled) ...
-+
- config X86_MCE
- 	bool "Machine check support" if EMBEDDED
- 	default y
---- linux-2.6.git-paolo/arch/x86_64/ia32/ptrace32.c	2005-07-28 19:40:10.000000000 +0200
-+++ linux-2.6.git-paolo/arch/x86_64/ia32/ptrace32.c	2005-07-28 19:40:18.000000000 +0200
-@@ -18,6 +18,8 @@
- #include <linux/unistd.h>
- #include <linux/mm.h>
- #include <linux/ptrace.h>
-+#include <linux/types.h>
-+#include <linux/proc_mm.h>
- #include <asm/ptrace.h>
- #include <asm/compat.h>
- #include <asm/uaccess.h>
-@@ -27,6 +29,7 @@
- #include <asm/debugreg.h>
- #include <asm/i387.h>
- #include <asm/fpu32.h>
-+#include <asm/desc.h>
- 
- /* determines which flags the user has access to. */
- /* 1 = access 0 = no access */
-@@ -251,6 +254,11 @@
- 	case PTRACE_SETFPXREGS:
- 	case PTRACE_GETFPXREGS:
- 	case PTRACE_GETEVENTMSG:
-+#ifdef CONFIG_PROC_MM
-+	case PTRACE_FAULTINFO:
-+	case PTRACE_LDT:
-+	case PTRACE_SWITCH_MM:
-+#endif
- 		break;
- 	} 
- 
-@@ -363,6 +371,65 @@
- 		ret = 0; 
- 		break;
- 	}
-+#ifdef CONFIG_PROC_MM
-+	case PTRACE_EX_FAULTINFO: {
-+		struct ptrace_ex_faultinfo32 fault;
-+
-+		fault = ((struct ptrace_ex_faultinfo32)
-+			{ .is_write	= (compat_int_t) child->thread.error_code,
-+			  .addr		= (compat_uptr_t) child->thread.cr2,
-+			  .trap_no	= (compat_int_t) child->thread.trap_no });
-+		ret = copy_to_user((unsigned long *) datap, &fault,
-+				   sizeof(fault));
-+		break;
-+	}
-+
-+	case PTRACE_FAULTINFO: {
-+		struct ptrace_faultinfo32 fault;
-+
-+		fault = ((struct ptrace_faultinfo32)
-+			{ .is_write	= (compat_int_t) child->thread.error_code,
-+			  .addr		= (compat_uptr_t) child->thread.cr2 });
-+		ret = copy_to_user((unsigned long *) datap, &fault,
-+				   sizeof(fault));
-+		break;
-+	}
-+
-+	case PTRACE_LDT: {
-+		struct ptrace_ldt32 ldt;
-+
-+		if(copy_from_user(&ldt, (unsigned long *) datap,
-+				  sizeof(ldt))){
-+			ret = -EIO;
-+			break;
-+		}
-+		ret = __modify_ldt(child->mm, ldt.func, compat_ptr(ldt.ptr), ldt.bytecount);
-+		break;
-+	}
-+
-+	case PTRACE_SWITCH_MM: {
-+		struct mm_struct *old = child->mm;
-+		struct mm_struct *new = proc_mm_get_mm(data);
-+
-+		if(IS_ERR(new)){
-+			ret = PTR_ERR(new);
-+			break;
-+		}
-+
-+		atomic_inc(&new->mm_users);
-+
-+		lock_fix_dumpable_setting(child, new);
-+
-+		child->mm = new;
-+		child->active_mm = new;
-+
-+		task_unlock(child);
-+
-+		mmput(old);
-+		ret = 0;
-+		break;
-+	}
-+#endif
- 
- 	case PTRACE_GETEVENTMSG:
- 		ret = put_user(child->ptrace_message,(unsigned int __user *)compat_ptr(data));
---- linux-2.6.git/include/asm-x86_64/mmu_context.h~x86-64-specific-addition	2005-07-31 18:56:20.000000000 +0200
-+++ linux-2.6.git-paolo/include/asm-x86_64/mmu_context.h	2005-07-31 18:56:20.000000000 +0200
-@@ -8,13 +8,28 @@
- #include <asm/pda.h>
- #include <asm/pgtable.h>
- #include <asm/tlbflush.h>
-+#include <asm/semaphore.h>
- 
- /*
-  * possibly do the LDT unload here?
-+ * Used for LDT initialization/destruction. You cannot copy an LDT with
-+ * init_new_context, since it thinks you are passing it a new LDT and won't
-+ * deallocate its old content.
-  */
-+
- int init_new_context(struct task_struct *tsk, struct mm_struct *mm);
- void destroy_context(struct mm_struct *mm);
- 
-+/* LDT initialization for a clean environment - needed for SKAS.*/
-+static inline void init_new_empty_context(struct mm_struct *mm)
-+{
-+	init_MUTEX(&mm->context.sem);
-+	mm->context.size = 0;
-+}
-+
-+/* LDT copy for SKAS - for the above problem.*/
-+int copy_context(struct mm_struct *mm, struct mm_struct *old_mm);
-+
- #ifdef CONFIG_SMP
- 
- static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
-@@ -37,6 +52,9 @@ static inline void switch_mm(struct mm_s
- 			     struct task_struct *tsk)
- {
- 	unsigned cpu = smp_processor_id();
-+#ifdef CONFIG_SMP
-+	prev = read_pda(active_mm);
-+#endif
- 	if (likely(prev != next)) {
- 		/* stop flush ipis for the previous mm */
- 		clear_bit(cpu, &prev->cpu_vm_mask);
-@@ -53,8 +71,6 @@ static inline void switch_mm(struct mm_s
- #ifdef CONFIG_SMP
- 	else {
- 		write_pda(mmu_state, TLBSTATE_OK);
--		if (read_pda(active_mm) != next)
--			out_of_line_bug();
- 		if(!test_and_set_bit(cpu, &next->cpu_vm_mask)) {
- 			/* We were in lazy tlb mode and leave_mm disabled 
- 			 * tlb flush IPI delivery. We must reload CR3
---- linux-2.6.git/arch/x86_64/ia32/sys_ia32.c~x86-64-specific-addition	2005-07-31 18:56:20.000000000 +0200
-+++ linux-2.6.git-paolo/arch/x86_64/ia32/sys_ia32.c	2005-07-31 18:56:20.000000000 +0200
-@@ -833,11 +833,10 @@ sys32_adjtimex(struct timex32 __user *ut
- 	return ret;
- }
- 
--asmlinkage long sys32_mmap2(unsigned long addr, unsigned long len,
--	unsigned long prot, unsigned long flags,
-+long do32_mmap2(struct mm_struct *mm, unsigned long addr,
-+	unsigned long len, unsigned long prot, unsigned long flags,
- 	unsigned long fd, unsigned long pgoff)
- {
--	struct mm_struct *mm = current->mm;
- 	unsigned long error;
- 	struct file * file = NULL;
- 
-@@ -849,7 +848,7 @@ asmlinkage long sys32_mmap2(unsigned lon
- 	}
- 
- 	down_write(&mm->mmap_sem);
--	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-+	error = __do_mmap_pgoff(mm, file, addr, len, prot, flags, pgoff);
- 	up_write(&mm->mmap_sem);
- 
- 	if (file)
-@@ -857,6 +856,15 @@ asmlinkage long sys32_mmap2(unsigned lon
- 	return error;
- }
- 
-+/* XXX: this wrapper can be probably removed, we can simply use the 64-bit
-+ * version.*/
-+asmlinkage long sys32_mmap2(unsigned long addr, unsigned long len,
-+	unsigned long prot, unsigned long flags,
-+	unsigned long fd, unsigned long pgoff)
-+{
-+	return do32_mmap2(current->mm, addr, len, prot, flags, fd, pgoff);
-+}
-+
- asmlinkage long sys32_olduname(struct oldold_utsname __user * name)
- {
- 	int error;
---- linux-2.6.git-paolo/arch/x86_64/kernel/ldt.c	2005-07-31 18:56:20.000000000 +0200
-+++ linux-2.6.11-paolo/arch/x86_64/kernel/ldt.c	2005-03-05 19:49:55.120753864 +0100
-@@ -22,6 +22,7 @@
- #include <asm/ldt.h>
- #include <asm/desc.h>
- #include <asm/proto.h>
-+#include <asm/mmu_context.h>
- 
- #ifdef CONFIG_SMP /* avoids "defined but not used" warnig */
- static void flush_ldt(void *null)
-@@ -31,11 +32,12 @@
- }
- #endif
- 
--static int alloc_ldt(mm_context_t *pc, unsigned mincount, int reload)
-+static int alloc_ldt(struct mm_struct *mm, unsigned mincount, int reload)
- {
- 	void *oldldt;
- 	void *newldt;
- 	unsigned oldsize;
-+	mm_context_t * pc = &mm->context;
- 
- 	if (mincount <= (unsigned)pc->size)
- 		return 0;
-@@ -64,12 +66,14 @@
- 
- 		preempt_disable();
- 		mask = cpumask_of_cpu(smp_processor_id());
--		load_LDT(pc);
--		if (!cpus_equal(current->mm->cpu_vm_mask, mask))
-+		if (&current->active_mm->context == pc)
-+			load_LDT(pc);
-+		if (!cpus_equal(mm->cpu_vm_mask, mask))
- 			smp_call_function(flush_ldt, NULL, 1, 1);
- 		preempt_enable();
- #else
--		load_LDT(pc);
-+		if (&current->active_mm->context == pc)
-+			load_LDT(pc);
- #endif
- 	}
- 	if (oldsize) {
-@@ -81,12 +85,12 @@
- 	return 0;
- }
- 
--static inline int copy_ldt(mm_context_t *new, mm_context_t *old)
-+static inline int copy_ldt(struct mm_struct *new, struct mm_struct *old)
- {
--	int err = alloc_ldt(new, old->size, 0);
-+	int err = alloc_ldt(new, old->context.size, 0);
- 	if (err < 0)
- 		return err;
--	memcpy(new->ldt, old->ldt, old->size*LDT_ENTRY_SIZE);
-+	memcpy(new->context.ldt, old->context.ldt, old->context.size*LDT_ENTRY_SIZE);
- 	return 0;
- }
- 
-@@ -94,22 +98,24 @@
-  * we do not have to muck with descriptors here, that is
-  * done in switch_mm() as needed.
-  */
--int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
-+int copy_context(struct mm_struct *mm, struct mm_struct *old_mm)
- {
--	struct mm_struct * old_mm;
- 	int retval = 0;
- 
--	init_MUTEX(&mm->context.sem);
--	mm->context.size = 0;
--	old_mm = current->mm;
- 	if (old_mm && old_mm->context.size > 0) {
- 		down(&old_mm->context.sem);
--		retval = copy_ldt(&mm->context, &old_mm->context);
-+		retval = copy_ldt(mm, old_mm);
- 		up(&old_mm->context.sem);
- 	}
- 	return retval;
- }
- 
-+int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
-+{
-+	init_new_empty_context(mm);
-+	return copy_context(mm, current->mm);
-+}
-+
- /*
-  * 
-  * Don't touch the LDT register - we're already in the next thread.
-@@ -125,11 +131,10 @@
- 	}
- }
- 
--static int read_ldt(void __user * ptr, unsigned long bytecount)
-+static int read_ldt(struct mm_struct * mm, void __user * ptr, unsigned long bytecount)
- {
- 	int err;
- 	unsigned long size;
--	struct mm_struct * mm = current->mm;
- 
- 	if (!mm->context.size)
- 		return 0;
-@@ -170,10 +175,8 @@
- 	return bytecount; 
- }
- 
--static int write_ldt(void __user * ptr, unsigned long bytecount, int oldmode)
-+static int write_ldt(struct mm_struct * mm, void __user * ptr, unsigned long bytecount, int oldmode)
- {
--	struct task_struct *me = current;
--	struct mm_struct * mm = me->mm;
- 	__u32 entry_1, entry_2, *lp;
- 	int error;
- 	struct user_desc ldt_info;
-@@ -198,7 +201,7 @@
- 
- 	down(&mm->context.sem);
- 	if (ldt_info.entry_number >= (unsigned)mm->context.size) {
--		error = alloc_ldt(&current->mm->context, ldt_info.entry_number+1, 1);
-+		error = alloc_ldt(mm, ldt_info.entry_number+1, 1);
- 		if (error < 0)
- 			goto out_unlock;
- 	}
-@@ -234,20 +237,26 @@
--asmlinkage int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
-+int __modify_ldt(struct mm_struct * mm, int func, void __user *ptr,
-+		unsigned long bytecount)
- {
- 	int ret = -ENOSYS;
- 
- 	switch (func) {
- 	case 0:
--		ret = read_ldt(ptr, bytecount);
-+		ret = read_ldt(mm, ptr, bytecount);
- 		break;
- 	case 1:
--		ret = write_ldt(ptr, bytecount, 1);
-+		ret = write_ldt(mm, ptr, bytecount, 1);
- 		break;
- 	case 2:
- 		ret = read_default_ldt(ptr, bytecount);
- 		break;
- 	case 0x11:
--		ret = write_ldt(ptr, bytecount, 0);
-+		ret = write_ldt(mm, ptr, bytecount, 0);
- 		break;
- 	}
- 	return ret;
- }
-+
-+asmlinkage int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
-+{
-+	return __modify_ldt(current->mm, func, ptr, bytecount);
-+}
---- linux-2.6.git/include/asm-x86_64/desc.h~x86-64-specific-addition	2005-07-31 18:56:20.000000000 +0200
-+++ linux-2.6.git-paolo/include/asm-x86_64/desc.h	2005-07-31 18:56:20.000000000 +0200
-@@ -213,6 +213,9 @@ static inline void load_LDT(mm_context_t
- 
- extern struct desc_ptr idt_descr;
- 
-+extern int __modify_ldt(struct mm_struct * mm, int func, void __user *ptr,
-+		unsigned long bytecount);
-+
- #endif /* !__ASSEMBLY__ */
- 
- #endif
---- linux-2.6.git-paolo/include/asm-x86_64/ptrace.h	2005-07-28 19:40:10.000000000 +0200
-+++ linux-2.6.git-paolo/include/asm-x86_64/ptrace.h	2005-07-28 19:40:18.000000000 +0200
-@@ -64,6 +64,59 @@
- /* top of stack page */ 
- };
- 
-+/* Stolen from
-+#include <linux/compat.h>; we can't include it because
-+there is a nasty ciclic include chain.
-+*/
-+
-+#include <asm/types.h>
-+
-+#define		compat_int_t	s32
-+#define		compat_long_t	s32
-+#define		compat_uint_t	u32
-+#define		compat_ulong_t	u32
-+#define		compat_uptr_t	u32
-+
-+struct ptrace_faultinfo32 {
-+	compat_int_t is_write;
-+	compat_ulong_t addr;
-+};
-+
-+struct ptrace_ex_faultinfo32 {
-+	compat_int_t is_write;
-+	compat_ulong_t addr;
-+	compat_int_t trap_no;
-+};
-+
-+struct ptrace_ldt32 {
-+	compat_int_t func;
-+	compat_uptr_t ptr; /*Actually a void pointer on i386, but must be converted.*/
-+	compat_ulong_t bytecount;
-+};
-+
-+struct ptrace_faultinfo {
-+	int is_write;
-+	unsigned long addr;
-+};
-+
-+struct ptrace_ex_faultinfo {
-+	int is_write;
-+	unsigned long addr;
-+	int trap_no;
-+};
-+
-+struct ptrace_ldt {
-+	int func;
-+  	void *ptr;
-+	unsigned long bytecount;
-+};
-+
-+#undef	compat_int_t
-+#undef	compat_long_t
-+#undef	compat_uint_t
-+#undef	compat_ulong_t
-+#undef	compat_uptr_t
-+
- #endif
- 
- /* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
-@@ -74,6 +127,12 @@
- #define PTRACE_GETFPXREGS         18
- #define PTRACE_SETFPXREGS         19
- 
-+#define PTRACE_FAULTINFO 52
-+/* 53 was used for PTRACE_SIGPENDING, don't reuse it. */
-+#define PTRACE_LDT 54
-+#define PTRACE_SWITCH_MM 55
-+#define PTRACE_EX_FAULTINFO	  56
-+
- /* only useful for access 32bit programs */
- #define PTRACE_GET_THREAD_AREA    25
- #define PTRACE_SET_THREAD_AREA    26
---- linux-2.6.git/arch/x86_64/mm/Makefile~x86-64-specific-addition	2005-07-31 18:56:20.000000000 +0200
-+++ linux-2.6.git-paolo/arch/x86_64/mm/Makefile	2005-07-31 18:56:20.000000000 +0200
-@@ -7,5 +7,6 @@ obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpag
- obj-$(CONFIG_NUMA) += numa.o
- obj-$(CONFIG_K8_NUMA) += k8topology.o
- obj-$(CONFIG_ACPI_NUMA) += srat.o
-+obj-$(CONFIG_PROC_MM) += proc_mm.o
- 
- hugetlbpage-y = ../../i386/mm/hugetlbpage.o
---- linux-2.6.git-paolo/arch/x86_64/kernel/ptrace.c	2005-07-28 19:40:10.000000000 +0200
-+++ linux-2.6.git-paolo/arch/x86_64/kernel/ptrace.c	2005-07-28 19:40:18.000000000 +0200
-@@ -19,6 +19,7 @@
- #include <linux/audit.h>
- #include <linux/seccomp.h>
- #include <linux/signal.h>
-+#include <linux/proc_mm.h>
- 
- #include <asm/uaccess.h>
- #include <asm/pgtable.h>
-@@ -604,6 +605,79 @@
- 		break;
- 	}
- 
-+#ifdef CONFIG_PROC_MM
-+	case PTRACE_EX_FAULTINFO: {
-+		struct ptrace_ex_faultinfo fault;
-+
-+		/* I checked in thread_struct comments that error_code and cr2
-+		 * are still part of the "fault info" section, so I guess that
-+		 * things are unchanged for now. Still to check manuals. BB*/
-+		fault = ((struct ptrace_ex_faultinfo)
-+			{ .is_write	= child->thread.error_code,
-+			  .addr		= child->thread.cr2,
-+			  .trap_no	= child->thread.trap_no });
-+		ret = copy_to_user((unsigned long *) data, &fault,
-+				   sizeof(fault));
-+		if(ret)
-+			break;
-+		break;
-+	}
-+
-+	/*Don't extend this broken interface to x86-64*/
-+#if 0
-+	case PTRACE_FAULTINFO: {
-+		struct ptrace_faultinfo fault;
-+
-+		/* I checked in thread_struct comments that error_code and cr2
-+		 * are still part of the "fault info" section, so I guess that
-+		 * things are unchanged for now. Still to check manuals. BB*/
-+		fault = ((struct ptrace_faultinfo)
-+			{ .is_write	= child->thread.error_code,
-+			  .addr		= child->thread.cr2 });
-+		ret = copy_to_user((unsigned long *) data, &fault,
-+				   sizeof(fault));
-+		if(ret)
-+			break;
-+		break;
-+	}
-+#endif
-+
-+	case PTRACE_LDT: {
-+		struct ptrace_ldt ldt;
-+
-+		if(copy_from_user(&ldt, (unsigned long *) data,
-+				  sizeof(ldt))){
-+			ret = -EIO;
-+			break;
-+		}
-+		ret = __modify_ldt(child->mm, ldt.func, ldt.ptr, ldt.bytecount);
-+		break;
-+	}
-+
-+	case PTRACE_SWITCH_MM: {
-+		struct mm_struct *old = child->mm;
-+		struct mm_struct *new = proc_mm_get_mm64(data);
-+
-+		if(IS_ERR(new)){
-+			ret = PTR_ERR(new);
-+			break;
-+		}
-+
-+		atomic_inc(&new->mm_users);
-+
-+		lock_fix_dumpable_setting(child, new);
-+
-+		child->mm = new;
-+		child->active_mm = new;
-+
-+		task_unlock(child);
-+
-+		mmput(old);
-+		ret = 0;
-+		break;
-+	}
-+#endif
-+
- 	default:
- 		ret = ptrace_request(child, request, addr, data);
- 		break;
---- linux-2.6.git/arch/x86_64/kernel/sys_x86_64.c~x86-64-specific-addition	2005-07-31 18:56:20.000000000 +0200
-+++ linux-2.6.git-paolo/arch/x86_64/kernel/sys_x86_64.c	2005-07-31 18:56:20.000000000 +0200
-@@ -19,6 +19,7 @@
- 
- #include <asm/uaccess.h>
- #include <asm/ia32.h>
-+#include <asm/proc_mm.h>
- 
- /*
-  * sys_pipe() is the normal C calling standard for creating
-@@ -37,7 +38,7 @@ asmlinkage long sys_pipe(int __user *fil
- 	return error;
- }
- 
--asmlinkage long sys_mmap(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags,
-+long do64_mmap(struct mm_struct *mm, unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags,
- 	unsigned long fd, unsigned long off)
- {
- 	long error;
-@@ -55,9 +56,9 @@ asmlinkage long sys_mmap(unsigned long a
- 		if (!file)
- 			goto out;
- 	}
--	down_write(&current->mm->mmap_sem);
--	error = do_mmap_pgoff(file, addr, len, prot, flags, off >> PAGE_SHIFT);
--	up_write(&current->mm->mmap_sem);
-+	down_write(&mm->mmap_sem);
-+	error = __do_mmap_pgoff(mm, file, addr, len, prot, flags, off >> PAGE_SHIFT);
-+	up_write(&mm->mmap_sem);
- 
- 	if (file)
- 		fput(file);
-@@ -65,6 +66,12 @@ out:
- 	return error;
- }
- 
-+asmlinkage long sys_mmap(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags,
-+	unsigned long fd, unsigned long off)
-+{
-+	return do64_mmap(current->mm, addr, len, prot, flags, fd, off);
-+}
-+
- static void find_start_end(unsigned long flags, unsigned long *begin,
- 			   unsigned long *end)
- {
---- /dev/null	2005-07-20 02:59:33.000000000 +0200
-+++ linux-2.6.git-paolo/include/asm-i386/proc_mm.h	2005-07-31 18:56:20.000000000 +0200
-@@ -0,0 +1,18 @@
-+#ifndef __ASM_PROC_MM
-+#define __ASM_PROC_MM
-+
-+#include <asm/page.h>
-+
-+extern long do_mmap2(struct mm_struct *mm, unsigned long addr,
-+		unsigned long len, unsigned long prot, unsigned long flags,
-+		unsigned long fd, unsigned long pgoff);
-+
-+static inline long __do_mmap(struct mm_struct *mm, unsigned long addr,
-+		     unsigned long len, unsigned long prot,
-+		     unsigned long flags, unsigned long fd,
-+		     unsigned long off)
-+{
-+	return do_mmap2(mm, addr, len, prot, flags, fd, off >> PAGE_SHIFT);
-+}
-+
-+#endif /* __ASM_PROC_MM */
---- /dev/null	2005-06-27 20:00:42.865153360 +0200
-+++ linux-2.6.git-paolo/mm/proc_mm-mod.c	2005-07-04 18:50:00.000000000 +0200
-@@ -0,0 +1,51 @@
-+#include <linux/config.h>
-+#include <linux/kernel.h>
-+#include <linux/proc_mm.h>
-+#include <linux/ptrace.h>
-+#include <linux/module.h>
-+
-+#ifdef CONFIG_64BIT
-+#define PRINT_OFFSET(type, member) \
-+	printk(KERN_DEBUG "struct " #type "32->" #member " \t: %ld\n", (long) offsetof(struct type ## 32, member))
-+#else
-+#define PRINT_OFFSET(type, member) \
-+	printk(KERN_DEBUG "struct " #type "->" #member " \t: %ld\n", (long) offsetof(struct type, member))
-+#endif
-+
-+static int debug_printoffsets(void)
-+{
-+	printk(KERN_DEBUG "Skas core structures layout BEGIN:\n");
-+	PRINT_OFFSET(mm_mmap, addr);
-+	PRINT_OFFSET(mm_mmap, len);
-+	PRINT_OFFSET(mm_mmap, prot);
-+	PRINT_OFFSET(mm_mmap, flags);
-+	PRINT_OFFSET(mm_mmap, fd);
-+	PRINT_OFFSET(mm_mmap, offset);
-+
-+	PRINT_OFFSET(mm_munmap, addr);
-+	PRINT_OFFSET(mm_munmap, len);
-+
-+	PRINT_OFFSET(mm_mprotect, addr);
-+	PRINT_OFFSET(mm_mprotect, len);
-+	PRINT_OFFSET(mm_mprotect, prot);
-+
-+	PRINT_OFFSET(proc_mm_op, op);
-+	PRINT_OFFSET(proc_mm_op, u);
-+	PRINT_OFFSET(proc_mm_op, u.mmap);
-+	PRINT_OFFSET(proc_mm_op, u.munmap);
-+	PRINT_OFFSET(proc_mm_op, u.mprotect);
-+	PRINT_OFFSET(proc_mm_op, u.copy_segments);
-+
-+	PRINT_OFFSET(ptrace_faultinfo, is_write);
-+	PRINT_OFFSET(ptrace_faultinfo, addr);
-+
-+	PRINT_OFFSET(ptrace_ldt, func);
-+	PRINT_OFFSET(ptrace_ldt, ptr);
-+	PRINT_OFFSET(ptrace_ldt, bytecount);
-+	printk(KERN_DEBUG "Skas core structures layout END.\n");
-+
-+	return 0;
-+}
-+#undef PRINT_OFFSET
-+
-+module_init(debug_printoffsets);

Deleted: trunk/src/kernel-patch-skas/skas-2.6.14-v9-pre7.patch
===================================================================
--- trunk/src/kernel-patch-skas/skas-2.6.14-v9-pre7.patch	2006-08-27 15:01:30 UTC (rev 166)
+++ trunk/src/kernel-patch-skas/skas-2.6.14-v9-pre7.patch	2006-08-27 15:16:57 UTC (rev 167)
@@ -1,1874 +0,0 @@
-Index: linux-2.6.14/arch/i386/Kconfig
-===================================================================
---- linux-2.6.14.orig/arch/i386/Kconfig	2005-10-29 05:49:31.000000000 +0200
-+++ linux-2.6.14/arch/i386/Kconfig	2005-10-29 05:50:33.000000000 +0200
-@@ -756,6 +756,26 @@
- 	depends on HIGHMEM64G
- 	default y
- 
-+config PROC_MM
-+	bool "/proc/mm support"
-+	default y
-+
-+config PROC_MM_DUMPABLE
-+	bool "Make UML childs /proc/<pid> completely browsable"
-+	default n
-+	help
-+	  If in doubt, say N.
-+
-+	  This fiddles with some settings to make sure /proc/<pid> is completely
-+	  browsable by who started UML, at the expense of some additional
-+	  locking (maybe this could slow down the runned UMLs of a few percents,
-+	  I've not tested this).
-+
-+	  Also, if there is a bug in this feature, there is some little
-+	  possibility to do privilege escalation if you have UML installed
-+	  setuid (which you shouldn't have done) or if UML changes uid on
-+	  startup (which will be a good thing, when enabled) ...
-+
- # Common NUMA Features
- config NUMA
- 	bool "Numa Memory Allocation and Scheduler Support"
-Index: linux-2.6.14/arch/i386/kernel/ldt.c
-===================================================================
---- linux-2.6.14.orig/arch/i386/kernel/ldt.c	2005-10-29 05:49:31.000000000 +0200
-+++ linux-2.6.14/arch/i386/kernel/ldt.c	2005-10-29 05:50:30.000000000 +0200
-@@ -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)
-@@ -27,11 +28,12 @@
- }
- #endif
- 
--static int alloc_ldt(mm_context_t *pc, int mincount, int reload)
-+static int alloc_ldt(struct mm_struct *mm, int mincount, int reload)
- {
- 	void *oldldt;
- 	void *newldt;
- 	int oldsize;
-+	mm_context_t * pc = &mm->context;
- 
- 	if (mincount <= pc->size)
- 		return 0;
-@@ -58,13 +60,15 @@
- #ifdef CONFIG_SMP
- 		cpumask_t mask;
- 		preempt_disable();
--		load_LDT(pc);
-+		if (&current->active_mm->context == pc)
-+			load_LDT(pc);
- 		mask = cpumask_of_cpu(smp_processor_id());
--		if (!cpus_equal(current->mm->cpu_vm_mask, mask))
-+		if (!cpus_equal(mm->cpu_vm_mask, mask))
- 			smp_call_function(flush_ldt, NULL, 1, 1);
- 		preempt_enable();
- #else
--		load_LDT(pc);
-+		if (&current->active_mm->context == pc)
-+			load_LDT(pc);
- #endif
- 	}
- 	if (oldsize) {
-@@ -76,12 +80,12 @@
- 	return 0;
- }
- 
--static inline int copy_ldt(mm_context_t *new, mm_context_t *old)
-+static inline int copy_ldt(struct mm_struct *new, struct mm_struct *old)
- {
--	int err = alloc_ldt(new, old->size, 0);
-+	int err = alloc_ldt(new, old->context.size, 0);
- 	if (err < 0)
- 		return err;
--	memcpy(new->ldt, old->ldt, old->size*LDT_ENTRY_SIZE);
-+	memcpy(new->context.ldt, old->context.ldt, old->context.size*LDT_ENTRY_SIZE);
- 	return 0;
- }
- 
-@@ -89,22 +93,24 @@
-  * we do not have to muck with descriptors here, that is
-  * done in switch_mm() as needed.
-  */
--int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
-+int copy_context(struct mm_struct *mm, struct mm_struct *old_mm)
- {
--	struct mm_struct * old_mm;
- 	int retval = 0;
- 
--	init_MUTEX(&mm->context.sem);
--	mm->context.size = 0;
--	old_mm = current->mm;
- 	if (old_mm && old_mm->context.size > 0) {
- 		down(&old_mm->context.sem);
--		retval = copy_ldt(&mm->context, &old_mm->context);
-+		retval = copy_ldt(mm, old_mm);
- 		up(&old_mm->context.sem);
- 	}
- 	return retval;
- }
- 
-+int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
-+{
-+	init_new_empty_context(mm);
-+	return copy_context(mm, current->mm);
-+}
-+
- /*
-  * No need to lock the MM as we are the last user
-  */
-@@ -121,11 +127,11 @@
- 	}
- }
- 
--static int read_ldt(void __user * ptr, unsigned long bytecount)
-+static int read_ldt(struct mm_struct * mm, void __user * ptr,
-+		    unsigned long bytecount)
- {
- 	int err;
- 	unsigned long size;
--	struct mm_struct * mm = current->mm;
- 
- 	if (!mm->context.size)
- 		return 0;
-@@ -174,9 +180,8 @@
- 	return err;
- }
- 
--static int write_ldt(void __user * ptr, unsigned long bytecount, int oldmode)
-+static int write_ldt(struct mm_struct * mm, void __user * ptr, unsigned long bytecount, int oldmode)
- {
--	struct mm_struct * mm = current->mm;
- 	__u32 entry_1, entry_2;
- 	int error;
- 	struct user_desc ldt_info;
-@@ -200,7 +205,7 @@
- 
- 	down(&mm->context.sem);
- 	if (ldt_info.entry_number >= mm->context.size) {
--		error = alloc_ldt(&current->mm->context, ldt_info.entry_number+1, 1);
-+		error = alloc_ldt(mm, ldt_info.entry_number+1, 1);
- 		if (error < 0)
- 			goto out_unlock;
- 	}
-@@ -230,23 +235,33 @@
- 	return error;
- }
- 
--asmlinkage int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
-+int __modify_ldt(struct mm_struct * mm, int func, void __user *ptr,
-+	       unsigned long bytecount)
- {
- 	int ret = -ENOSYS;
- 
- 	switch (func) {
- 	case 0:
--		ret = read_ldt(ptr, bytecount);
-+		ret = read_ldt(mm, ptr, bytecount);
- 		break;
- 	case 1:
--		ret = write_ldt(ptr, bytecount, 1);
-+		ret = write_ldt(mm, ptr, bytecount, 1);
- 		break;
- 	case 2:
- 		ret = read_default_ldt(ptr, bytecount);
- 		break;
- 	case 0x11:
--		ret = write_ldt(ptr, bytecount, 0);
-+		ret = write_ldt(mm, ptr, bytecount, 0);
- 		break;
- 	}
- 	return ret;
- }
-+
-+asmlinkage int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
-+{
-+	int ret = __modify_ldt(current->mm, func, ptr, bytecount);
-+	/* A tail call would reorder parameters on the stack and they would then
-+	 * be restored at the wrong places. */
-+	prevent_tail_call(ret);
-+	return ret;
-+}
-Index: linux-2.6.14/arch/i386/kernel/ptrace.c
-===================================================================
---- linux-2.6.14.orig/arch/i386/kernel/ptrace.c	2005-10-29 05:49:31.000000000 +0200
-+++ linux-2.6.14/arch/i386/kernel/ptrace.c	2005-10-29 05:50:34.000000000 +0200
-@@ -17,6 +17,7 @@
- #include <linux/audit.h>
- #include <linux/seccomp.h>
- #include <linux/signal.h>
-+#include <linux/proc_mm.h>
- 
- #include <asm/uaccess.h>
- #include <asm/pgtable.h>
-@@ -659,6 +660,70 @@
- 					(struct user_desc __user *) data);
- 		break;
- 
-+#ifdef CONFIG_PROC_MM
-+	case PTRACE_EX_FAULTINFO: {
-+		struct ptrace_ex_faultinfo fault;
-+
-+		fault = ((struct ptrace_ex_faultinfo)
-+			{ .is_write	= child->thread.error_code,
-+			  .addr		= child->thread.cr2,
-+			  .trap_no	= child->thread.trap_no });
-+		ret = copy_to_user((unsigned long *) data, &fault,
-+				   sizeof(fault));
-+		if(ret)
-+			break;
-+		break;
-+	}
-+
-+	case PTRACE_FAULTINFO: {
-+		struct ptrace_faultinfo fault;
-+
-+		fault = ((struct ptrace_faultinfo)
-+			{ .is_write	= child->thread.error_code,
-+			  .addr		= child->thread.cr2 });
-+		ret = copy_to_user((unsigned long *) data, &fault,
-+				   sizeof(fault));
-+		if(ret)
-+			break;
-+		break;
-+	}
-+
-+	case PTRACE_LDT: {
-+		struct ptrace_ldt ldt;
-+
-+		if(copy_from_user(&ldt, (unsigned long *) data,
-+				  sizeof(ldt))){
-+			ret = -EIO;
-+			break;
-+		}
-+		ret = __modify_ldt(child->mm, ldt.func, ldt.ptr, ldt.bytecount);
-+		break;
-+	}
-+
-+	case PTRACE_SWITCH_MM: {
-+		struct mm_struct *old = child->mm;
-+		struct mm_struct *new = proc_mm_get_mm(data);
-+
-+		if(IS_ERR(new)){
-+			ret = PTR_ERR(new);
-+			break;
-+		}
-+
-+		atomic_inc(&new->mm_users);
-+
-+		lock_fix_dumpable_setting(child, new);
-+
-+		child->mm = new;
-+		child->active_mm = new;
-+
-+		task_unlock(child);
-+
-+		mmput(old);
-+		ret = 0;
-+		break;
-+	}
-+#endif
-+
- 	default:
- 		ret = ptrace_request(child, request, addr, data);
- 		break;
-Index: linux-2.6.14/arch/i386/kernel/sys_i386.c
-===================================================================
---- linux-2.6.14.orig/arch/i386/kernel/sys_i386.c	2005-10-29 05:49:31.000000000 +0200
-+++ linux-2.6.14/arch/i386/kernel/sys_i386.c	2005-10-29 05:50:28.000000000 +0200
-@@ -41,7 +41,7 @@
- }
- 
- /* common code for old and new mmaps */
--static inline long do_mmap2(
-+long do_mmap2(struct mm_struct *mm,
- 	unsigned long addr, unsigned long len,
- 	unsigned long prot, unsigned long flags,
- 	unsigned long fd, unsigned long pgoff)
-@@ -56,9 +56,9 @@
- 			goto out;
- 	}
- 
--	down_write(&current->mm->mmap_sem);
--	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
--	up_write(&current->mm->mmap_sem);
-+	down_write(&mm->mmap_sem);
-+	error = __do_mmap_pgoff(mm, file, addr, len, prot, flags, pgoff);
-+	up_write(&mm->mmap_sem);
- 
- 	if (file)
- 		fput(file);
-@@ -70,7 +70,12 @@
- 	unsigned long prot, unsigned long flags,
- 	unsigned long fd, unsigned long pgoff)
- {
--	return do_mmap2(addr, len, prot, flags, fd, pgoff);
-+	long ret = do_mmap2(current->mm, addr, len, prot, flags, fd, pgoff);
-+
-+	/* A tail call would reorder parameters on the stack and they would then
-+	 * be restored at the wrong places. */
-+	prevent_tail_call(ret);
-+	return ret;
- }
- 
- /*
-@@ -101,7 +106,10 @@
- 	if (a.offset & ~PAGE_MASK)
- 		goto out;
- 
--	err = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
-+	err = do_mmap2(current->mm, a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
-+	/* A tail call would reorder parameters on the stack and they would then
-+	 * be restored at the wrong places. */
-+	prevent_tail_call(err);
- out:
- 	return err;
- }
-Index: linux-2.6.14/arch/um/include/skas_ptrace.h
-===================================================================
---- linux-2.6.14.orig/arch/um/include/skas_ptrace.h	2005-10-29 05:49:33.000000000 +0200
-+++ linux-2.6.14/arch/um/include/skas_ptrace.h	2005-10-29 05:50:00.000000000 +0200
-@@ -6,6 +6,8 @@
- #ifndef __SKAS_PTRACE_H
- #define __SKAS_PTRACE_H
- 
-+#ifndef PTRACE_FAULTINFO
-+
- #define PTRACE_FAULTINFO 52
- #define PTRACE_SWITCH_MM 55
- 
-@@ -13,6 +15,8 @@
- 
- #endif
- 
-+#endif
-+
- /*
-  * Overrides for Emacs so that we follow Linus's tabbing style.
-  * Emacs will notice this stuff at the end of the file and automatically
-Index: linux-2.6.14/arch/x86_64/ia32/ptrace32.c
-===================================================================
---- linux-2.6.14.orig/arch/x86_64/ia32/ptrace32.c	2005-10-29 05:49:27.000000000 +0200
-+++ linux-2.6.14/arch/x86_64/ia32/ptrace32.c	2005-10-29 05:50:34.000000000 +0200
-@@ -18,6 +18,8 @@
- #include <linux/unistd.h>
- #include <linux/mm.h>
- #include <linux/ptrace.h>
-+#include <linux/types.h>
-+#include <linux/proc_mm.h>
- #include <asm/ptrace.h>
- #include <asm/compat.h>
- #include <asm/uaccess.h>
-@@ -27,6 +29,7 @@
- #include <asm/debugreg.h>
- #include <asm/i387.h>
- #include <asm/fpu32.h>
-+#include <asm/desc.h>
- 
- /* determines which flags the user has access to. */
- /* 1 = access 0 = no access */
-@@ -251,6 +254,11 @@
- 	case PTRACE_SETFPXREGS:
- 	case PTRACE_GETFPXREGS:
- 	case PTRACE_GETEVENTMSG:
-+#ifdef CONFIG_PROC_MM
-+	case PTRACE_FAULTINFO:
-+	case PTRACE_LDT:
-+	case PTRACE_SWITCH_MM:
-+#endif
- 		break;
- 	} 
- 
-@@ -363,6 +371,65 @@
- 		ret = 0; 
- 		break;
- 	}
-+#ifdef CONFIG_PROC_MM
-+	case PTRACE_EX_FAULTINFO: {
-+		struct ptrace_ex_faultinfo32 fault;
-+
-+		fault = ((struct ptrace_ex_faultinfo32)
-+			{ .is_write	= (compat_int_t) child->thread.error_code,
-+			  .addr		= (compat_uptr_t) child->thread.cr2,
-+			  .trap_no	= (compat_int_t) child->thread.trap_no });
-+		ret = copy_to_user((unsigned long *) datap, &fault,
-+				   sizeof(fault));
-+		break;
-+	}
-+
-+	case PTRACE_FAULTINFO: {
-+		struct ptrace_faultinfo32 fault;
-+
-+		fault = ((struct ptrace_faultinfo32)
-+			{ .is_write	= (compat_int_t) child->thread.error_code,
-+			  .addr		= (compat_uptr_t) child->thread.cr2 });
-+		ret = copy_to_user((unsigned long *) datap, &fault,
-+				   sizeof(fault));
-+		break;
-+	}
-+
-+	case PTRACE_LDT: {
-+		struct ptrace_ldt32 ldt;
-+
-+		if(copy_from_user(&ldt, (unsigned long *) datap,
-+				  sizeof(ldt))){
-+			ret = -EIO;
-+			break;
-+		}
-+		ret = __modify_ldt(child->mm, ldt.func, compat_ptr(ldt.ptr), ldt.bytecount);
-+		break;
-+	}
-+
-+	case PTRACE_SWITCH_MM: {
-+		struct mm_struct *old = child->mm;
-+		struct mm_struct *new = proc_mm_get_mm(data);
-+
-+		if(IS_ERR(new)){
-+			ret = PTR_ERR(new);
-+			break;
-+		}
-+
-+		atomic_inc(&new->mm_users);
-+
-+		lock_fix_dumpable_setting(child, new);
-+
-+		child->mm = new;
-+		child->active_mm = new;
-+
-+		task_unlock(child);
-+
-+		mmput(old);
-+		ret = 0;
-+		break;
-+	}
-+#endif
- 
- 	case PTRACE_GETEVENTMSG:
- 		ret = put_user(child->ptrace_message,(unsigned int __user *)compat_ptr(data));
-Index: linux-2.6.14/arch/x86_64/ia32/sys_ia32.c
-===================================================================
---- linux-2.6.14.orig/arch/x86_64/ia32/sys_ia32.c	2005-10-29 05:49:27.000000000 +0200
-+++ linux-2.6.14/arch/x86_64/ia32/sys_ia32.c	2005-10-29 05:50:31.000000000 +0200
-@@ -833,11 +833,10 @@
- 	return ret;
- }
- 
--asmlinkage long sys32_mmap2(unsigned long addr, unsigned long len,
--	unsigned long prot, unsigned long flags,
-+long do32_mmap2(struct mm_struct *mm, unsigned long addr,
-+	unsigned long len, unsigned long prot, unsigned long flags,
- 	unsigned long fd, unsigned long pgoff)
- {
--	struct mm_struct *mm = current->mm;
- 	unsigned long error;
- 	struct file * file = NULL;
- 
-@@ -849,7 +848,7 @@
- 	}
- 
- 	down_write(&mm->mmap_sem);
--	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-+	error = __do_mmap_pgoff(mm, file, addr, len, prot, flags, pgoff);
- 	up_write(&mm->mmap_sem);
- 
- 	if (file)
-@@ -857,6 +856,15 @@
- 	return error;
- }
- 
-+/* XXX: this wrapper can be probably removed, we can simply use the 64-bit
-+ * version.*/
-+asmlinkage long sys32_mmap2(unsigned long addr, unsigned long len,
-+	unsigned long prot, unsigned long flags,
-+	unsigned long fd, unsigned long pgoff)
-+{
-+	return do32_mmap2(current->mm, addr, len, prot, flags, fd, pgoff);
-+}
-+
- asmlinkage long sys32_olduname(struct oldold_utsname __user * name)
- {
- 	int error;
-Index: linux-2.6.14/arch/x86_64/Kconfig
-===================================================================
---- linux-2.6.14.orig/arch/x86_64/Kconfig	2005-10-29 05:49:27.000000000 +0200
-+++ linux-2.6.14/arch/x86_64/Kconfig	2005-10-29 05:50:33.000000000 +0200
-@@ -357,6 +357,26 @@
- 	  of memory and any 32-bit devices. Don't turn on unless you know what you
- 	  are doing.
- 
-+config PROC_MM
-+	bool "/proc/mm support"
-+	default y
-+
-+config PROC_MM_DUMPABLE
-+	bool "Make UML childs /proc/<pid> completely browsable"
-+	default n
-+	help
-+	  If in doubt, say N.
-+
-+	  This fiddles with some settings to make sure /proc/<pid> is completely
-+	  browsable by who started UML, at the expense of some additional
-+	  locking (maybe this could slow down the runned UMLs of a few percents,
-+	  I've not tested this).
-+
-+	  Also, if there is a bug in this feature, there is some little
-+	  possibility to do privilege escalation if you have UML installed
-+	  setuid (which you shouldn't have done) or if UML changes uid on
-+	  startup (which will be a good thing, when enabled) ...
-+
- config X86_MCE
- 	bool "Machine check support" if EMBEDDED
- 	default y
-Index: linux-2.6.14/arch/x86_64/kernel/ldt.c
-===================================================================
---- linux-2.6.14.orig/arch/x86_64/kernel/ldt.c	2005-10-29 05:49:27.000000000 +0200
-+++ linux-2.6.14/arch/x86_64/kernel/ldt.c	2005-10-29 05:50:33.000000000 +0200
-@@ -22,6 +22,7 @@
- #include <asm/ldt.h>
- #include <asm/desc.h>
- #include <asm/proto.h>
-+#include <asm/mmu_context.h>
- 
- #ifdef CONFIG_SMP /* avoids "defined but not used" warnig */
- static void flush_ldt(void *null)
-@@ -31,11 +32,12 @@
- }
- #endif
- 
--static int alloc_ldt(mm_context_t *pc, unsigned mincount, int reload)
-+static int alloc_ldt(struct mm_struct *mm, unsigned mincount, int reload)
- {
- 	void *oldldt;
- 	void *newldt;
- 	unsigned oldsize;
-+	mm_context_t * pc = &mm->context;
- 
- 	if (mincount <= (unsigned)pc->size)
- 		return 0;
-@@ -64,12 +66,14 @@
- 
- 		preempt_disable();
- 		mask = cpumask_of_cpu(smp_processor_id());
--		load_LDT(pc);
--		if (!cpus_equal(current->mm->cpu_vm_mask, mask))
-+		if (&current->active_mm->context == pc)
-+			load_LDT(pc);
-+		if (!cpus_equal(mm->cpu_vm_mask, mask))
- 			smp_call_function(flush_ldt, NULL, 1, 1);
- 		preempt_enable();
- #else
--		load_LDT(pc);
-+		if (&current->active_mm->context == pc)
-+			load_LDT(pc);
- #endif
- 	}
- 	if (oldsize) {
-@@ -81,12 +85,12 @@
- 	return 0;
- }
- 
--static inline int copy_ldt(mm_context_t *new, mm_context_t *old)
-+static inline int copy_ldt(struct mm_struct *new, struct mm_struct *old)
- {
--	int err = alloc_ldt(new, old->size, 0);
-+	int err = alloc_ldt(new, old->context.size, 0);
- 	if (err < 0)
- 		return err;
--	memcpy(new->ldt, old->ldt, old->size*LDT_ENTRY_SIZE);
-+	memcpy(new->context.ldt, old->context.ldt, old->context.size*LDT_ENTRY_SIZE);
- 	return 0;
- }
- 
-@@ -94,22 +98,24 @@
-  * we do not have to muck with descriptors here, that is
-  * done in switch_mm() as needed.
-  */
--int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
-+int copy_context(struct mm_struct *mm, struct mm_struct *old_mm)
- {
--	struct mm_struct * old_mm;
- 	int retval = 0;
- 
--	init_MUTEX(&mm->context.sem);
--	mm->context.size = 0;
--	old_mm = current->mm;
- 	if (old_mm && old_mm->context.size > 0) {
- 		down(&old_mm->context.sem);
--		retval = copy_ldt(&mm->context, &old_mm->context);
-+		retval = copy_ldt(mm, old_mm);
- 		up(&old_mm->context.sem);
- 	}
- 	return retval;
- }
- 
-+int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
-+{
-+	init_new_empty_context(mm);
-+	return copy_context(mm, current->mm);
-+}
-+
- /*
-  * 
-  * Don't touch the LDT register - we're already in the next thread.
-@@ -125,11 +131,10 @@
- 	}
- }
- 
--static int read_ldt(void __user * ptr, unsigned long bytecount)
-+static int read_ldt(struct mm_struct * mm, void __user * ptr, unsigned long bytecount)
- {
- 	int err;
- 	unsigned long size;
--	struct mm_struct * mm = current->mm;
- 
- 	if (!mm->context.size)
- 		return 0;
-@@ -170,10 +175,8 @@
- 	return bytecount; 
- }
- 
--static int write_ldt(void __user * ptr, unsigned long bytecount, int oldmode)
-+static int write_ldt(struct mm_struct * mm, void __user * ptr, unsigned long bytecount, int oldmode)
- {
--	struct task_struct *me = current;
--	struct mm_struct * mm = me->mm;
- 	__u32 entry_1, entry_2, *lp;
- 	int error;
- 	struct user_desc ldt_info;
-@@ -198,7 +201,7 @@
- 
- 	down(&mm->context.sem);
- 	if (ldt_info.entry_number >= (unsigned)mm->context.size) {
--		error = alloc_ldt(&current->mm->context, ldt_info.entry_number+1, 1);
-+		error = alloc_ldt(mm, ldt_info.entry_number+1, 1);
- 		if (error < 0)
- 			goto out_unlock;
- 	}
-@@ -231,23 +234,29 @@
- 	return error;
- }
- 
--asmlinkage int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
-+int __modify_ldt(struct mm_struct * mm, int func, void __user *ptr,
-+		unsigned long bytecount)
- {
- 	int ret = -ENOSYS;
- 
- 	switch (func) {
- 	case 0:
--		ret = read_ldt(ptr, bytecount);
-+		ret = read_ldt(mm, ptr, bytecount);
- 		break;
- 	case 1:
--		ret = write_ldt(ptr, bytecount, 1);
-+		ret = write_ldt(mm, ptr, bytecount, 1);
- 		break;
- 	case 2:
- 		ret = read_default_ldt(ptr, bytecount);
- 		break;
- 	case 0x11:
--		ret = write_ldt(ptr, bytecount, 0);
-+		ret = write_ldt(mm, ptr, bytecount, 0);
- 		break;
- 	}
- 	return ret;
- }
-+
-+asmlinkage int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
-+{
-+	return __modify_ldt(current->mm, func, ptr, bytecount);
-+}
-Index: linux-2.6.14/arch/x86_64/kernel/ptrace.c
-===================================================================
---- linux-2.6.14.orig/arch/x86_64/kernel/ptrace.c	2005-10-29 05:49:27.000000000 +0200
-+++ linux-2.6.14/arch/x86_64/kernel/ptrace.c	2005-10-29 05:50:34.000000000 +0200
-@@ -19,6 +19,7 @@
- #include <linux/audit.h>
- #include <linux/seccomp.h>
- #include <linux/signal.h>
-+#include <linux/proc_mm.h>
- 
- #include <asm/uaccess.h>
- #include <asm/pgtable.h>
-@@ -604,6 +605,79 @@
- 		break;
- 	}
- 
-+#ifdef CONFIG_PROC_MM
-+	case PTRACE_EX_FAULTINFO: {
-+		struct ptrace_ex_faultinfo fault;
-+
-+		/* I checked in thread_struct comments that error_code and cr2
-+		 * are still part of the "fault info" section, so I guess that
-+		 * things are unchanged for now. Still to check manuals. BB*/
-+		fault = ((struct ptrace_ex_faultinfo)
-+			{ .is_write	= child->thread.error_code,
-+			  .addr		= child->thread.cr2,
-+			  .trap_no	= child->thread.trap_no });
-+		ret = copy_to_user((unsigned long *) data, &fault,
-+				   sizeof(fault));
-+		if(ret)
-+			break;
-+		break;
-+	}
-+
-+	/*Don't extend this broken interface to x86-64*/
-+#if 0
-+	case PTRACE_FAULTINFO: {
-+		struct ptrace_faultinfo fault;
-+
-+		/* I checked in thread_struct comments that error_code and cr2
-+		 * are still part of the "fault info" section, so I guess that
-+		 * things are unchanged for now. Still to check manuals. BB*/
-+		fault = ((struct ptrace_faultinfo)
-+			{ .is_write	= child->thread.error_code,
-+			  .addr		= child->thread.cr2 });
-+		ret = copy_to_user((unsigned long *) data, &fault,
-+				   sizeof(fault));
-+		if(ret)
-+			break;
-+		break;
-+	}
-+#endif
-+
-+	case PTRACE_LDT: {
-+		struct ptrace_ldt ldt;
-+
-+		if(copy_from_user(&ldt, (unsigned long *) data,
-+				  sizeof(ldt))){
-+			ret = -EIO;
-+			break;
-+		}
-+		ret = __modify_ldt(child->mm, ldt.func, ldt.ptr, ldt.bytecount);
-+		break;
-+	}
-+
-+	case PTRACE_SWITCH_MM: {
-+		struct mm_struct *old = child->mm;
-+		struct mm_struct *new = proc_mm_get_mm64(data);
-+
-+		if(IS_ERR(new)){
-+			ret = PTR_ERR(new);
-+			break;
-+		}
-+
-+		atomic_inc(&new->mm_users);
-+
-+		lock_fix_dumpable_setting(child, new);
-+
-+		child->mm = new;
-+		child->active_mm = new;
-+
-+		task_unlock(child);
-+
-+		mmput(old);
-+		ret = 0;
-+		break;
-+	}
-+#endif
-+
- 	default:
- 		ret = ptrace_request(child, request, addr, data);
- 		break;
-Index: linux-2.6.14/arch/x86_64/kernel/sys_x86_64.c
-===================================================================
---- linux-2.6.14.orig/arch/x86_64/kernel/sys_x86_64.c	2005-10-29 05:49:27.000000000 +0200
-+++ linux-2.6.14/arch/x86_64/kernel/sys_x86_64.c	2005-10-29 05:50:31.000000000 +0200
-@@ -19,6 +19,7 @@
- 
- #include <asm/uaccess.h>
- #include <asm/ia32.h>
-+#include <asm/proc_mm.h>
- 
- /*
-  * sys_pipe() is the normal C calling standard for creating
-@@ -37,7 +38,7 @@
- 	return error;
- }
- 
--asmlinkage long sys_mmap(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags,
-+long do64_mmap(struct mm_struct *mm, unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags,
- 	unsigned long fd, unsigned long off)
- {
- 	long error;
-@@ -55,9 +56,9 @@
- 		if (!file)
- 			goto out;
- 	}
--	down_write(&current->mm->mmap_sem);
--	error = do_mmap_pgoff(file, addr, len, prot, flags, off >> PAGE_SHIFT);
--	up_write(&current->mm->mmap_sem);
-+	down_write(&mm->mmap_sem);
-+	error = __do_mmap_pgoff(mm, file, addr, len, prot, flags, off >> PAGE_SHIFT);
-+	up_write(&mm->mmap_sem);
- 
- 	if (file)
- 		fput(file);
-@@ -65,6 +66,12 @@
- 	return error;
- }
- 
-+asmlinkage long sys_mmap(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags,
-+	unsigned long fd, unsigned long off)
-+{
-+	return do64_mmap(current->mm, addr, len, prot, flags, fd, off);
-+}
-+
- static void find_start_end(unsigned long flags, unsigned long *begin,
- 			   unsigned long *end)
- {
-Index: linux-2.6.14/arch/x86_64/mm/Makefile
-===================================================================
---- linux-2.6.14.orig/arch/x86_64/mm/Makefile	2005-10-29 05:49:27.000000000 +0200
-+++ linux-2.6.14/arch/x86_64/mm/Makefile	2005-10-29 05:50:31.000000000 +0200
-@@ -7,5 +7,6 @@
- obj-$(CONFIG_NUMA) += numa.o
- obj-$(CONFIG_K8_NUMA) += k8topology.o
- obj-$(CONFIG_ACPI_NUMA) += srat.o
-+obj-$(CONFIG_PROC_MM) += proc_mm.o
- 
- hugetlbpage-y = ../../i386/mm/hugetlbpage.o
-Index: linux-2.6.14/arch/x86_64/mm/proc_mm.c
-===================================================================
---- /dev/null	1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.14/arch/x86_64/mm/proc_mm.c	2005-10-29 05:50:31.000000000 +0200
-@@ -0,0 +1,85 @@
-+#include <linux/proc_mm.h>
-+#include <linux/mm.h>
-+#include <linux/init.h>
-+#include <linux/proc_fs.h>
-+#include <linux/file.h>
-+#include <linux/mman.h>
-+#include <asm/uaccess.h>
-+#include <asm/mmu_context.h>
-+
-+ssize_t write_proc_mm_emul(struct file *file, const char *buffer,
-+			     size_t count, loff_t *ppos)
-+{
-+	struct mm_struct *mm = file->private_data;
-+	struct proc_mm_op32 req;
-+	int n, ret;
-+
-+	if(count > sizeof(req))
-+		return(-EINVAL);
-+
-+	n = copy_from_user(&req, buffer, count);
-+	if(n != 0)
-+		return(-EFAULT);
-+
-+	ret = count;
-+	switch(req.op){
-+	case MM_MMAP: {
-+		struct mm_mmap32 *map = &req.u.mmap;
-+
-+		/* Nobody ever noticed it, but do_mmap_pgoff() calls
-+		 * get_unmapped_area() which checks current->mm, if
-+		 * MAP_FIXED is not set, so mmap() could replace
-+		 * an old mapping.
-+		 */
-+		if (! (map->flags & MAP_FIXED))
-+			return(-EINVAL);
-+
-+		ret = __do_mmap(mm, map->addr, map->len, map->prot,
-+			       map->flags, map->fd, map->offset);
-+		if((ret & ~PAGE_MASK) == 0)
-+			ret = count;
-+
-+		break;
-+	}
-+	case MM_MUNMAP: {
-+		struct mm_munmap32 *unmap = &req.u.munmap;
-+
-+		down_write(&mm->mmap_sem);
-+		ret = do_munmap(mm, unmap->addr, unmap->len);
-+		up_write(&mm->mmap_sem);
-+
-+		if(ret == 0)
-+			ret = count;
-+		break;
-+	}
-+	case MM_MPROTECT: {
-+		struct mm_mprotect32 *protect = &req.u.mprotect;
-+
-+		ret = do_mprotect(mm, protect->addr, protect->len,
-+				  protect->prot);
-+		if(ret == 0)
-+			ret = count;
-+		break;
-+	}
-+
-+	case MM_COPY_SEGMENTS: {
-+		struct mm_struct *from = proc_mm_get_mm_emul(req.u.copy_segments);
-+
-+		if(IS_ERR(from)){
-+			ret = PTR_ERR(from);
-+			break;
-+		}
-+
-+		ret = copy_context(mm, from);
-+		if(ret == 0)
-+			ret = count;
-+		break;
-+	}
-+	default:
-+		ret = -EINVAL;
-+		break;
-+	}
-+
-+	return ret;
-+}
-+
-Index: linux-2.6.14/include/asm-i386/desc.h
-===================================================================
---- linux-2.6.14.orig/include/asm-i386/desc.h	2005-10-29 05:49:31.000000000 +0200
-+++ linux-2.6.14/include/asm-i386/desc.h	2005-10-29 05:50:06.000000000 +0200
-@@ -156,6 +156,9 @@
- 	return base;
- }
- 
-+extern int __modify_ldt(struct mm_struct * mm, int func, void __user *ptr,
-+		      unsigned long bytecount);
-+
- #endif /* !__ASSEMBLY__ */
- 
- #endif
-Index: linux-2.6.14/include/asm-i386/mmu_context.h
-===================================================================
---- linux-2.6.14.orig/include/asm-i386/mmu_context.h	2005-10-29 05:49:31.000000000 +0200
-+++ linux-2.6.14/include/asm-i386/mmu_context.h	2005-10-29 05:50:11.000000000 +0200
-@@ -6,13 +6,25 @@
- #include <asm/atomic.h>
- #include <asm/pgalloc.h>
- #include <asm/tlbflush.h>
-+#include <asm/semaphore.h>
- 
- /*
-- * Used for LDT copy/destruction.
-+ * Used for LDT initialization/destruction. You cannot copy an LDT with
-+ * init_new_context, since it thinks you are passing it a new LDT and won't
-+ * deallocate its old content.
-  */
- int init_new_context(struct task_struct *tsk, struct mm_struct *mm);
- void destroy_context(struct mm_struct *mm);
- 
-+/* LDT initialization for a clean environment - needed for SKAS.*/
-+static inline void init_new_empty_context(struct mm_struct *mm)
-+{
-+	init_MUTEX(&mm->context.sem);
-+	mm->context.size = 0;
-+}
-+
-+/* LDT copy for SKAS - for the above problem.*/
-+int copy_context(struct mm_struct *mm, struct mm_struct *old_mm);
- 
- static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
- {
-@@ -29,6 +41,10 @@
- {
- 	int cpu = smp_processor_id();
- 
-+#ifdef CONFIG_SMP
-+	prev = per_cpu(cpu_tlbstate, cpu).active_mm;
-+#endif
-+
- 	if (likely(prev != next)) {
- 		/* stop flush ipis for the previous mm */
- 		cpu_clear(cpu, prev->cpu_vm_mask);
-@@ -50,7 +66,6 @@
- #ifdef CONFIG_SMP
- 	else {
- 		per_cpu(cpu_tlbstate, cpu).state = TLBSTATE_OK;
--		BUG_ON(per_cpu(cpu_tlbstate, cpu).active_mm != next);
- 
- 		if (!cpu_test_and_set(cpu, next->cpu_vm_mask)) {
- 			/* We were in lazy tlb mode and leave_mm disabled 
-Index: linux-2.6.14/include/asm-i386/proc_mm.h
-===================================================================
---- /dev/null	1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.14/include/asm-i386/proc_mm.h	2005-10-29 05:50:31.000000000 +0200
-@@ -0,0 +1,18 @@
-+#ifndef __ASM_PROC_MM
-+#define __ASM_PROC_MM
-+
-+#include <asm/page.h>
-+
-+extern long do_mmap2(struct mm_struct *mm, unsigned long addr,
-+		unsigned long len, unsigned long prot, unsigned long flags,
-+		unsigned long fd, unsigned long pgoff);
-+
-+static inline long __do_mmap(struct mm_struct *mm, unsigned long addr,
-+		     unsigned long len, unsigned long prot,
-+		     unsigned long flags, unsigned long fd,
-+		     unsigned long off)
-+{
-+	return do_mmap2(mm, addr, len, prot, flags, fd, off >> PAGE_SHIFT);
-+}
-+
-+#endif /* __ASM_PROC_MM */
-Index: linux-2.6.14/include/asm-i386/ptrace.h
-===================================================================
---- linux-2.6.14.orig/include/asm-i386/ptrace.h	2005-10-29 05:49:31.000000000 +0200
-+++ linux-2.6.14/include/asm-i386/ptrace.h	2005-10-29 05:50:34.000000000 +0200
-@@ -84,4 +84,33 @@
- #endif
- #endif /* __KERNEL__ */
- 
-+/*For SKAS3 support.*/
-+#ifndef _LINUX_PTRACE_STRUCT_DEF
-+#define _LINUX_PTRACE_STRUCT_DEF
-+
-+#define PTRACE_FAULTINFO	  52
-+/* 53 was used for PTRACE_SIGPENDING, don't reuse it. */
-+#define PTRACE_LDT		  54
-+#define PTRACE_SWITCH_MM 	  55
-+#define PTRACE_EX_FAULTINFO	  56
-+
-+struct ptrace_faultinfo {
-+	int is_write;
-+	unsigned long addr;
-+};
-+
-+struct ptrace_ex_faultinfo {
-+	int is_write;
-+	unsigned long addr;
-+	int trap_no;
-+};
-+
-+struct ptrace_ldt {
-+	int func;
-+  	void *ptr;
-+	unsigned long bytecount;
-+};
-+
-+#endif /*ifndef _LINUX_PTRACE_STRUCT_DEF*/
-+
- #endif
-Index: linux-2.6.14/include/asm-i386/thread_info.h
-===================================================================
---- linux-2.6.14.orig/include/asm-i386/thread_info.h	2005-10-29 05:49:28.000000000 +0200
-+++ linux-2.6.14/include/asm-i386/thread_info.h	2005-10-29 05:50:29.000000000 +0200
-@@ -139,9 +139,9 @@
- #define TIF_NEED_RESCHED	3	/* rescheduling necessary */
- #define TIF_SINGLESTEP		4	/* restore singlestep on return to user mode */
- #define TIF_IRET		5	/* return with iret */
--#define TIF_SYSCALL_EMU		6	/* syscall emulation active */
- #define TIF_SYSCALL_AUDIT	7	/* syscall auditing active */
- #define TIF_SECCOMP		8	/* secure computing */
-+#define TIF_SYSCALL_EMU		9	/* syscall emulation active */
- #define TIF_POLLING_NRFLAG	16	/* true if poll_idle() is polling TIF_NEED_RESCHED */
- #define TIF_MEMDIE		17
- 
-Index: linux-2.6.14/include/asm-x86_64/desc.h
-===================================================================
---- linux-2.6.14.orig/include/asm-x86_64/desc.h	2005-10-29 05:49:27.000000000 +0200
-+++ linux-2.6.14/include/asm-x86_64/desc.h	2005-10-29 05:50:31.000000000 +0200
-@@ -215,6 +215,9 @@
- 
- extern struct desc_ptr idt_descr;
- 
-+extern int __modify_ldt(struct mm_struct * mm, int func, void __user *ptr,
-+		unsigned long bytecount);
-+
- #endif /* !__ASSEMBLY__ */
- 
- #endif
-Index: linux-2.6.14/include/asm-x86_64/mmu_context.h
-===================================================================
---- linux-2.6.14.orig/include/asm-x86_64/mmu_context.h	2005-10-29 05:49:27.000000000 +0200
-+++ linux-2.6.14/include/asm-x86_64/mmu_context.h	2005-10-29 05:50:31.000000000 +0200
-@@ -8,13 +8,28 @@
- #include <asm/pda.h>
- #include <asm/pgtable.h>
- #include <asm/tlbflush.h>
-+#include <asm/semaphore.h>
- 
- /*
-  * possibly do the LDT unload here?
-+ * Used for LDT initialization/destruction. You cannot copy an LDT with
-+ * init_new_context, since it thinks you are passing it a new LDT and won't
-+ * deallocate its old content.
-  */
-+
- int init_new_context(struct task_struct *tsk, struct mm_struct *mm);
- void destroy_context(struct mm_struct *mm);
- 
-+/* LDT initialization for a clean environment - needed for SKAS.*/
-+static inline void init_new_empty_context(struct mm_struct *mm)
-+{
-+	init_MUTEX(&mm->context.sem);
-+	mm->context.size = 0;
-+}
-+
-+/* LDT copy for SKAS - for the above problem.*/
-+int copy_context(struct mm_struct *mm, struct mm_struct *old_mm);
-+
- #ifdef CONFIG_SMP
- 
- static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
-@@ -37,6 +52,9 @@
- 			     struct task_struct *tsk)
- {
- 	unsigned cpu = smp_processor_id();
-+#ifdef CONFIG_SMP
-+	prev = read_pda(active_mm);
-+#endif
- 	if (likely(prev != next)) {
- 		/* stop flush ipis for the previous mm */
- 		clear_bit(cpu, &prev->cpu_vm_mask);
-@@ -53,8 +71,6 @@
- #ifdef CONFIG_SMP
- 	else {
- 		write_pda(mmu_state, TLBSTATE_OK);
--		if (read_pda(active_mm) != next)
--			out_of_line_bug();
- 		if(!test_and_set_bit(cpu, &next->cpu_vm_mask)) {
- 			/* We were in lazy tlb mode and leave_mm disabled 
- 			 * tlb flush IPI delivery. We must reload CR3
-Index: linux-2.6.14/include/asm-x86_64/proc_mm.h
-===================================================================
---- /dev/null	1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.14/include/asm-x86_64/proc_mm.h	2005-10-29 05:50:31.000000000 +0200
-@@ -0,0 +1,56 @@
-+#ifndef __ASM_PROC_MM
-+#define __ASM_PROC_MM
-+#include <linux/types.h>
-+
-+#include <asm/compat.h>
-+
-+struct mm_mmap32 {
-+	compat_ulong_t addr;
-+	compat_ulong_t len;
-+	compat_ulong_t prot;
-+	compat_ulong_t flags;
-+	compat_ulong_t fd;
-+	compat_ulong_t offset;
-+};
-+
-+struct mm_munmap32 {
-+	compat_ulong_t addr;
-+	compat_ulong_t len;
-+};
-+
-+struct mm_mprotect32 {
-+	compat_ulong_t addr;
-+	compat_ulong_t len;
-+        compat_uint_t prot;
-+};
-+
-+struct proc_mm_op32 {
-+	compat_int_t op;
-+	union {
-+		struct mm_mmap32 mmap;
-+		struct mm_munmap32 munmap;
-+	        struct mm_mprotect32 mprotect;
-+		compat_int_t copy_segments;
-+	} u;
-+};
-+
-+extern ssize_t write_proc_mm_emul(struct file *file, const char *buffer,
-+			     size_t count, loff_t *ppos);
-+
-+extern long do64_mmap(struct mm_struct *mm, unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags,
-+	unsigned long fd, unsigned long off);
-+
-+static inline long __do_mmap(struct mm_struct *mm, unsigned long addr,
-+		     unsigned long len, unsigned long prot,
-+		     unsigned long flags, unsigned long fd,
-+		     unsigned long off)
-+{
-+	/* The latter one is stricter, since will actually check that off is page
-+	 * aligned. The first one skipped the check. */
-+
-+	/* return do32_mmap2(mm, addr, len, prot, flags, fd, off >>
-+	 * PAGE_SHIFT);*/
-+	return do64_mmap(mm, addr, len, prot, flags, fd, off);
-+}
-+
-+#endif /* __ASM_PROC_MM */
-Index: linux-2.6.14/include/asm-x86_64/ptrace.h
-===================================================================
---- linux-2.6.14.orig/include/asm-x86_64/ptrace.h	2005-10-29 05:49:27.000000000 +0200
-+++ linux-2.6.14/include/asm-x86_64/ptrace.h	2005-10-29 05:50:34.000000000 +0200
-@@ -64,6 +64,59 @@
- /* top of stack page */ 
- };
- 
-+/* Stolen from
-+#include <linux/compat.h>; we can't include it because
-+there is a nasty ciclic include chain.
-+*/
-+
-+#include <asm/types.h>
-+
-+#define		compat_int_t	s32
-+#define		compat_long_t	s32
-+#define		compat_uint_t	u32
-+#define		compat_ulong_t	u32
-+#define		compat_uptr_t	u32
-+
-+struct ptrace_faultinfo32 {
-+	compat_int_t is_write;
-+	compat_ulong_t addr;
-+};
-+
-+struct ptrace_ex_faultinfo32 {
-+	compat_int_t is_write;
-+	compat_ulong_t addr;
-+	compat_int_t trap_no;
-+};
-+
-+struct ptrace_ldt32 {
-+	compat_int_t func;
-+	compat_uptr_t ptr; /*Actually a void pointer on i386, but must be converted.*/
-+	compat_ulong_t bytecount;
-+};
-+
-+struct ptrace_faultinfo {
-+	int is_write;
-+	unsigned long addr;
-+};
-+
-+struct ptrace_ex_faultinfo {
-+	int is_write;
-+	unsigned long addr;
-+	int trap_no;
-+};
-+
-+struct ptrace_ldt {
-+	int func;
-+  	void *ptr;
-+	unsigned long bytecount;
-+};
-+
-+#undef	compat_int_t
-+#undef	compat_long_t
-+#undef	compat_uint_t
-+#undef	compat_ulong_t
-+#undef	compat_uptr_t
-+
- #endif
- 
- /* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
-@@ -74,6 +127,12 @@
- #define PTRACE_GETFPXREGS         18
- #define PTRACE_SETFPXREGS         19
- 
-+#define PTRACE_FAULTINFO 52
-+/* 53 was used for PTRACE_SIGPENDING, don't reuse it. */
-+#define PTRACE_LDT 54
-+#define PTRACE_SWITCH_MM 55
-+#define PTRACE_EX_FAULTINFO	  56
-+
- /* only useful for access 32bit programs */
- #define PTRACE_GET_THREAD_AREA    25
- #define PTRACE_SET_THREAD_AREA    26
-Index: linux-2.6.14/include/linux/mm.h
-===================================================================
---- linux-2.6.14.orig/include/linux/mm.h	2005-10-29 05:49:33.000000000 +0200
-+++ linux-2.6.14/include/linux/mm.h	2005-10-29 05:50:00.000000000 +0200
-@@ -759,6 +759,9 @@
- extern struct shrinker *set_shrinker(int, shrinker_t);
- extern void remove_shrinker(struct shrinker *shrinker);
- 
-+extern long do_mprotect(struct mm_struct *mm, unsigned long start,
-+			size_t len, unsigned long prot);
-+
- /*
-  * On a two-level or three-level page table, this ends up being trivial. Thus
-  * the inlining and the symmetry break with pte_alloc_map() that does all
-@@ -841,9 +844,15 @@
- 
- extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
- 
--extern unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
-+extern unsigned long __do_mmap_pgoff(struct mm_struct *mm, struct file *file,
-+				   unsigned long addr, unsigned long len,
-+				   unsigned long prot, unsigned long flag,
-+				   unsigned long pgoff);
-+static inline unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
- 	unsigned long len, unsigned long prot,
--	unsigned long flag, unsigned long pgoff);
-+	unsigned long flag, unsigned long pgoff) {
-+	return __do_mmap_pgoff(current->mm, file, addr, len, prot, flag, pgoff);
-+}
- 
- static inline unsigned long do_mmap(struct file *file, unsigned long addr,
- 	unsigned long len, unsigned long prot,
-Index: linux-2.6.14/include/linux/proc_mm.h
-===================================================================
---- /dev/null	1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.14/include/linux/proc_mm.h	2005-10-29 05:50:33.000000000 +0200
-@@ -0,0 +1,114 @@
-+/*
-+ * Copyright (C) 2002 Jeff Dike (jdike at karaya.com)
-+ * Licensed under the GPL
-+ */
-+
-+#ifndef __PROC_MM_H
-+#define __PROC_MM_H
-+
-+#include <linux/config.h>
-+#include <linux/sched.h>
-+#include <linux/compiler.h>
-+
-+/* The differences between this one and do_mmap are that:
-+ * - we must perform controls for userspace-supplied params (which are
-+ *   arch-specific currently). And also fget(fd) if needed and so on...
-+ * - we must accept the struct mm_struct on which to act as first param, and the
-+ *   offset in byte rather than page units as last param.
-+ */
-+static inline long __do_mmap(struct mm_struct *mm, unsigned long addr,
-+		     unsigned long len, unsigned long prot,
-+		     unsigned long flags, unsigned long fd,
-+		     unsigned long off);
-+
-+/* This header can be used only on archs defining CONFIG_PROC_MM in their
-+ * configs, so asm/proc_mm.h can still exist only for the needed archs.
-+ * Including it only in the x86-64 case does not make sense.*/
-+#include <asm/proc_mm.h>
-+
-+/*XXX: this is defined on x86_64, but not on every 64-bit arch (not on sh64).*/
-+#ifdef CONFIG_64BIT
-+
-+#define write_proc_mm write_proc_mm_emul
-+#define write_proc_mm64 write_proc_mm_native
-+
-+/* It would make more sense to do this mapping the reverse direction, to map the
-+ * called name to the defined one and not the reverse. Like the 2nd example
-+ */
-+/*#define proc_mm_get_mm proc_mm_get_mm_emul
-+#define proc_mm_get_mm64 proc_mm_get_mm_native*/
-+
-+#define proc_mm_get_mm_emul proc_mm_get_mm
-+#define proc_mm_get_mm_native proc_mm_get_mm64
-+
-+#else
-+
-+#define write_proc_mm write_proc_mm_native
-+#undef write_proc_mm64
-+
-+/*#define proc_mm_get_mm proc_mm_get_mm_native
-+#undef proc_mm_get_mm64*/
-+
-+#define proc_mm_get_mm_native proc_mm_get_mm
-+#undef proc_mm_get_mm_emul
-+
-+#endif
-+
-+#define MM_MMAP 54
-+#define MM_MUNMAP 55
-+#define MM_MPROTECT 56
-+#define MM_COPY_SEGMENTS 57
-+
-+struct mm_mmap {
-+	unsigned long addr;
-+	unsigned long len;
-+	unsigned long prot;
-+	unsigned long flags;
-+	unsigned long fd;
-+	unsigned long offset;
-+};
-+
-+struct mm_munmap {
-+	unsigned long addr;
-+	unsigned long len;
-+};
-+
-+struct mm_mprotect {
-+	unsigned long addr;
-+	unsigned long len;
-+        unsigned int prot;
-+};
-+
-+struct proc_mm_op {
-+	int op;
-+	union {
-+		struct mm_mmap mmap;
-+		struct mm_munmap munmap;
-+	        struct mm_mprotect mprotect;
-+		int copy_segments;
-+	} u;
-+};
-+
-+extern struct mm_struct *proc_mm_get_mm(int fd);
-+
-+/* Cope with older kernels */
-+#ifndef __acquires
-+#define __acquires(x)
-+#endif
-+
-+#ifdef CONFIG_PROC_MM_DUMPABLE
-+/*
-+ * Since we take task_lock of child and it's needed also by the caller, we
-+ * return with it locked.
-+ */
-+extern void lock_fix_dumpable_setting(struct task_struct * child,
-+		struct mm_struct* new) __acquires(child->alloc_lock);
-+#else
-+static inline void lock_fix_dumpable_setting(struct task_struct * child,
-+		struct mm_struct* new) __acquires(child->alloc_lock)
-+{
-+	task_lock(child);
-+}
-+#endif
-+
-+#endif
-Index: linux-2.6.14/localversion-skas
-===================================================================
---- /dev/null	1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.14/localversion-skas	2005-10-29 05:50:35.000000000 +0200
-@@ -0,0 +1 @@
-+-skas3-v9-pre7
-Index: linux-2.6.14/mm/Makefile
-===================================================================
---- linux-2.6.14.orig/mm/Makefile	2005-10-29 05:49:32.000000000 +0200
-+++ linux-2.6.14/mm/Makefile	2005-10-29 05:50:34.000000000 +0200
-@@ -20,3 +20,9 @@
- obj-$(CONFIG_TINY_SHMEM) += tiny-shmem.o
- 
- obj-$(CONFIG_FS_XIP) += filemap_xip.o
-+
-+obj-$(CONFIG_PROC_MM)	+= proc_mm.o
-+
-+ifeq ($(CONFIG_PROC_MM),y)
-+obj-m			+= proc_mm-mod.o
-+endif
-Index: linux-2.6.14/mm/mmap.c
-===================================================================
---- linux-2.6.14.orig/mm/mmap.c	2005-10-29 05:49:32.000000000 +0200
-+++ linux-2.6.14/mm/mmap.c	2005-10-29 05:50:00.000000000 +0200
-@@ -861,11 +861,11 @@
-  * The caller must hold down_write(current->mm->mmap_sem).
-  */
- 
--unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
--			unsigned long len, unsigned long prot,
--			unsigned long flags, unsigned long pgoff)
-+unsigned long __do_mmap_pgoff(struct mm_struct *mm, struct file * file,
-+			    unsigned long addr, unsigned long len,
-+			    unsigned long prot, unsigned long flags,
-+			    unsigned long pgoff)
- {
--	struct mm_struct * mm = current->mm;
- 	struct vm_area_struct * vma, * prev;
- 	struct inode *inode;
- 	unsigned int vm_flags;
-@@ -1140,7 +1140,7 @@
- 	return error;
- }
- 
--EXPORT_SYMBOL(do_mmap_pgoff);
-+EXPORT_SYMBOL(__do_mmap_pgoff);
- 
- /* Get an address range which is currently unmapped.
-  * For shmat() with addr=0.
-Index: linux-2.6.14/mm/mprotect.c
-===================================================================
---- linux-2.6.14.orig/mm/mprotect.c	2005-10-29 05:49:32.000000000 +0200
-+++ linux-2.6.14/mm/mprotect.c	2005-10-29 05:50:30.000000000 +0200
-@@ -177,8 +177,9 @@
- 	return error;
- }
- 
--asmlinkage long
--sys_mprotect(unsigned long start, size_t len, unsigned long prot)
-+long
-+do_mprotect(struct mm_struct *mm, unsigned long start, size_t len,
-+	     unsigned long prot)
- {
- 	unsigned long vm_flags, nstart, end, tmp, reqprot;
- 	struct vm_area_struct *vma, *prev;
-@@ -209,9 +210,9 @@
- 
- 	vm_flags = calc_vm_prot_bits(prot);
- 
--	down_write(&current->mm->mmap_sem);
-+	down_write(&mm->mmap_sem);
- 
--	vma = find_vma_prev(current->mm, start, &prev);
-+	vma = find_vma_prev(mm, start, &prev);
- 	error = -ENOMEM;
- 	if (!vma)
- 		goto out;
-@@ -278,6 +279,15 @@
- 		}
- 	}
- out:
--	up_write(&current->mm->mmap_sem);
-+	up_write(&mm->mmap_sem);
- 	return error;
- }
-+
-+asmlinkage long sys_mprotect(unsigned long start, size_t len, unsigned long prot)
-+{
-+	long ret = do_mprotect(current->mm, start, len, prot);
-+	/* A tail call would reorder parameters on the stack and they would then
-+	 * be restored at the wrong places. */
-+	prevent_tail_call(ret);
-+	return ret;
-+}
-Index: linux-2.6.14/mm/proc_mm.c
-===================================================================
---- /dev/null	1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.14/mm/proc_mm.c	2005-10-29 05:50:33.000000000 +0200
-@@ -0,0 +1,300 @@
-+/*
-+ * Copyright (C) 2002 Jeff Dike (jdike at karaya.com)
-+ * Licensed under the GPL
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/compiler.h>
-+#include <linux/mm.h>
-+#include <linux/init.h>
-+#include <linux/proc_fs.h>
-+#include <linux/proc_mm.h>
-+#include <linux/file.h>
-+#include <linux/mman.h>
-+#include <asm/uaccess.h>
-+#include <asm/mmu_context.h>
-+
-+#ifdef CONFIG_PROC_MM_DUMPABLE
-+/* Checks if a task must be considered dumpable
-+ *
-+ * XXX: copied from fs/proc/base.c, removed task_lock, added rmb(): this must be
-+ * called with task_lock(task) held. */
-+static int task_dumpable(struct task_struct *task)
-+{
-+	int dumpable = 0;
-+	struct mm_struct *mm;
-+
-+	mm = task->mm;
-+	if (mm) {
-+		rmb();
-+		dumpable = mm->dumpable;
-+	}
-+	return dumpable;
-+}
-+
-+/*
-+ * This is to be used in PTRACE_SWITCH_MM handling. We are going to set
-+ * child->mm to new, and we must first correctly set new->dumpable.
-+ * Since we take task_lock of child and it's needed also by the caller, we
-+ * return with it locked.
-+ */
-+void lock_fix_dumpable_setting(struct task_struct* child, struct mm_struct* new)
-+	__acquires(child->alloc_lock)
-+{
-+	int dumpable = 1;
-+
-+	/* We must be safe.
-+	 * If the child is ptraced from a non-dumpable process,
-+	 * let's not be dumpable. If the child is non-dumpable itself,
-+	 * copy this property across mm's.
-+	 *
-+	 * Don't try to be smart for the opposite case and turn
-+	 * child->mm->dumpable to 1: I've not made sure it is safe.
-+	 */
-+
-+	task_lock(current);
-+	if (unlikely(!task_dumpable(current))) {
-+		dumpable = 0;
-+	}
-+	task_unlock(current);
-+
-+	task_lock(child);
-+	if (likely(dumpable) && unlikely(!task_dumpable(child))) {
-+		dumpable = 0;
-+	}
-+
-+	if (!dumpable) {
-+		new->dumpable = 0;
-+		wmb();
-+	}
-+}
-+#endif
-+
-+/* Naming conventions are a mess, so I note them down.
-+ *
-+ * Things ending in _mm can be for everything. It's only for
-+ * {open,release}_proc_mm.
-+ *
-+ * For the rest:
-+ *
-+ * _mm means /proc/mm, _mm64 means /proc/mm64. This is for the infrastructure
-+ * only (for instance proc_mm_get_mm checks whether the file is /proc/mm or
-+ * /proc/mm64; for instance the /proc handling).
-+ *
-+ * While for what is conversion dependant, we use the suffix _native and _emul.
-+ * In some cases, there is a mapping between these ones (defined by
-+ * <asm/proc_mm.h>).
-+ */
-+
-+/*These two are common to everything.*/
-+static int open_proc_mm(struct inode *inode, struct file *file)
-+{
-+	struct mm_struct *mm = mm_alloc();
-+	int ret;
-+
-+	ret = -ENOMEM;
-+	if(mm == NULL)
-+		goto out_mem;
-+
-+	init_new_empty_context(mm);
-+	arch_pick_mmap_layout(mm);
-+#ifdef CONFIG_PROC_MM_DUMPABLE
-+	mm->dumpable = current->mm->dumpable;
-+	wmb();
-+#endif
-+
-+	file->private_data = mm;
-+
-+	return 0;
-+
-+out_mem:
-+	return ret;
-+}
-+
-+static int release_proc_mm(struct inode *inode, struct file *file)
-+{
-+	struct mm_struct *mm = file->private_data;
-+
-+	mmput(mm);
-+	return 0;
-+}
-+
-+static struct file_operations proc_mm_fops;
-+
-+struct mm_struct *proc_mm_get_mm_native(int fd);
-+
-+static ssize_t write_proc_mm_native(struct file *file, const char *buffer,
-+			     size_t count, loff_t *ppos)
-+{
-+	struct mm_struct *mm = file->private_data;
-+	struct proc_mm_op req;
-+	int n, ret;
-+
-+	if(count > sizeof(req))
-+		return(-EINVAL);
-+
-+	n = copy_from_user(&req, buffer, count);
-+	if(n != 0)
-+		return(-EFAULT);
-+
-+	ret = count;
-+	switch(req.op){
-+	case MM_MMAP: {
-+		struct mm_mmap *map = &req.u.mmap;
-+
-+		/* Nobody ever noticed it, but do_mmap_pgoff() calls
-+		 * get_unmapped_area() which checks current->mm, if
-+		 * MAP_FIXED is not set, so mmap() could replace
-+		 * an old mapping.
-+		 */
-+		if (! (map->flags & MAP_FIXED))
-+			return(-EINVAL);
-+
-+		ret = __do_mmap(mm, map->addr, map->len, map->prot,
-+			       map->flags, map->fd, map->offset);
-+		if((ret & ~PAGE_MASK) == 0)
-+			ret = count;
-+
-+		break;
-+	}
-+	case MM_MUNMAP: {
-+		struct mm_munmap *unmap = &req.u.munmap;
-+
-+		down_write(&mm->mmap_sem);
-+		ret = do_munmap(mm, unmap->addr, unmap->len);
-+		up_write(&mm->mmap_sem);
-+
-+		if(ret == 0)
-+			ret = count;
-+		break;
-+	}
-+	case MM_MPROTECT: {
-+		struct mm_mprotect *protect = &req.u.mprotect;
-+
-+		ret = do_mprotect(mm, protect->addr, protect->len,
-+				  protect->prot);
-+		if(ret == 0)
-+			ret = count;
-+		break;
-+	}
-+
-+	case MM_COPY_SEGMENTS: {
-+		struct mm_struct *from = proc_mm_get_mm_native(req.u.copy_segments);
-+
-+		if(IS_ERR(from)){
-+			ret = PTR_ERR(from);
-+			break;
-+		}
-+
-+		ret = copy_context(mm, from);
-+		if(ret == 0)
-+			ret = count;
-+		break;
-+	}
-+	default:
-+		ret = -EINVAL;
-+		break;
-+	}
-+
-+	return ret;
-+}
-+
-+/*These three are all for /proc/mm.*/
-+struct mm_struct *proc_mm_get_mm(int fd)
-+{
-+	struct mm_struct *ret = ERR_PTR(-EBADF);
-+	struct file *file;
-+
-+	file = fget(fd);
-+	if (!file)
-+		goto out;
-+
-+	ret = ERR_PTR(-EINVAL);
-+	if(file->f_op != &proc_mm_fops)
-+		goto out_fput;
-+
-+	ret = file->private_data;
-+out_fput:
-+	fput(file);
-+out:
-+	return(ret);
-+}
-+
-+static struct file_operations proc_mm_fops = {
-+	.open		= open_proc_mm,
-+	.release	= release_proc_mm,
-+	.write		= write_proc_mm,
-+};
-+
-+/*Macro-ify it to avoid the duplication.*/
-+static int make_proc_mm(void)
-+{
-+	struct proc_dir_entry *ent;
-+
-+	ent = create_proc_entry("mm", 0222, &proc_root);
-+	if(ent == NULL){
-+		printk("make_proc_mm : Failed to register /proc/mm\n");
-+		return(0);
-+	}
-+	ent->proc_fops = &proc_mm_fops;
-+
-+	return 0;
-+}
-+
-+__initcall(make_proc_mm);
-+
-+/*XXX: change the option.*/
-+#ifdef CONFIG_64BIT
-+static struct file_operations proc_mm64_fops = {
-+	.open		= open_proc_mm,
-+	.release	= release_proc_mm,
-+	.write		= write_proc_mm64,
-+};
-+
-+static int make_proc_mm64(void)
-+{
-+	struct proc_dir_entry *ent;
-+
-+	ent = create_proc_entry("mm64", 0222, &proc_root);
-+	if(ent == NULL){
-+		printk("make_proc_mm : Failed to register /proc/mm64\n");
-+		return(0);
-+	}
-+	ent->proc_fops = &proc_mm64_fops;
-+
-+	return 0;
-+}
-+
-+__initcall(make_proc_mm64);
-+
-+struct mm_struct *proc_mm_get_mm64(int fd)
-+{
-+	struct mm_struct *ret = ERR_PTR(-EBADF);
-+	struct file *file;
-+
-+	file = fget(fd);
-+	if (!file)
-+		goto out;
-+
-+	ret = ERR_PTR(-EINVAL);
-+	/*This is the only change.*/
-+	if(file->f_op != &proc_mm64_fops)
-+		goto out_fput;
-+
-+	ret = file->private_data;
-+out_fput:
-+	fput(file);
-+out:
-+	return(ret);
-+}
-+#endif
-+/*
-+ * Overrides for Emacs so that we follow Linus's tabbing style.
-+ * Emacs will notice this stuff at the end of the file and automatically
-+ * adjust the settings for this buffer only.  This must remain at the end
-+ * of the file.
-+ * ---------------------------------------------------------------------------
-+ * Local variables:
-+ * c-file-style: "linux"
-+ * End:
-+ */
-Index: linux-2.6.14/mm/proc_mm-mod.c
-===================================================================
---- /dev/null	1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.14/mm/proc_mm-mod.c	2005-10-29 05:50:34.000000000 +0200
-@@ -0,0 +1,51 @@
-+#include <linux/config.h>
-+#include <linux/kernel.h>
-+#include <linux/proc_mm.h>
-+#include <linux/ptrace.h>
-+#include <linux/module.h>
-+
-+#ifdef CONFIG_64BIT
-+#define PRINT_OFFSET(type, member) \
-+	printk(KERN_DEBUG "struct " #type "32->" #member " \t: %ld\n", (long) offsetof(struct type ## 32, member))
-+#else
-+#define PRINT_OFFSET(type, member) \
-+	printk(KERN_DEBUG "struct " #type "->" #member " \t: %ld\n", (long) offsetof(struct type, member))
-+#endif
-+
-+static int debug_printoffsets(void)
-+{
-+	printk(KERN_DEBUG "Skas core structures layout BEGIN:\n");
-+	PRINT_OFFSET(mm_mmap, addr);
-+	PRINT_OFFSET(mm_mmap, len);
-+	PRINT_OFFSET(mm_mmap, prot);
-+	PRINT_OFFSET(mm_mmap, flags);
-+	PRINT_OFFSET(mm_mmap, fd);
-+	PRINT_OFFSET(mm_mmap, offset);
-+
-+	PRINT_OFFSET(mm_munmap, addr);
-+	PRINT_OFFSET(mm_munmap, len);
-+
-+	PRINT_OFFSET(mm_mprotect, addr);
-+	PRINT_OFFSET(mm_mprotect, len);
-+	PRINT_OFFSET(mm_mprotect, prot);
-+
-+	PRINT_OFFSET(proc_mm_op, op);
-+	PRINT_OFFSET(proc_mm_op, u);
-+	PRINT_OFFSET(proc_mm_op, u.mmap);
-+	PRINT_OFFSET(proc_mm_op, u.munmap);
-+	PRINT_OFFSET(proc_mm_op, u.mprotect);
-+	PRINT_OFFSET(proc_mm_op, u.copy_segments);
-+
-+	PRINT_OFFSET(ptrace_faultinfo, is_write);
-+	PRINT_OFFSET(ptrace_faultinfo, addr);
-+
-+	PRINT_OFFSET(ptrace_ldt, func);
-+	PRINT_OFFSET(ptrace_ldt, ptr);
-+	PRINT_OFFSET(ptrace_ldt, bytecount);
-+	printk(KERN_DEBUG "Skas core structures layout END.\n");
-+
-+	return 0;
-+}
-+#undef PRINT_OFFSET
-+
-+module_init(debug_printoffsets);

Deleted: trunk/src/kernel-patch-skas/skas-2.6.15-v9-pre8.patch
===================================================================
--- trunk/src/kernel-patch-skas/skas-2.6.15-v9-pre8.patch	2006-08-27 15:01:30 UTC (rev 166)
+++ trunk/src/kernel-patch-skas/skas-2.6.15-v9-pre8.patch	2006-08-27 15:16:57 UTC (rev 167)
@@ -1,1860 +0,0 @@
-Index: linux-2.6.15/arch/i386/Kconfig
-===================================================================
---- linux-2.6.15.orig/arch/i386/Kconfig
-+++ linux-2.6.15/arch/i386/Kconfig
-@@ -458,6 +458,26 @@ config X86_PAE
- 	depends on HIGHMEM64G
- 	default y
- 
-+config PROC_MM
-+	bool "/proc/mm support"
-+	default y
-+
-+config PROC_MM_DUMPABLE
-+	bool "Make UML childs /proc/<pid> completely browsable"
-+	default n
-+	help
-+	  If in doubt, say N.
-+
-+	  This fiddles with some settings to make sure /proc/<pid> is completely
-+	  browsable by who started UML, at the expense of some additional
-+	  locking (maybe this could slow down the runned UMLs of a few percents,
-+	  I've not tested this).
-+
-+	  Also, if there is a bug in this feature, there is some little
-+	  possibility to do privilege escalation if you have UML installed
-+	  setuid (which you shouldn't have done) or if UML changes uid on
-+	  startup (which will be a good thing, when enabled) ...
-+
- # Common NUMA Features
- config NUMA
- 	bool "Numa Memory Allocation and Scheduler Support"
-Index: linux-2.6.15/arch/i386/kernel/ldt.c
-===================================================================
---- linux-2.6.15.orig/arch/i386/kernel/ldt.c
-+++ linux-2.6.15/arch/i386/kernel/ldt.c
-@@ -28,11 +28,12 @@ static void flush_ldt(void *null)
- }
- #endif
- 
--static int alloc_ldt(mm_context_t *pc, int mincount, int reload)
-+static int alloc_ldt(struct mm_struct *mm, int mincount, int reload)
- {
- 	void *oldldt;
- 	void *newldt;
- 	int oldsize;
-+	mm_context_t * pc = &mm->context;
- 
- 	if (mincount <= pc->size)
- 		return 0;
-@@ -59,13 +60,15 @@ static int alloc_ldt(mm_context_t *pc, i
- #ifdef CONFIG_SMP
- 		cpumask_t mask;
- 		preempt_disable();
--		load_LDT(pc);
-+		if (&current->active_mm->context == pc)
-+			load_LDT(pc);
- 		mask = cpumask_of_cpu(smp_processor_id());
--		if (!cpus_equal(current->mm->cpu_vm_mask, mask))
-+		if (!cpus_equal(mm->cpu_vm_mask, mask))
- 			smp_call_function(flush_ldt, NULL, 1, 1);
- 		preempt_enable();
- #else
--		load_LDT(pc);
-+		if (&current->active_mm->context == pc)
-+			load_LDT(pc);
- #endif
- 	}
- 	if (oldsize) {
-@@ -77,12 +80,12 @@ static int alloc_ldt(mm_context_t *pc, i
- 	return 0;
- }
- 
--static inline int copy_ldt(mm_context_t *new, mm_context_t *old)
-+static inline int copy_ldt(struct mm_struct *new, struct mm_struct *old)
- {
--	int err = alloc_ldt(new, old->size, 0);
-+	int err = alloc_ldt(new, old->context.size, 0);
- 	if (err < 0)
- 		return err;
--	memcpy(new->ldt, old->ldt, old->size*LDT_ENTRY_SIZE);
-+	memcpy(new->context.ldt, old->context.ldt, old->context.size*LDT_ENTRY_SIZE);
- 	return 0;
- }
- 
-@@ -90,22 +93,24 @@ static inline int copy_ldt(mm_context_t 
-  * we do not have to muck with descriptors here, that is
-  * done in switch_mm() as needed.
-  */
--int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
-+int copy_context(struct mm_struct *mm, struct mm_struct *old_mm)
- {
--	struct mm_struct * old_mm;
- 	int retval = 0;
- 
--	init_MUTEX(&mm->context.sem);
--	mm->context.size = 0;
--	old_mm = current->mm;
- 	if (old_mm && old_mm->context.size > 0) {
- 		down(&old_mm->context.sem);
--		retval = copy_ldt(&mm->context, &old_mm->context);
-+		retval = copy_ldt(mm, old_mm);
- 		up(&old_mm->context.sem);
- 	}
- 	return retval;
- }
- 
-+int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
-+{
-+	init_new_empty_context(mm);
-+	return copy_context(mm, current->mm);
-+}
-+
- /*
-  * No need to lock the MM as we are the last user
-  */
-@@ -122,11 +127,11 @@ void destroy_context(struct mm_struct *m
- 	}
- }
- 
--static int read_ldt(void __user * ptr, unsigned long bytecount)
-+static int read_ldt(struct mm_struct * mm, void __user * ptr,
-+		    unsigned long bytecount)
- {
- 	int err;
- 	unsigned long size;
--	struct mm_struct * mm = current->mm;
- 
- 	if (!mm->context.size)
- 		return 0;
-@@ -175,9 +180,8 @@ static int read_default_ldt(void __user 
- 	return err;
- }
- 
--static int write_ldt(void __user * ptr, unsigned long bytecount, int oldmode)
-+static int write_ldt(struct mm_struct * mm, void __user * ptr, unsigned long bytecount, int oldmode)
- {
--	struct mm_struct * mm = current->mm;
- 	__u32 entry_1, entry_2;
- 	int error;
- 	struct user_desc ldt_info;
-@@ -201,7 +205,7 @@ static int write_ldt(void __user * ptr, 
- 
- 	down(&mm->context.sem);
- 	if (ldt_info.entry_number >= mm->context.size) {
--		error = alloc_ldt(&current->mm->context, ldt_info.entry_number+1, 1);
-+		error = alloc_ldt(mm, ldt_info.entry_number+1, 1);
- 		if (error < 0)
- 			goto out_unlock;
- 	}
-@@ -231,23 +235,33 @@ out:
- 	return error;
- }
- 
--asmlinkage int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
-+int __modify_ldt(struct mm_struct * mm, int func, void __user *ptr,
-+	       unsigned long bytecount)
- {
- 	int ret = -ENOSYS;
- 
- 	switch (func) {
- 	case 0:
--		ret = read_ldt(ptr, bytecount);
-+		ret = read_ldt(mm, ptr, bytecount);
- 		break;
- 	case 1:
--		ret = write_ldt(ptr, bytecount, 1);
-+		ret = write_ldt(mm, ptr, bytecount, 1);
- 		break;
- 	case 2:
- 		ret = read_default_ldt(ptr, bytecount);
- 		break;
- 	case 0x11:
--		ret = write_ldt(ptr, bytecount, 0);
-+		ret = write_ldt(mm, ptr, bytecount, 0);
- 		break;
- 	}
- 	return ret;
- }
-+
-+asmlinkage int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
-+{
-+	int ret = __modify_ldt(current->mm, func, ptr, bytecount);
-+	/* A tail call would reorder parameters on the stack and they would then
-+	 * be restored at the wrong places. */
-+	prevent_tail_call(ret);
-+	return ret;
-+}
-Index: linux-2.6.15/arch/i386/kernel/ptrace.c
-===================================================================
---- linux-2.6.15.orig/arch/i386/kernel/ptrace.c
-+++ linux-2.6.15/arch/i386/kernel/ptrace.c
-@@ -17,6 +17,7 @@
- #include <linux/audit.h>
- #include <linux/seccomp.h>
- #include <linux/signal.h>
-+#include <linux/proc_mm.h>
- 
- #include <asm/uaccess.h>
- #include <asm/pgtable.h>
-@@ -622,6 +623,66 @@ long arch_ptrace(struct task_struct *chi
- 					(struct user_desc __user *) data);
- 		break;
- 
-+#ifdef CONFIG_PROC_MM
-+	case PTRACE_EX_FAULTINFO: {
-+		struct ptrace_ex_faultinfo fault;
-+
-+		fault = ((struct ptrace_ex_faultinfo)
-+			{ .is_write	= child->thread.error_code,
-+			  .addr		= child->thread.cr2,
-+			  .trap_no	= child->thread.trap_no });
-+		ret = copy_to_user((unsigned long *) data, &fault,
-+				   sizeof(fault));
-+		break;
-+	}
-+
-+	case PTRACE_FAULTINFO: {
-+		struct ptrace_faultinfo fault;
-+
-+		fault = ((struct ptrace_faultinfo)
-+			{ .is_write	= child->thread.error_code,
-+			  .addr		= child->thread.cr2 });
-+		ret = copy_to_user((unsigned long *) data, &fault,
-+				   sizeof(fault));
-+		break;
-+	}
-+
-+	case PTRACE_LDT: {
-+		struct ptrace_ldt ldt;
-+
-+		if(copy_from_user(&ldt, (unsigned long *) data,
-+				  sizeof(ldt))){
-+			ret = -EIO;
-+			break;
-+		}
-+		ret = __modify_ldt(child->mm, ldt.func, ldt.ptr, ldt.bytecount);
-+		break;
-+	}
-+
-+	case PTRACE_SWITCH_MM: {
-+		struct mm_struct *old = child->mm;
-+		struct mm_struct *new = proc_mm_get_mm(data);
-+
-+		if(IS_ERR(new)){
-+			ret = PTR_ERR(new);
-+			break;
-+		}
-+
-+		atomic_inc(&new->mm_users);
-+
-+		lock_fix_dumpable_setting(child, new);
-+
-+		child->mm = new;
-+		child->active_mm = new;
-+
-+		task_unlock(child);
-+
-+		mmput(old);
-+		ret = 0;
-+		break;
-+	}
-+#endif
-+
- 	default:
- 		ret = ptrace_request(child, request, addr, data);
- 		break;
-Index: linux-2.6.15/arch/i386/kernel/sys_i386.c
-===================================================================
---- linux-2.6.15.orig/arch/i386/kernel/sys_i386.c
-+++ linux-2.6.15/arch/i386/kernel/sys_i386.c
-@@ -41,7 +41,7 @@ asmlinkage int sys_pipe(unsigned long __
- }
- 
- /* common code for old and new mmaps */
--static inline long do_mmap2(
-+long do_mmap2(struct mm_struct *mm,
- 	unsigned long addr, unsigned long len,
- 	unsigned long prot, unsigned long flags,
- 	unsigned long fd, unsigned long pgoff)
-@@ -56,9 +56,9 @@ static inline long do_mmap2(
- 			goto out;
- 	}
- 
--	down_write(&current->mm->mmap_sem);
--	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
--	up_write(&current->mm->mmap_sem);
-+	down_write(&mm->mmap_sem);
-+	error = __do_mmap_pgoff(mm, file, addr, len, prot, flags, pgoff);
-+	up_write(&mm->mmap_sem);
- 
- 	if (file)
- 		fput(file);
-@@ -70,7 +70,12 @@ asmlinkage long sys_mmap2(unsigned long 
- 	unsigned long prot, unsigned long flags,
- 	unsigned long fd, unsigned long pgoff)
- {
--	return do_mmap2(addr, len, prot, flags, fd, pgoff);
-+	long ret = do_mmap2(current->mm, addr, len, prot, flags, fd, pgoff);
-+
-+	/* A tail call would reorder parameters on the stack and they would then
-+	 * be restored at the wrong places. */
-+	prevent_tail_call(ret);
-+	return ret;
- }
- 
- /*
-@@ -101,7 +106,10 @@ asmlinkage int old_mmap(struct mmap_arg_
- 	if (a.offset & ~PAGE_MASK)
- 		goto out;
- 
--	err = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
-+	err = do_mmap2(current->mm, a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
-+	/* A tail call would reorder parameters on the stack and they would then
-+	 * be restored at the wrong places. */
-+	prevent_tail_call(err);
- out:
- 	return err;
- }
-Index: linux-2.6.15/arch/um/include/skas_ptrace.h
-===================================================================
---- linux-2.6.15.orig/arch/um/include/skas_ptrace.h
-+++ linux-2.6.15/arch/um/include/skas_ptrace.h
-@@ -6,6 +6,8 @@
- #ifndef __SKAS_PTRACE_H
- #define __SKAS_PTRACE_H
- 
-+#ifndef PTRACE_FAULTINFO
-+
- #define PTRACE_FAULTINFO 52
- #define PTRACE_SWITCH_MM 55
- 
-@@ -13,6 +15,8 @@
- 
- #endif
- 
-+#endif
-+
- /*
-  * Overrides for Emacs so that we follow Linus's tabbing style.
-  * Emacs will notice this stuff at the end of the file and automatically
-Index: linux-2.6.15/arch/x86_64/ia32/ptrace32.c
-===================================================================
---- linux-2.6.15.orig/arch/x86_64/ia32/ptrace32.c
-+++ linux-2.6.15/arch/x86_64/ia32/ptrace32.c
-@@ -18,6 +18,8 @@
- #include <linux/unistd.h>
- #include <linux/mm.h>
- #include <linux/ptrace.h>
-+#include <linux/types.h>
-+#include <linux/proc_mm.h>
- #include <asm/ptrace.h>
- #include <asm/compat.h>
- #include <asm/uaccess.h>
-@@ -27,6 +29,7 @@
- #include <asm/debugreg.h>
- #include <asm/i387.h>
- #include <asm/fpu32.h>
-+#include <asm/desc.h>
- 
- /* determines which flags the user has access to. */
- /* 1 = access 0 = no access */
-@@ -251,6 +254,11 @@ asmlinkage long sys32_ptrace(long reques
- 	case PTRACE_SETFPXREGS:
- 	case PTRACE_GETFPXREGS:
- 	case PTRACE_GETEVENTMSG:
-+#ifdef CONFIG_PROC_MM
-+	case PTRACE_FAULTINFO:
-+	case PTRACE_LDT:
-+	case PTRACE_SWITCH_MM:
-+#endif
- 		break;
- 	} 
- 
-@@ -363,6 +371,65 @@ asmlinkage long sys32_ptrace(long reques
- 		ret = 0; 
- 		break;
- 	}
-+#ifdef CONFIG_PROC_MM
-+	case PTRACE_EX_FAULTINFO: {
-+		struct ptrace_ex_faultinfo32 fault;
-+
-+		fault = ((struct ptrace_ex_faultinfo32)
-+			{ .is_write	= (compat_int_t) child->thread.error_code,
-+			  .addr		= (compat_uptr_t) child->thread.cr2,
-+			  .trap_no	= (compat_int_t) child->thread.trap_no });
-+		ret = copy_to_user((unsigned long *) datap, &fault,
-+				   sizeof(fault));
-+		break;
-+	}
-+
-+	case PTRACE_FAULTINFO: {
-+		struct ptrace_faultinfo32 fault;
-+
-+		fault = ((struct ptrace_faultinfo32)
-+			{ .is_write	= (compat_int_t) child->thread.error_code,
-+			  .addr		= (compat_uptr_t) child->thread.cr2 });
-+		ret = copy_to_user((unsigned long *) datap, &fault,
-+				   sizeof(fault));
-+		break;
-+	}
-+
-+	case PTRACE_LDT: {
-+		struct ptrace_ldt32 ldt;
-+
-+		if(copy_from_user(&ldt, (unsigned long *) datap,
-+				  sizeof(ldt))){
-+			ret = -EIO;
-+			break;
-+		}
-+		ret = __modify_ldt(child->mm, ldt.func, compat_ptr(ldt.ptr), ldt.bytecount);
-+		break;
-+	}
-+
-+	case PTRACE_SWITCH_MM: {
-+		struct mm_struct *old = child->mm;
-+		struct mm_struct *new = proc_mm_get_mm(data);
-+
-+		if(IS_ERR(new)){
-+			ret = PTR_ERR(new);
-+			break;
-+		}
-+
-+		atomic_inc(&new->mm_users);
-+
-+		lock_fix_dumpable_setting(child, new);
-+
-+		child->mm = new;
-+		child->active_mm = new;
-+
-+		task_unlock(child);
-+
-+		mmput(old);
-+		ret = 0;
-+		break;
-+	}
-+#endif
- 
- 	case PTRACE_GETEVENTMSG:
- 		ret = put_user(child->ptrace_message,(unsigned int __user *)compat_ptr(data));
-Index: linux-2.6.15/arch/x86_64/ia32/sys_ia32.c
-===================================================================
---- linux-2.6.15.orig/arch/x86_64/ia32/sys_ia32.c
-+++ linux-2.6.15/arch/x86_64/ia32/sys_ia32.c
-@@ -833,11 +833,10 @@ sys32_adjtimex(struct timex32 __user *ut
- 	return ret;
- }
- 
--asmlinkage long sys32_mmap2(unsigned long addr, unsigned long len,
--	unsigned long prot, unsigned long flags,
-+long do32_mmap2(struct mm_struct *mm, unsigned long addr,
-+	unsigned long len, unsigned long prot, unsigned long flags,
- 	unsigned long fd, unsigned long pgoff)
- {
--	struct mm_struct *mm = current->mm;
- 	unsigned long error;
- 	struct file * file = NULL;
- 
-@@ -849,7 +848,7 @@ asmlinkage long sys32_mmap2(unsigned lon
- 	}
- 
- 	down_write(&mm->mmap_sem);
--	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-+	error = __do_mmap_pgoff(mm, file, addr, len, prot, flags, pgoff);
- 	up_write(&mm->mmap_sem);
- 
- 	if (file)
-@@ -857,6 +856,15 @@ asmlinkage long sys32_mmap2(unsigned lon
- 	return error;
- }
- 
-+/* XXX: this wrapper can be probably removed, we can simply use the 64-bit
-+ * version.*/
-+asmlinkage long sys32_mmap2(unsigned long addr, unsigned long len,
-+	unsigned long prot, unsigned long flags,
-+	unsigned long fd, unsigned long pgoff)
-+{
-+	return do32_mmap2(current->mm, addr, len, prot, flags, fd, pgoff);
-+}
-+
- asmlinkage long sys32_olduname(struct oldold_utsname __user * name)
- {
- 	int error;
-Index: linux-2.6.15/arch/x86_64/Kconfig
-===================================================================
---- linux-2.6.15.orig/arch/x86_64/Kconfig
-+++ linux-2.6.15/arch/x86_64/Kconfig
-@@ -374,6 +374,26 @@ config DUMMY_IOMMU
- 	  of memory and any 32-bit devices. Don't turn on unless you know what you
- 	  are doing.
- 
-+config PROC_MM
-+	bool "/proc/mm support"
-+	default y
-+
-+config PROC_MM_DUMPABLE
-+	bool "Make UML childs /proc/<pid> completely browsable"
-+	default n
-+	help
-+	  If in doubt, say N.
-+
-+	  This fiddles with some settings to make sure /proc/<pid> is completely
-+	  browsable by who started UML, at the expense of some additional
-+	  locking (maybe this could slow down the runned UMLs of a few percents,
-+	  I've not tested this).
-+
-+	  Also, if there is a bug in this feature, there is some little
-+	  possibility to do privilege escalation if you have UML installed
-+	  setuid (which you shouldn't have done) or if UML changes uid on
-+	  startup (which will be a good thing, when enabled) ...
-+
- config X86_MCE
- 	bool "Machine check support" if EMBEDDED
- 	default y
-Index: linux-2.6.15/arch/x86_64/kernel/ldt.c
-===================================================================
---- linux-2.6.15.orig/arch/x86_64/kernel/ldt.c
-+++ linux-2.6.15/arch/x86_64/kernel/ldt.c
-@@ -22,6 +22,7 @@
- #include <asm/ldt.h>
- #include <asm/desc.h>
- #include <asm/proto.h>
-+#include <asm/mmu_context.h>
- 
- #ifdef CONFIG_SMP /* avoids "defined but not used" warnig */
- static void flush_ldt(void *null)
-@@ -31,11 +32,12 @@ static void flush_ldt(void *null)
- }
- #endif
- 
--static int alloc_ldt(mm_context_t *pc, unsigned mincount, int reload)
-+static int alloc_ldt(struct mm_struct *mm, unsigned mincount, int reload)
- {
- 	void *oldldt;
- 	void *newldt;
- 	unsigned oldsize;
-+	mm_context_t * pc = &mm->context;
- 
- 	if (mincount <= (unsigned)pc->size)
- 		return 0;
-@@ -64,12 +66,14 @@ static int alloc_ldt(mm_context_t *pc, u
- 
- 		preempt_disable();
- 		mask = cpumask_of_cpu(smp_processor_id());
--		load_LDT(pc);
--		if (!cpus_equal(current->mm->cpu_vm_mask, mask))
-+		if (&current->active_mm->context == pc)
-+			load_LDT(pc);
-+		if (!cpus_equal(mm->cpu_vm_mask, mask))
- 			smp_call_function(flush_ldt, NULL, 1, 1);
- 		preempt_enable();
- #else
--		load_LDT(pc);
-+		if (&current->active_mm->context == pc)
-+			load_LDT(pc);
- #endif
- 	}
- 	if (oldsize) {
-@@ -81,12 +85,12 @@ static int alloc_ldt(mm_context_t *pc, u
- 	return 0;
- }
- 
--static inline int copy_ldt(mm_context_t *new, mm_context_t *old)
-+static inline int copy_ldt(struct mm_struct *new, struct mm_struct *old)
- {
--	int err = alloc_ldt(new, old->size, 0);
-+	int err = alloc_ldt(new, old->context.size, 0);
- 	if (err < 0)
- 		return err;
--	memcpy(new->ldt, old->ldt, old->size*LDT_ENTRY_SIZE);
-+	memcpy(new->context.ldt, old->context.ldt, old->context.size*LDT_ENTRY_SIZE);
- 	return 0;
- }
- 
-@@ -94,22 +98,24 @@ static inline int copy_ldt(mm_context_t 
-  * we do not have to muck with descriptors here, that is
-  * done in switch_mm() as needed.
-  */
--int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
-+int copy_context(struct mm_struct *mm, struct mm_struct *old_mm)
- {
--	struct mm_struct * old_mm;
- 	int retval = 0;
- 
--	init_MUTEX(&mm->context.sem);
--	mm->context.size = 0;
--	old_mm = current->mm;
- 	if (old_mm && old_mm->context.size > 0) {
- 		down(&old_mm->context.sem);
--		retval = copy_ldt(&mm->context, &old_mm->context);
-+		retval = copy_ldt(mm, old_mm);
- 		up(&old_mm->context.sem);
- 	}
- 	return retval;
- }
- 
-+int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
-+{
-+	init_new_empty_context(mm);
-+	return copy_context(mm, current->mm);
-+}
-+
- /*
-  * 
-  * Don't touch the LDT register - we're already in the next thread.
-@@ -125,11 +131,10 @@ void destroy_context(struct mm_struct *m
- 	}
- }
- 
--static int read_ldt(void __user * ptr, unsigned long bytecount)
-+static int read_ldt(struct mm_struct * mm, void __user * ptr, unsigned long bytecount)
- {
- 	int err;
- 	unsigned long size;
--	struct mm_struct * mm = current->mm;
- 
- 	if (!mm->context.size)
- 		return 0;
-@@ -170,10 +175,8 @@ static int read_default_ldt(void __user 
- 	return bytecount; 
- }
- 
--static int write_ldt(void __user * ptr, unsigned long bytecount, int oldmode)
-+static int write_ldt(struct mm_struct * mm, void __user * ptr, unsigned long bytecount, int oldmode)
- {
--	struct task_struct *me = current;
--	struct mm_struct * mm = me->mm;
- 	__u32 entry_1, entry_2, *lp;
- 	int error;
- 	struct user_desc ldt_info;
-@@ -198,7 +201,7 @@ static int write_ldt(void __user * ptr, 
- 
- 	down(&mm->context.sem);
- 	if (ldt_info.entry_number >= (unsigned)mm->context.size) {
--		error = alloc_ldt(&current->mm->context, ldt_info.entry_number+1, 1);
-+		error = alloc_ldt(mm, ldt_info.entry_number+1, 1);
- 		if (error < 0)
- 			goto out_unlock;
- 	}
-@@ -231,23 +234,29 @@ out:
- 	return error;
- }
- 
--asmlinkage int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
-+int __modify_ldt(struct mm_struct * mm, int func, void __user *ptr,
-+		unsigned long bytecount)
- {
- 	int ret = -ENOSYS;
- 
- 	switch (func) {
- 	case 0:
--		ret = read_ldt(ptr, bytecount);
-+		ret = read_ldt(mm, ptr, bytecount);
- 		break;
- 	case 1:
--		ret = write_ldt(ptr, bytecount, 1);
-+		ret = write_ldt(mm, ptr, bytecount, 1);
- 		break;
- 	case 2:
- 		ret = read_default_ldt(ptr, bytecount);
- 		break;
- 	case 0x11:
--		ret = write_ldt(ptr, bytecount, 0);
-+		ret = write_ldt(mm, ptr, bytecount, 0);
- 		break;
- 	}
- 	return ret;
- }
-+
-+asmlinkage int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
-+{
-+	return __modify_ldt(current->mm, func, ptr, bytecount);
-+}
-Index: linux-2.6.15/arch/x86_64/kernel/ptrace.c
-===================================================================
---- linux-2.6.15.orig/arch/x86_64/kernel/ptrace.c
-+++ linux-2.6.15/arch/x86_64/kernel/ptrace.c
-@@ -19,6 +19,7 @@
- #include <linux/audit.h>
- #include <linux/seccomp.h>
- #include <linux/signal.h>
-+#include <linux/proc_mm.h>
- 
- #include <asm/uaccess.h>
- #include <asm/pgtable.h>
-@@ -567,6 +568,75 @@ long arch_ptrace(struct task_struct *chi
- 		break;
- 	}
- 
-+#ifdef CONFIG_PROC_MM
-+	case PTRACE_EX_FAULTINFO: {
-+		struct ptrace_ex_faultinfo fault;
-+
-+		/* I checked in thread_struct comments that error_code and cr2
-+		 * are still part of the "fault info" section, so I guess that
-+		 * things are unchanged for now. Still to check manuals. BB*/
-+		fault = ((struct ptrace_ex_faultinfo)
-+			{ .is_write	= child->thread.error_code,
-+			  .addr		= child->thread.cr2,
-+			  .trap_no	= child->thread.trap_no });
-+		ret = copy_to_user((unsigned long *) data, &fault,
-+				   sizeof(fault));
-+		break;
-+	}
-+
-+	/*Don't extend this broken interface to x86-64*/
-+#if 0
-+	case PTRACE_FAULTINFO: {
-+		struct ptrace_faultinfo fault;
-+
-+		/* I checked in thread_struct comments that error_code and cr2
-+		 * are still part of the "fault info" section, so I guess that
-+		 * things are unchanged for now. Still to check manuals. BB*/
-+		fault = ((struct ptrace_faultinfo)
-+			{ .is_write	= child->thread.error_code,
-+			  .addr		= child->thread.cr2 });
-+		ret = copy_to_user((unsigned long *) data, &fault,
-+				   sizeof(fault));
-+		break;
-+	}
-+#endif
-+
-+	case PTRACE_LDT: {
-+		struct ptrace_ldt ldt;
-+
-+		if(copy_from_user(&ldt, (unsigned long *) data,
-+				  sizeof(ldt))){
-+			ret = -EIO;
-+			break;
-+		}
-+		ret = __modify_ldt(child->mm, ldt.func, ldt.ptr, ldt.bytecount);
-+		break;
-+	}
-+
-+	case PTRACE_SWITCH_MM: {
-+		struct mm_struct *old = child->mm;
-+		struct mm_struct *new = proc_mm_get_mm64(data);
-+
-+		if(IS_ERR(new)){
-+			ret = PTR_ERR(new);
-+			break;
-+		}
-+
-+		atomic_inc(&new->mm_users);
-+
-+		lock_fix_dumpable_setting(child, new);
-+
-+		child->mm = new;
-+		child->active_mm = new;
-+
-+		task_unlock(child);
-+
-+		mmput(old);
-+		ret = 0;
-+		break;
-+	}
-+#endif
-+
- 	default:
- 		ret = ptrace_request(child, request, addr, data);
- 		break;
-Index: linux-2.6.15/arch/x86_64/kernel/sys_x86_64.c
-===================================================================
---- linux-2.6.15.orig/arch/x86_64/kernel/sys_x86_64.c
-+++ linux-2.6.15/arch/x86_64/kernel/sys_x86_64.c
-@@ -19,6 +19,7 @@
- 
- #include <asm/uaccess.h>
- #include <asm/ia32.h>
-+#include <asm/proc_mm.h>
- 
- /*
-  * sys_pipe() is the normal C calling standard for creating
-@@ -37,7 +38,7 @@ asmlinkage long sys_pipe(int __user *fil
- 	return error;
- }
- 
--asmlinkage long sys_mmap(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags,
-+long do64_mmap(struct mm_struct *mm, unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags,
- 	unsigned long fd, unsigned long off)
- {
- 	long error;
-@@ -55,9 +56,9 @@ asmlinkage long sys_mmap(unsigned long a
- 		if (!file)
- 			goto out;
- 	}
--	down_write(&current->mm->mmap_sem);
--	error = do_mmap_pgoff(file, addr, len, prot, flags, off >> PAGE_SHIFT);
--	up_write(&current->mm->mmap_sem);
-+	down_write(&mm->mmap_sem);
-+	error = __do_mmap_pgoff(mm, file, addr, len, prot, flags, off >> PAGE_SHIFT);
-+	up_write(&mm->mmap_sem);
- 
- 	if (file)
- 		fput(file);
-@@ -65,6 +66,12 @@ out:
- 	return error;
- }
- 
-+asmlinkage long sys_mmap(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags,
-+	unsigned long fd, unsigned long off)
-+{
-+	return do64_mmap(current->mm, addr, len, prot, flags, fd, off);
-+}
-+
- static void find_start_end(unsigned long flags, unsigned long *begin,
- 			   unsigned long *end)
- {
-Index: linux-2.6.15/arch/x86_64/mm/Makefile
-===================================================================
---- linux-2.6.15.orig/arch/x86_64/mm/Makefile
-+++ linux-2.6.15/arch/x86_64/mm/Makefile
-@@ -7,5 +7,6 @@ obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpag
- obj-$(CONFIG_NUMA) += numa.o
- obj-$(CONFIG_K8_NUMA) += k8topology.o
- obj-$(CONFIG_ACPI_NUMA) += srat.o
-+obj-$(CONFIG_PROC_MM) += proc_mm.o
- 
- hugetlbpage-y = ../../i386/mm/hugetlbpage.o
-Index: linux-2.6.15/arch/x86_64/mm/proc_mm.c
-===================================================================
---- /dev/null
-+++ linux-2.6.15/arch/x86_64/mm/proc_mm.c
-@@ -0,0 +1,85 @@
-+#include <linux/proc_mm.h>
-+#include <linux/mm.h>
-+#include <linux/init.h>
-+#include <linux/proc_fs.h>
-+#include <linux/file.h>
-+#include <linux/mman.h>
-+#include <asm/uaccess.h>
-+#include <asm/mmu_context.h>
-+
-+ssize_t write_proc_mm_emul(struct file *file, const char *buffer,
-+			     size_t count, loff_t *ppos)
-+{
-+	struct mm_struct *mm = file->private_data;
-+	struct proc_mm_op32 req;
-+	int n, ret;
-+
-+	if(count > sizeof(req))
-+		return(-EINVAL);
-+
-+	n = copy_from_user(&req, buffer, count);
-+	if(n != 0)
-+		return(-EFAULT);
-+
-+	ret = count;
-+	switch(req.op){
-+	case MM_MMAP: {
-+		struct mm_mmap32 *map = &req.u.mmap;
-+
-+		/* Nobody ever noticed it, but do_mmap_pgoff() calls
-+		 * get_unmapped_area() which checks current->mm, if
-+		 * MAP_FIXED is not set, so mmap() could replace
-+		 * an old mapping.
-+		 */
-+		if (! (map->flags & MAP_FIXED))
-+			return(-EINVAL);
-+
-+		ret = __do_mmap(mm, map->addr, map->len, map->prot,
-+			       map->flags, map->fd, map->offset);
-+		if((ret & ~PAGE_MASK) == 0)
-+			ret = count;
-+
-+		break;
-+	}
-+	case MM_MUNMAP: {
-+		struct mm_munmap32 *unmap = &req.u.munmap;
-+
-+		down_write(&mm->mmap_sem);
-+		ret = do_munmap(mm, unmap->addr, unmap->len);
-+		up_write(&mm->mmap_sem);
-+
-+		if(ret == 0)
-+			ret = count;
-+		break;
-+	}
-+	case MM_MPROTECT: {
-+		struct mm_mprotect32 *protect = &req.u.mprotect;
-+
-+		ret = do_mprotect(mm, protect->addr, protect->len,
-+				  protect->prot);
-+		if(ret == 0)
-+			ret = count;
-+		break;
-+	}
-+
-+	case MM_COPY_SEGMENTS: {
-+		struct mm_struct *from = proc_mm_get_mm_emul(req.u.copy_segments);
-+
-+		if(IS_ERR(from)){
-+			ret = PTR_ERR(from);
-+			break;
-+		}
-+
-+		ret = copy_context(mm, from);
-+		if(ret == 0)
-+			ret = count;
-+		break;
-+	}
-+	default:
-+		ret = -EINVAL;
-+		break;
-+	}
-+
-+	return ret;
-+}
-+
-Index: linux-2.6.15/include/asm-i386/desc.h
-===================================================================
---- linux-2.6.15.orig/include/asm-i386/desc.h
-+++ linux-2.6.15/include/asm-i386/desc.h
-@@ -158,6 +158,9 @@ static inline unsigned long get_desc_bas
- 	return base;
- }
- 
-+extern int __modify_ldt(struct mm_struct * mm, int func, void __user *ptr,
-+		      unsigned long bytecount);
-+
- #endif /* !__ASSEMBLY__ */
- 
- #endif
-Index: linux-2.6.15/include/asm-i386/mmu_context.h
-===================================================================
---- linux-2.6.15.orig/include/asm-i386/mmu_context.h
-+++ linux-2.6.15/include/asm-i386/mmu_context.h
-@@ -6,13 +6,25 @@
- #include <asm/atomic.h>
- #include <asm/pgalloc.h>
- #include <asm/tlbflush.h>
-+#include <asm/semaphore.h>
- 
- /*
-- * Used for LDT copy/destruction.
-+ * Used for LDT initialization/destruction. You cannot copy an LDT with
-+ * init_new_context, since it thinks you are passing it a new LDT and won't
-+ * deallocate its old content.
-  */
- int init_new_context(struct task_struct *tsk, struct mm_struct *mm);
- void destroy_context(struct mm_struct *mm);
- 
-+/* LDT initialization for a clean environment - needed for SKAS.*/
-+static inline void init_new_empty_context(struct mm_struct *mm)
-+{
-+	init_MUTEX(&mm->context.sem);
-+	mm->context.size = 0;
-+}
-+
-+/* LDT copy for SKAS - for the above problem.*/
-+int copy_context(struct mm_struct *mm, struct mm_struct *old_mm);
- 
- static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
- {
-@@ -29,6 +41,10 @@ static inline void switch_mm(struct mm_s
- {
- 	int cpu = smp_processor_id();
- 
-+#ifdef CONFIG_SMP
-+	prev = per_cpu(cpu_tlbstate, cpu).active_mm;
-+#endif
-+
- 	if (likely(prev != next)) {
- 		/* stop flush ipis for the previous mm */
- 		cpu_clear(cpu, prev->cpu_vm_mask);
-@@ -50,7 +66,6 @@ static inline void switch_mm(struct mm_s
- #ifdef CONFIG_SMP
- 	else {
- 		per_cpu(cpu_tlbstate, cpu).state = TLBSTATE_OK;
--		BUG_ON(per_cpu(cpu_tlbstate, cpu).active_mm != next);
- 
- 		if (!cpu_test_and_set(cpu, next->cpu_vm_mask)) {
- 			/* We were in lazy tlb mode and leave_mm disabled 
-Index: linux-2.6.15/include/asm-i386/proc_mm.h
-===================================================================
---- /dev/null
-+++ linux-2.6.15/include/asm-i386/proc_mm.h
-@@ -0,0 +1,18 @@
-+#ifndef __ASM_PROC_MM
-+#define __ASM_PROC_MM
-+
-+#include <asm/page.h>
-+
-+extern long do_mmap2(struct mm_struct *mm, unsigned long addr,
-+		unsigned long len, unsigned long prot, unsigned long flags,
-+		unsigned long fd, unsigned long pgoff);
-+
-+static inline long __do_mmap(struct mm_struct *mm, unsigned long addr,
-+		     unsigned long len, unsigned long prot,
-+		     unsigned long flags, unsigned long fd,
-+		     unsigned long off)
-+{
-+	return do_mmap2(mm, addr, len, prot, flags, fd, off >> PAGE_SHIFT);
-+}
-+
-+#endif /* __ASM_PROC_MM */
-Index: linux-2.6.15/include/asm-i386/ptrace.h
-===================================================================
---- linux-2.6.15.orig/include/asm-i386/ptrace.h
-+++ linux-2.6.15/include/asm-i386/ptrace.h
-@@ -84,4 +84,33 @@ extern unsigned long profile_pc(struct p
- #endif
- #endif /* __KERNEL__ */
- 
-+/*For SKAS3 support.*/
-+#ifndef _LINUX_PTRACE_STRUCT_DEF
-+#define _LINUX_PTRACE_STRUCT_DEF
-+
-+#define PTRACE_FAULTINFO	  52
-+/* 53 was used for PTRACE_SIGPENDING, don't reuse it. */
-+#define PTRACE_LDT		  54
-+#define PTRACE_SWITCH_MM 	  55
-+#define PTRACE_EX_FAULTINFO	  56
-+
-+struct ptrace_faultinfo {
-+	int is_write;
-+	unsigned long addr;
-+};
-+
-+struct ptrace_ex_faultinfo {
-+	int is_write;
-+	unsigned long addr;
-+	int trap_no;
-+};
-+
-+struct ptrace_ldt {
-+	int func;
-+  	void *ptr;
-+	unsigned long bytecount;
-+};
-+
-+#endif /*ifndef _LINUX_PTRACE_STRUCT_DEF*/
-+
- #endif
-Index: linux-2.6.15/include/asm-i386/thread_info.h
-===================================================================
---- linux-2.6.15.orig/include/asm-i386/thread_info.h
-+++ linux-2.6.15/include/asm-i386/thread_info.h
-@@ -139,9 +139,9 @@ register unsigned long current_stack_poi
- #define TIF_NEED_RESCHED	3	/* rescheduling necessary */
- #define TIF_SINGLESTEP		4	/* restore singlestep on return to user mode */
- #define TIF_IRET		5	/* return with iret */
--#define TIF_SYSCALL_EMU		6	/* syscall emulation active */
- #define TIF_SYSCALL_AUDIT	7	/* syscall auditing active */
- #define TIF_SECCOMP		8	/* secure computing */
-+#define TIF_SYSCALL_EMU		9	/* syscall emulation active */
- #define TIF_POLLING_NRFLAG	16	/* true if poll_idle() is polling TIF_NEED_RESCHED */
- #define TIF_MEMDIE		17
- 
-Index: linux-2.6.15/include/asm-x86_64/desc.h
-===================================================================
---- linux-2.6.15.orig/include/asm-x86_64/desc.h
-+++ linux-2.6.15/include/asm-x86_64/desc.h
-@@ -225,6 +225,9 @@ static inline void load_LDT(mm_context_t
- 
- extern struct desc_ptr idt_descr;
- 
-+extern int __modify_ldt(struct mm_struct * mm, int func, void __user *ptr,
-+		unsigned long bytecount);
-+
- #endif /* !__ASSEMBLY__ */
- 
- #endif
-Index: linux-2.6.15/include/asm-x86_64/mmu_context.h
-===================================================================
---- linux-2.6.15.orig/include/asm-x86_64/mmu_context.h
-+++ linux-2.6.15/include/asm-x86_64/mmu_context.h
-@@ -8,13 +8,28 @@
- #include <asm/pda.h>
- #include <asm/pgtable.h>
- #include <asm/tlbflush.h>
-+#include <asm/semaphore.h>
- 
- /*
-  * possibly do the LDT unload here?
-+ * Used for LDT initialization/destruction. You cannot copy an LDT with
-+ * init_new_context, since it thinks you are passing it a new LDT and won't
-+ * deallocate its old content.
-  */
-+
- int init_new_context(struct task_struct *tsk, struct mm_struct *mm);
- void destroy_context(struct mm_struct *mm);
- 
-+/* LDT initialization for a clean environment - needed for SKAS.*/
-+static inline void init_new_empty_context(struct mm_struct *mm)
-+{
-+	init_MUTEX(&mm->context.sem);
-+	mm->context.size = 0;
-+}
-+
-+/* LDT copy for SKAS - for the above problem.*/
-+int copy_context(struct mm_struct *mm, struct mm_struct *old_mm);
-+
- #ifdef CONFIG_SMP
- 
- static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
-@@ -37,6 +52,9 @@ static inline void switch_mm(struct mm_s
- 			     struct task_struct *tsk)
- {
- 	unsigned cpu = smp_processor_id();
-+#ifdef CONFIG_SMP
-+	prev = read_pda(active_mm);
-+#endif
- 	if (likely(prev != next)) {
- 		/* stop flush ipis for the previous mm */
- 		clear_bit(cpu, &prev->cpu_vm_mask);
-@@ -53,8 +71,6 @@ static inline void switch_mm(struct mm_s
- #ifdef CONFIG_SMP
- 	else {
- 		write_pda(mmu_state, TLBSTATE_OK);
--		if (read_pda(active_mm) != next)
--			out_of_line_bug();
- 		if(!test_and_set_bit(cpu, &next->cpu_vm_mask)) {
- 			/* We were in lazy tlb mode and leave_mm disabled 
- 			 * tlb flush IPI delivery. We must reload CR3
-Index: linux-2.6.15/include/asm-x86_64/proc_mm.h
-===================================================================
---- /dev/null
-+++ linux-2.6.15/include/asm-x86_64/proc_mm.h
-@@ -0,0 +1,58 @@
-+#ifndef __ASM_PROC_MM
-+#define __ASM_PROC_MM
-+#include <linux/types.h>
-+
-+#include <asm/compat.h>
-+
-+struct mm_mmap32 {
-+	compat_ulong_t addr;
-+	compat_ulong_t len;
-+	compat_ulong_t prot;
-+	compat_ulong_t flags;
-+	compat_ulong_t fd;
-+	compat_ulong_t offset;
-+};
-+
-+struct mm_munmap32 {
-+	compat_ulong_t addr;
-+	compat_ulong_t len;
-+};
-+
-+struct mm_mprotect32 {
-+	compat_ulong_t addr;
-+	compat_ulong_t len;
-+        compat_uint_t prot;
-+};
-+
-+struct proc_mm_op32 {
-+	compat_int_t op;
-+	union {
-+		struct mm_mmap32 mmap;
-+		struct mm_munmap32 munmap;
-+	        struct mm_mprotect32 mprotect;
-+		compat_int_t copy_segments;
-+	} u;
-+};
-+
-+extern ssize_t write_proc_mm_emul(struct file *file, const char *buffer,
-+			     size_t count, loff_t *ppos);
-+
-+extern struct mm_struct *proc_mm_get_mm64(int fd);
-+
-+extern long do64_mmap(struct mm_struct *mm, unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags,
-+	unsigned long fd, unsigned long off);
-+
-+static inline long __do_mmap(struct mm_struct *mm, unsigned long addr,
-+		     unsigned long len, unsigned long prot,
-+		     unsigned long flags, unsigned long fd,
-+		     unsigned long off)
-+{
-+	/* The latter one is stricter, since will actually check that off is page
-+	 * aligned. The first one skipped the check. */
-+
-+	/* return do32_mmap2(mm, addr, len, prot, flags, fd, off >>
-+	 * PAGE_SHIFT);*/
-+	return do64_mmap(mm, addr, len, prot, flags, fd, off);
-+}
-+
-+#endif /* __ASM_PROC_MM */
-Index: linux-2.6.15/include/asm-x86_64/ptrace.h
-===================================================================
---- linux-2.6.15.orig/include/asm-x86_64/ptrace.h
-+++ linux-2.6.15/include/asm-x86_64/ptrace.h
-@@ -64,6 +64,59 @@ struct pt_regs {
- /* top of stack page */ 
- };
- 
-+/* Stolen from
-+#include <linux/compat.h>; we can't include it because
-+there is a nasty ciclic include chain.
-+*/
-+
-+#include <asm/types.h>
-+
-+#define		compat_int_t	s32
-+#define		compat_long_t	s32
-+#define		compat_uint_t	u32
-+#define		compat_ulong_t	u32
-+#define		compat_uptr_t	u32
-+
-+struct ptrace_faultinfo32 {
-+	compat_int_t is_write;
-+	compat_ulong_t addr;
-+};
-+
-+struct ptrace_ex_faultinfo32 {
-+	compat_int_t is_write;
-+	compat_ulong_t addr;
-+	compat_int_t trap_no;
-+};
-+
-+struct ptrace_ldt32 {
-+	compat_int_t func;
-+	compat_uptr_t ptr; /*Actually a void pointer on i386, but must be converted.*/
-+	compat_ulong_t bytecount;
-+};
-+
-+struct ptrace_faultinfo {
-+	int is_write;
-+	unsigned long addr;
-+};
-+
-+struct ptrace_ex_faultinfo {
-+	int is_write;
-+	unsigned long addr;
-+	int trap_no;
-+};
-+
-+struct ptrace_ldt {
-+	int func;
-+  	void *ptr;
-+	unsigned long bytecount;
-+};
-+
-+#undef	compat_int_t
-+#undef	compat_long_t
-+#undef	compat_uint_t
-+#undef	compat_ulong_t
-+#undef	compat_uptr_t
-+
- #endif
- 
- /* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
-@@ -74,6 +127,12 @@ struct pt_regs {
- #define PTRACE_GETFPXREGS         18
- #define PTRACE_SETFPXREGS         19
- 
-+#define PTRACE_FAULTINFO 52
-+/* 53 was used for PTRACE_SIGPENDING, don't reuse it. */
-+#define PTRACE_LDT 54
-+#define PTRACE_SWITCH_MM 55
-+#define PTRACE_EX_FAULTINFO	  56
-+
- /* only useful for access 32bit programs */
- #define PTRACE_GET_THREAD_AREA    25
- #define PTRACE_SET_THREAD_AREA    26
-Index: linux-2.6.15/include/linux/mm.h
-===================================================================
---- linux-2.6.15.orig/include/linux/mm.h
-+++ linux-2.6.15/include/linux/mm.h
-@@ -719,6 +719,9 @@ extern unsigned long do_mremap(unsigned 
- 			       unsigned long old_len, unsigned long new_len,
- 			       unsigned long flags, unsigned long new_addr);
- 
-+extern long do_mprotect(struct mm_struct *mm, unsigned long start,
-+			size_t len, unsigned long prot);
-+
- /*
-  * Prototype to add a shrinker callback for ageable caches.
-  * 
-@@ -872,9 +875,15 @@ extern int may_expand_vm(struct mm_struc
- 
- extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
- 
--extern unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
-+extern unsigned long __do_mmap_pgoff(struct mm_struct *mm, struct file *file,
-+				   unsigned long addr, unsigned long len,
-+				   unsigned long prot, unsigned long flag,
-+				   unsigned long pgoff);
-+static inline unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
- 	unsigned long len, unsigned long prot,
--	unsigned long flag, unsigned long pgoff);
-+	unsigned long flag, unsigned long pgoff) {
-+	return __do_mmap_pgoff(current->mm, file, addr, len, prot, flag, pgoff);
-+}
- 
- static inline unsigned long do_mmap(struct file *file, unsigned long addr,
- 	unsigned long len, unsigned long prot,
-Index: linux-2.6.15/include/linux/proc_mm.h
-===================================================================
---- /dev/null
-+++ linux-2.6.15/include/linux/proc_mm.h
-@@ -0,0 +1,114 @@
-+/*
-+ * Copyright (C) 2002 Jeff Dike (jdike at karaya.com)
-+ * Licensed under the GPL
-+ */
-+
-+#ifndef __PROC_MM_H
-+#define __PROC_MM_H
-+
-+#include <linux/config.h>
-+#include <linux/sched.h>
-+#include <linux/compiler.h>
-+
-+/* The differences between this one and do_mmap are that:
-+ * - we must perform controls for userspace-supplied params (which are
-+ *   arch-specific currently). And also fget(fd) if needed and so on...
-+ * - we must accept the struct mm_struct on which to act as first param, and the
-+ *   offset in byte rather than page units as last param.
-+ */
-+static inline long __do_mmap(struct mm_struct *mm, unsigned long addr,
-+		     unsigned long len, unsigned long prot,
-+		     unsigned long flags, unsigned long fd,
-+		     unsigned long off);
-+
-+/* This header can be used only on archs defining CONFIG_PROC_MM in their
-+ * configs, so asm/proc_mm.h can still exist only for the needed archs.
-+ * Including it only in the x86-64 case does not make sense.*/
-+#include <asm/proc_mm.h>
-+
-+/*XXX: this is defined on x86_64, but not on every 64-bit arch (not on sh64).*/
-+#ifdef CONFIG_64BIT
-+
-+#define write_proc_mm write_proc_mm_emul
-+#define write_proc_mm64 write_proc_mm_native
-+
-+/* It would make more sense to do this mapping the reverse direction, to map the
-+ * called name to the defined one and not the reverse. Like the 2nd example
-+ */
-+/*#define proc_mm_get_mm proc_mm_get_mm_emul
-+#define proc_mm_get_mm64 proc_mm_get_mm_native*/
-+
-+#define proc_mm_get_mm_emul proc_mm_get_mm
-+#define proc_mm_get_mm_native proc_mm_get_mm64
-+
-+#else
-+
-+#define write_proc_mm write_proc_mm_native
-+#undef write_proc_mm64
-+
-+/*#define proc_mm_get_mm proc_mm_get_mm_native
-+#undef proc_mm_get_mm64*/
-+
-+#define proc_mm_get_mm_native proc_mm_get_mm
-+#undef proc_mm_get_mm_emul
-+
-+#endif
-+
-+#define MM_MMAP 54
-+#define MM_MUNMAP 55
-+#define MM_MPROTECT 56
-+#define MM_COPY_SEGMENTS 57
-+
-+struct mm_mmap {
-+	unsigned long addr;
-+	unsigned long len;
-+	unsigned long prot;
-+	unsigned long flags;
-+	unsigned long fd;
-+	unsigned long offset;
-+};
-+
-+struct mm_munmap {
-+	unsigned long addr;
-+	unsigned long len;
-+};
-+
-+struct mm_mprotect {
-+	unsigned long addr;
-+	unsigned long len;
-+        unsigned int prot;
-+};
-+
-+struct proc_mm_op {
-+	int op;
-+	union {
-+		struct mm_mmap mmap;
-+		struct mm_munmap munmap;
-+	        struct mm_mprotect mprotect;
-+		int copy_segments;
-+	} u;
-+};
-+
-+extern struct mm_struct *proc_mm_get_mm(int fd);
-+
-+/* Cope with older kernels */
-+#ifndef __acquires
-+#define __acquires(x)
-+#endif
-+
-+#ifdef CONFIG_PROC_MM_DUMPABLE
-+/*
-+ * Since we take task_lock of child and it's needed also by the caller, we
-+ * return with it locked.
-+ */
-+extern void lock_fix_dumpable_setting(struct task_struct * child,
-+		struct mm_struct* new) __acquires(child->alloc_lock);
-+#else
-+static inline void lock_fix_dumpable_setting(struct task_struct * child,
-+		struct mm_struct* new) __acquires(child->alloc_lock)
-+{
-+	task_lock(child);
-+}
-+#endif
-+
-+#endif
-Index: linux-2.6.15/localversion-skas
-===================================================================
---- /dev/null
-+++ linux-2.6.15/localversion-skas
-@@ -0,0 +1 @@
-+-skas3-v9-pre8
-Index: linux-2.6.15/mm/Makefile
-===================================================================
---- linux-2.6.15.orig/mm/Makefile
-+++ linux-2.6.15/mm/Makefile
-@@ -20,3 +20,9 @@ obj-$(CONFIG_SHMEM) += shmem.o
- obj-$(CONFIG_TINY_SHMEM) += tiny-shmem.o
- obj-$(CONFIG_MEMORY_HOTPLUG) += memory_hotplug.o
- obj-$(CONFIG_FS_XIP) += filemap_xip.o
-+
-+obj-$(CONFIG_PROC_MM)	+= proc_mm.o
-+
-+ifeq ($(CONFIG_PROC_MM),y)
-+obj-m			+= proc_mm-mod.o
-+endif
-Index: linux-2.6.15/mm/mmap.c
-===================================================================
---- linux-2.6.15.orig/mm/mmap.c
-+++ linux-2.6.15/mm/mmap.c
-@@ -867,11 +867,11 @@ void vm_stat_account(struct mm_struct *m
-  * The caller must hold down_write(current->mm->mmap_sem).
-  */
- 
--unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
--			unsigned long len, unsigned long prot,
--			unsigned long flags, unsigned long pgoff)
-+unsigned long __do_mmap_pgoff(struct mm_struct *mm, struct file * file,
-+			    unsigned long addr, unsigned long len,
-+			    unsigned long prot, unsigned long flags,
-+			    unsigned long pgoff)
- {
--	struct mm_struct * mm = current->mm;
- 	struct vm_area_struct * vma, * prev;
- 	struct inode *inode;
- 	unsigned int vm_flags;
-@@ -1146,7 +1146,7 @@ unacct_error:
- 	return error;
- }
- 
--EXPORT_SYMBOL(do_mmap_pgoff);
-+EXPORT_SYMBOL(__do_mmap_pgoff);
- 
- /* Get an address range which is currently unmapped.
-  * For shmat() with addr=0.
-Index: linux-2.6.15/mm/mprotect.c
-===================================================================
---- linux-2.6.15.orig/mm/mprotect.c
-+++ linux-2.6.15/mm/mprotect.c
-@@ -176,8 +176,9 @@ fail:
- 	return error;
- }
- 
--asmlinkage long
--sys_mprotect(unsigned long start, size_t len, unsigned long prot)
-+long
-+do_mprotect(struct mm_struct *mm, unsigned long start, size_t len,
-+	     unsigned long prot)
- {
- 	unsigned long vm_flags, nstart, end, tmp, reqprot;
- 	struct vm_area_struct *vma, *prev;
-@@ -208,9 +209,9 @@ sys_mprotect(unsigned long start, size_t
- 
- 	vm_flags = calc_vm_prot_bits(prot);
- 
--	down_write(&current->mm->mmap_sem);
-+	down_write(&mm->mmap_sem);
- 
--	vma = find_vma_prev(current->mm, start, &prev);
-+	vma = find_vma_prev(mm, start, &prev);
- 	error = -ENOMEM;
- 	if (!vma)
- 		goto out;
-@@ -277,6 +278,15 @@ sys_mprotect(unsigned long start, size_t
- 		}
- 	}
- out:
--	up_write(&current->mm->mmap_sem);
-+	up_write(&mm->mmap_sem);
- 	return error;
- }
-+
-+asmlinkage long sys_mprotect(unsigned long start, size_t len, unsigned long prot)
-+{
-+	long ret = do_mprotect(current->mm, start, len, prot);
-+	/* A tail call would reorder parameters on the stack and they would then
-+	 * be restored at the wrong places. */
-+	prevent_tail_call(ret);
-+	return ret;
-+}
-Index: linux-2.6.15/mm/proc_mm.c
-===================================================================
---- /dev/null
-+++ linux-2.6.15/mm/proc_mm.c
-@@ -0,0 +1,300 @@
-+/*
-+ * Copyright (C) 2002 Jeff Dike (jdike at karaya.com)
-+ * Licensed under the GPL
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/compiler.h>
-+#include <linux/mm.h>
-+#include <linux/init.h>
-+#include <linux/proc_fs.h>
-+#include <linux/proc_mm.h>
-+#include <linux/file.h>
-+#include <linux/mman.h>
-+#include <asm/uaccess.h>
-+#include <asm/mmu_context.h>
-+
-+#ifdef CONFIG_PROC_MM_DUMPABLE
-+/* Checks if a task must be considered dumpable
-+ *
-+ * XXX: copied from fs/proc/base.c, removed task_lock, added rmb(): this must be
-+ * called with task_lock(task) held. */
-+static int task_dumpable(struct task_struct *task)
-+{
-+	int dumpable = 0;
-+	struct mm_struct *mm;
-+
-+	mm = task->mm;
-+	if (mm) {
-+		rmb();
-+		dumpable = mm->dumpable;
-+	}
-+	return dumpable;
-+}
-+
-+/*
-+ * This is to be used in PTRACE_SWITCH_MM handling. We are going to set
-+ * child->mm to new, and we must first correctly set new->dumpable.
-+ * Since we take task_lock of child and it's needed also by the caller, we
-+ * return with it locked.
-+ */
-+void lock_fix_dumpable_setting(struct task_struct* child, struct mm_struct* new)
-+	__acquires(child->alloc_lock)
-+{
-+	int dumpable = 1;
-+
-+	/* We must be safe.
-+	 * If the child is ptraced from a non-dumpable process,
-+	 * let's not be dumpable. If the child is non-dumpable itself,
-+	 * copy this property across mm's.
-+	 *
-+	 * Don't try to be smart for the opposite case and turn
-+	 * child->mm->dumpable to 1: I've not made sure it is safe.
-+	 */
-+
-+	task_lock(current);
-+	if (unlikely(!task_dumpable(current))) {
-+		dumpable = 0;
-+	}
-+	task_unlock(current);
-+
-+	task_lock(child);
-+	if (likely(dumpable) && unlikely(!task_dumpable(child))) {
-+		dumpable = 0;
-+	}
-+
-+	if (!dumpable) {
-+		new->dumpable = 0;
-+		wmb();
-+	}
-+}
-+#endif
-+
-+/* Naming conventions are a mess, so I note them down.
-+ *
-+ * Things ending in _mm can be for everything. It's only for
-+ * {open,release}_proc_mm.
-+ *
-+ * For the rest:
-+ *
-+ * _mm means /proc/mm, _mm64 means /proc/mm64. This is for the infrastructure
-+ * only (for instance proc_mm_get_mm checks whether the file is /proc/mm or
-+ * /proc/mm64; for instance the /proc handling).
-+ *
-+ * While for what is conversion dependant, we use the suffix _native and _emul.
-+ * In some cases, there is a mapping between these ones (defined by
-+ * <asm/proc_mm.h>).
-+ */
-+
-+/*These two are common to everything.*/
-+static int open_proc_mm(struct inode *inode, struct file *file)
-+{
-+	struct mm_struct *mm = mm_alloc();
-+	int ret;
-+
-+	ret = -ENOMEM;
-+	if(mm == NULL)
-+		goto out_mem;
-+
-+	init_new_empty_context(mm);
-+	arch_pick_mmap_layout(mm);
-+#ifdef CONFIG_PROC_MM_DUMPABLE
-+	mm->dumpable = current->mm->dumpable;
-+	wmb();
-+#endif
-+
-+	file->private_data = mm;
-+
-+	return 0;
-+
-+out_mem:
-+	return ret;
-+}
-+
-+static int release_proc_mm(struct inode *inode, struct file *file)
-+{
-+	struct mm_struct *mm = file->private_data;
-+
-+	mmput(mm);
-+	return 0;
-+}
-+
-+static struct file_operations proc_mm_fops;
-+
-+struct mm_struct *proc_mm_get_mm_native(int fd);
-+
-+static ssize_t write_proc_mm_native(struct file *file, const char *buffer,
-+			     size_t count, loff_t *ppos)
-+{
-+	struct mm_struct *mm = file->private_data;
-+	struct proc_mm_op req;
-+	int n, ret;
-+
-+	if(count > sizeof(req))
-+		return(-EINVAL);
-+
-+	n = copy_from_user(&req, buffer, count);
-+	if(n != 0)
-+		return(-EFAULT);
-+
-+	ret = count;
-+	switch(req.op){
-+	case MM_MMAP: {
-+		struct mm_mmap *map = &req.u.mmap;
-+
-+		/* Nobody ever noticed it, but do_mmap_pgoff() calls
-+		 * get_unmapped_area() which checks current->mm, if
-+		 * MAP_FIXED is not set, so mmap() could replace
-+		 * an old mapping.
-+		 */
-+		if (! (map->flags & MAP_FIXED))
-+			return(-EINVAL);
-+
-+		ret = __do_mmap(mm, map->addr, map->len, map->prot,
-+			       map->flags, map->fd, map->offset);
-+		if((ret & ~PAGE_MASK) == 0)
-+			ret = count;
-+
-+		break;
-+	}
-+	case MM_MUNMAP: {
-+		struct mm_munmap *unmap = &req.u.munmap;
-+
-+		down_write(&mm->mmap_sem);
-+		ret = do_munmap(mm, unmap->addr, unmap->len);
-+		up_write(&mm->mmap_sem);
-+
-+		if(ret == 0)
-+			ret = count;
-+		break;
-+	}
-+	case MM_MPROTECT: {
-+		struct mm_mprotect *protect = &req.u.mprotect;
-+
-+		ret = do_mprotect(mm, protect->addr, protect->len,
-+				  protect->prot);
-+		if(ret == 0)
-+			ret = count;
-+		break;
-+	}
-+
-+	case MM_COPY_SEGMENTS: {
-+		struct mm_struct *from = proc_mm_get_mm_native(req.u.copy_segments);
-+
-+		if(IS_ERR(from)){
-+			ret = PTR_ERR(from);
-+			break;
-+		}
-+
-+		ret = copy_context(mm, from);
-+		if(ret == 0)
-+			ret = count;
-+		break;
-+	}
-+	default:
-+		ret = -EINVAL;
-+		break;
-+	}
-+
-+	return ret;
-+}
-+
-+/*These three are all for /proc/mm.*/
-+struct mm_struct *proc_mm_get_mm(int fd)
-+{
-+	struct mm_struct *ret = ERR_PTR(-EBADF);
-+	struct file *file;
-+
-+	file = fget(fd);
-+	if (!file)
-+		goto out;
-+
-+	ret = ERR_PTR(-EINVAL);
-+	if(file->f_op != &proc_mm_fops)
-+		goto out_fput;
-+
-+	ret = file->private_data;
-+out_fput:
-+	fput(file);
-+out:
-+	return(ret);
-+}
-+
-+static struct file_operations proc_mm_fops = {
-+	.open		= open_proc_mm,
-+	.release	= release_proc_mm,
-+	.write		= write_proc_mm,
-+};
-+
-+/*Macro-ify it to avoid the duplication.*/
-+static int make_proc_mm(void)
-+{
-+	struct proc_dir_entry *ent;
-+
-+	ent = create_proc_entry("mm", 0222, &proc_root);
-+	if(ent == NULL){
-+		printk("make_proc_mm : Failed to register /proc/mm\n");
-+		return(0);
-+	}
-+	ent->proc_fops = &proc_mm_fops;
-+
-+	return 0;
-+}
-+
-+__initcall(make_proc_mm);
-+
-+/*XXX: change the option.*/
-+#ifdef CONFIG_64BIT
-+static struct file_operations proc_mm64_fops = {
-+	.open		= open_proc_mm,
-+	.release	= release_proc_mm,
-+	.write		= write_proc_mm64,
-+};
-+
-+static int make_proc_mm64(void)
-+{
-+	struct proc_dir_entry *ent;
-+
-+	ent = create_proc_entry("mm64", 0222, &proc_root);
-+	if(ent == NULL){
-+		printk("make_proc_mm : Failed to register /proc/mm64\n");
-+		return(0);
-+	}
-+	ent->proc_fops = &proc_mm64_fops;
-+
-+	return 0;
-+}
-+
-+__initcall(make_proc_mm64);
-+
-+struct mm_struct *proc_mm_get_mm64(int fd)
-+{
-+	struct mm_struct *ret = ERR_PTR(-EBADF);
-+	struct file *file;
-+
-+	file = fget(fd);
-+	if (!file)
-+		goto out;
-+
-+	ret = ERR_PTR(-EINVAL);
-+	/*This is the only change.*/
-+	if(file->f_op != &proc_mm64_fops)
-+		goto out_fput;
-+
-+	ret = file->private_data;
-+out_fput:
-+	fput(file);
-+out:
-+	return(ret);
-+}
-+#endif
-+/*
-+ * Overrides for Emacs so that we follow Linus's tabbing style.
-+ * Emacs will notice this stuff at the end of the file and automatically
-+ * adjust the settings for this buffer only.  This must remain at the end
-+ * of the file.
-+ * ---------------------------------------------------------------------------
-+ * Local variables:
-+ * c-file-style: "linux"
-+ * End:
-+ */
-Index: linux-2.6.15/mm/proc_mm-mod.c
-===================================================================
---- /dev/null
-+++ linux-2.6.15/mm/proc_mm-mod.c
-@@ -0,0 +1,51 @@
-+#include <linux/config.h>
-+#include <linux/kernel.h>
-+#include <linux/proc_mm.h>
-+#include <linux/ptrace.h>
-+#include <linux/module.h>
-+
-+#ifdef CONFIG_64BIT
-+#define PRINT_OFFSET(type, member) \
-+	printk(KERN_DEBUG "struct " #type "32->" #member " \t: %ld\n", (long) offsetof(struct type ## 32, member))
-+#else
-+#define PRINT_OFFSET(type, member) \
-+	printk(KERN_DEBUG "struct " #type "->" #member " \t: %ld\n", (long) offsetof(struct type, member))
-+#endif
-+
-+static int debug_printoffsets(void)
-+{
-+	printk(KERN_DEBUG "Skas core structures layout BEGIN:\n");
-+	PRINT_OFFSET(mm_mmap, addr);
-+	PRINT_OFFSET(mm_mmap, len);
-+	PRINT_OFFSET(mm_mmap, prot);
-+	PRINT_OFFSET(mm_mmap, flags);
-+	PRINT_OFFSET(mm_mmap, fd);
-+	PRINT_OFFSET(mm_mmap, offset);
-+
-+	PRINT_OFFSET(mm_munmap, addr);
-+	PRINT_OFFSET(mm_munmap, len);
-+
-+	PRINT_OFFSET(mm_mprotect, addr);
-+	PRINT_OFFSET(mm_mprotect, len);
-+	PRINT_OFFSET(mm_mprotect, prot);
-+
-+	PRINT_OFFSET(proc_mm_op, op);
-+	PRINT_OFFSET(proc_mm_op, u);
-+	PRINT_OFFSET(proc_mm_op, u.mmap);
-+	PRINT_OFFSET(proc_mm_op, u.munmap);
-+	PRINT_OFFSET(proc_mm_op, u.mprotect);
-+	PRINT_OFFSET(proc_mm_op, u.copy_segments);
-+
-+	PRINT_OFFSET(ptrace_faultinfo, is_write);
-+	PRINT_OFFSET(ptrace_faultinfo, addr);
-+
-+	PRINT_OFFSET(ptrace_ldt, func);
-+	PRINT_OFFSET(ptrace_ldt, ptr);
-+	PRINT_OFFSET(ptrace_ldt, bytecount);
-+	printk(KERN_DEBUG "Skas core structures layout END.\n");
-+
-+	return 0;
-+}
-+#undef PRINT_OFFSET
-+
-+module_init(debug_printoffsets);

Deleted: trunk/src/kernel-patch-skas/skas-2.6.16-v9-pre9.patch
===================================================================
--- trunk/src/kernel-patch-skas/skas-2.6.16-v9-pre9.patch	2006-08-27 15:01:30 UTC (rev 166)
+++ trunk/src/kernel-patch-skas/skas-2.6.16-v9-pre9.patch	2006-08-27 15:16:57 UTC (rev 167)
@@ -1,1846 +0,0 @@
-Index: linux-2.6.16/arch/i386/Kconfig
-===================================================================
---- linux-2.6.16.orig/arch/i386/Kconfig
-+++ linux-2.6.16/arch/i386/Kconfig
-@@ -496,6 +496,26 @@ config X86_PAE
- 	depends on HIGHMEM64G
- 	default y
- 
-+config PROC_MM
-+	bool "/proc/mm support"
-+	default y
-+
-+config PROC_MM_DUMPABLE
-+	bool "Make UML childs /proc/<pid> completely browsable"
-+	default n
-+	help
-+	  If in doubt, say N.
-+
-+	  This fiddles with some settings to make sure /proc/<pid> is completely
-+	  browsable by who started UML, at the expense of some additional
-+	  locking (maybe this could slow down the runned UMLs of a few percents,
-+	  I've not tested this).
-+
-+	  Also, if there is a bug in this feature, there is some little
-+	  possibility to do privilege escalation if you have UML installed
-+	  setuid (which you shouldn't have done) or if UML changes uid on
-+	  startup (which will be a good thing, when enabled) ...
-+
- # Common NUMA Features
- config NUMA
- 	bool "Numa Memory Allocation and Scheduler Support"
-Index: linux-2.6.16/arch/i386/kernel/ldt.c
-===================================================================
---- linux-2.6.16.orig/arch/i386/kernel/ldt.c
-+++ linux-2.6.16/arch/i386/kernel/ldt.c
-@@ -28,11 +28,12 @@ static void flush_ldt(void *null)
- }
- #endif
- 
--static int alloc_ldt(mm_context_t *pc, int mincount, int reload)
-+static int alloc_ldt(struct mm_struct *mm, int mincount, int reload)
- {
- 	void *oldldt;
- 	void *newldt;
- 	int oldsize;
-+	mm_context_t * pc = &mm->context;
- 
- 	if (mincount <= pc->size)
- 		return 0;
-@@ -59,13 +60,15 @@ static int alloc_ldt(mm_context_t *pc, i
- #ifdef CONFIG_SMP
- 		cpumask_t mask;
- 		preempt_disable();
--		load_LDT(pc);
-+		if (&current->active_mm->context == pc)
-+			load_LDT(pc);
- 		mask = cpumask_of_cpu(smp_processor_id());
--		if (!cpus_equal(current->mm->cpu_vm_mask, mask))
-+		if (!cpus_equal(mm->cpu_vm_mask, mask))
- 			smp_call_function(flush_ldt, NULL, 1, 1);
- 		preempt_enable();
- #else
--		load_LDT(pc);
-+		if (&current->active_mm->context == pc)
-+			load_LDT(pc);
- #endif
- 	}
- 	if (oldsize) {
-@@ -77,12 +80,12 @@ static int alloc_ldt(mm_context_t *pc, i
- 	return 0;
- }
- 
--static inline int copy_ldt(mm_context_t *new, mm_context_t *old)
-+static inline int copy_ldt(struct mm_struct *new, struct mm_struct *old)
- {
--	int err = alloc_ldt(new, old->size, 0);
-+	int err = alloc_ldt(new, old->context.size, 0);
- 	if (err < 0)
- 		return err;
--	memcpy(new->ldt, old->ldt, old->size*LDT_ENTRY_SIZE);
-+	memcpy(new->context.ldt, old->context.ldt, old->context.size*LDT_ENTRY_SIZE);
- 	return 0;
- }
- 
-@@ -90,22 +93,24 @@ static inline int copy_ldt(mm_context_t 
-  * we do not have to muck with descriptors here, that is
-  * done in switch_mm() as needed.
-  */
--int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
-+int copy_context(struct mm_struct *mm, struct mm_struct *old_mm)
- {
--	struct mm_struct * old_mm;
- 	int retval = 0;
- 
--	init_MUTEX(&mm->context.sem);
--	mm->context.size = 0;
--	old_mm = current->mm;
- 	if (old_mm && old_mm->context.size > 0) {
- 		down(&old_mm->context.sem);
--		retval = copy_ldt(&mm->context, &old_mm->context);
-+		retval = copy_ldt(mm, old_mm);
- 		up(&old_mm->context.sem);
- 	}
- 	return retval;
- }
- 
-+int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
-+{
-+	init_new_empty_context(mm);
-+	return copy_context(mm, current->mm);
-+}
-+
- /*
-  * No need to lock the MM as we are the last user
-  */
-@@ -122,11 +127,11 @@ void destroy_context(struct mm_struct *m
- 	}
- }
- 
--static int read_ldt(void __user * ptr, unsigned long bytecount)
-+static int read_ldt(struct mm_struct * mm, void __user * ptr,
-+		    unsigned long bytecount)
- {
- 	int err;
- 	unsigned long size;
--	struct mm_struct * mm = current->mm;
- 
- 	if (!mm->context.size)
- 		return 0;
-@@ -175,9 +180,8 @@ static int read_default_ldt(void __user 
- 	return err;
- }
- 
--static int write_ldt(void __user * ptr, unsigned long bytecount, int oldmode)
-+static int write_ldt(struct mm_struct * mm, void __user * ptr, unsigned long bytecount, int oldmode)
- {
--	struct mm_struct * mm = current->mm;
- 	__u32 entry_1, entry_2;
- 	int error;
- 	struct user_desc ldt_info;
-@@ -201,7 +205,7 @@ static int write_ldt(void __user * ptr, 
- 
- 	down(&mm->context.sem);
- 	if (ldt_info.entry_number >= mm->context.size) {
--		error = alloc_ldt(&current->mm->context, ldt_info.entry_number+1, 1);
-+		error = alloc_ldt(mm, ldt_info.entry_number+1, 1);
- 		if (error < 0)
- 			goto out_unlock;
- 	}
-@@ -231,23 +235,33 @@ out:
- 	return error;
- }
- 
--asmlinkage int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
-+int __modify_ldt(struct mm_struct * mm, int func, void __user *ptr,
-+	       unsigned long bytecount)
- {
- 	int ret = -ENOSYS;
- 
- 	switch (func) {
- 	case 0:
--		ret = read_ldt(ptr, bytecount);
-+		ret = read_ldt(mm, ptr, bytecount);
- 		break;
- 	case 1:
--		ret = write_ldt(ptr, bytecount, 1);
-+		ret = write_ldt(mm, ptr, bytecount, 1);
- 		break;
- 	case 2:
- 		ret = read_default_ldt(ptr, bytecount);
- 		break;
- 	case 0x11:
--		ret = write_ldt(ptr, bytecount, 0);
-+		ret = write_ldt(mm, ptr, bytecount, 0);
- 		break;
- 	}
- 	return ret;
- }
-+
-+asmlinkage int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
-+{
-+	int ret = __modify_ldt(current->mm, func, ptr, bytecount);
-+	/* A tail call would reorder parameters on the stack and they would then
-+	 * be restored at the wrong places. */
-+	prevent_tail_call(ret);
-+	return ret;
-+}
-Index: linux-2.6.16/arch/i386/kernel/ptrace.c
-===================================================================
---- linux-2.6.16.orig/arch/i386/kernel/ptrace.c
-+++ linux-2.6.16/arch/i386/kernel/ptrace.c
-@@ -17,6 +17,7 @@
- #include <linux/audit.h>
- #include <linux/seccomp.h>
- #include <linux/signal.h>
-+#include <linux/proc_mm.h>
- 
- #include <asm/uaccess.h>
- #include <asm/pgtable.h>
-@@ -625,6 +626,66 @@ long arch_ptrace(struct task_struct *chi
- 					(struct user_desc __user *) data);
- 		break;
- 
-+#ifdef CONFIG_PROC_MM
-+	case PTRACE_EX_FAULTINFO: {
-+		struct ptrace_ex_faultinfo fault;
-+
-+		fault = ((struct ptrace_ex_faultinfo)
-+			{ .is_write	= child->thread.error_code,
-+			  .addr		= child->thread.cr2,
-+			  .trap_no	= child->thread.trap_no });
-+		ret = copy_to_user((unsigned long *) data, &fault,
-+				   sizeof(fault));
-+		break;
-+	}
-+
-+	case PTRACE_FAULTINFO: {
-+		struct ptrace_faultinfo fault;
-+
-+		fault = ((struct ptrace_faultinfo)
-+			{ .is_write	= child->thread.error_code,
-+			  .addr		= child->thread.cr2 });
-+		ret = copy_to_user((unsigned long *) data, &fault,
-+				   sizeof(fault));
-+		break;
-+	}
-+
-+	case PTRACE_LDT: {
-+		struct ptrace_ldt ldt;
-+
-+		if(copy_from_user(&ldt, (unsigned long *) data,
-+				  sizeof(ldt))){
-+			ret = -EIO;
-+			break;
-+		}
-+		ret = __modify_ldt(child->mm, ldt.func, ldt.ptr, ldt.bytecount);
-+		break;
-+	}
-+
-+	case PTRACE_SWITCH_MM: {
-+		struct mm_struct *old = child->mm;
-+		struct mm_struct *new = proc_mm_get_mm(data);
-+
-+		if(IS_ERR(new)){
-+			ret = PTR_ERR(new);
-+			break;
-+		}
-+
-+		atomic_inc(&new->mm_users);
-+
-+		lock_fix_dumpable_setting(child, new);
-+
-+		child->mm = new;
-+		child->active_mm = new;
-+
-+		task_unlock(child);
-+
-+		mmput(old);
-+		ret = 0;
-+		break;
-+	}
-+#endif
-+
- 	default:
- 		ret = ptrace_request(child, request, addr, data);
- 		break;
-Index: linux-2.6.16/arch/i386/kernel/sys_i386.c
-===================================================================
---- linux-2.6.16.orig/arch/i386/kernel/sys_i386.c
-+++ linux-2.6.16/arch/i386/kernel/sys_i386.c
-@@ -41,7 +41,7 @@ asmlinkage int sys_pipe(unsigned long __
- }
- 
- /* common code for old and new mmaps */
--static inline long do_mmap2(
-+long do_mmap2(struct mm_struct *mm,
- 	unsigned long addr, unsigned long len,
- 	unsigned long prot, unsigned long flags,
- 	unsigned long fd, unsigned long pgoff)
-@@ -56,9 +56,9 @@ static inline long do_mmap2(
- 			goto out;
- 	}
- 
--	down_write(&current->mm->mmap_sem);
--	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
--	up_write(&current->mm->mmap_sem);
-+	down_write(&mm->mmap_sem);
-+	error = __do_mmap_pgoff(mm, file, addr, len, prot, flags, pgoff);
-+	up_write(&mm->mmap_sem);
- 
- 	if (file)
- 		fput(file);
-@@ -70,7 +70,12 @@ asmlinkage long sys_mmap2(unsigned long 
- 	unsigned long prot, unsigned long flags,
- 	unsigned long fd, unsigned long pgoff)
- {
--	return do_mmap2(addr, len, prot, flags, fd, pgoff);
-+	long ret = do_mmap2(current->mm, addr, len, prot, flags, fd, pgoff);
-+
-+	/* A tail call would reorder parameters on the stack and they would then
-+	 * be restored at the wrong places. */
-+	prevent_tail_call(ret);
-+	return ret;
- }
- 
- /*
-@@ -101,7 +106,10 @@ asmlinkage int old_mmap(struct mmap_arg_
- 	if (a.offset & ~PAGE_MASK)
- 		goto out;
- 
--	err = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
-+	err = do_mmap2(current->mm, a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
-+	/* A tail call would reorder parameters on the stack and they would then
-+	 * be restored at the wrong places. */
-+	prevent_tail_call(err);
- out:
- 	return err;
- }
-Index: linux-2.6.16/arch/um/include/skas_ptrace.h
-===================================================================
---- linux-2.6.16.orig/arch/um/include/skas_ptrace.h
-+++ linux-2.6.16/arch/um/include/skas_ptrace.h
-@@ -6,6 +6,8 @@
- #ifndef __SKAS_PTRACE_H
- #define __SKAS_PTRACE_H
- 
-+#ifndef PTRACE_FAULTINFO
-+
- #define PTRACE_FAULTINFO 52
- #define PTRACE_SWITCH_MM 55
- 
-@@ -13,6 +15,8 @@
- 
- #endif
- 
-+#endif
-+
- /*
-  * Overrides for Emacs so that we follow Linus's tabbing style.
-  * Emacs will notice this stuff at the end of the file and automatically
-Index: linux-2.6.16/arch/x86_64/ia32/ptrace32.c
-===================================================================
---- linux-2.6.16.orig/arch/x86_64/ia32/ptrace32.c
-+++ linux-2.6.16/arch/x86_64/ia32/ptrace32.c
-@@ -18,6 +18,8 @@
- #include <linux/unistd.h>
- #include <linux/mm.h>
- #include <linux/ptrace.h>
-+#include <linux/types.h>
-+#include <linux/proc_mm.h>
- #include <asm/ptrace.h>
- #include <asm/compat.h>
- #include <asm/uaccess.h>
-@@ -27,6 +29,7 @@
- #include <asm/debugreg.h>
- #include <asm/i387.h>
- #include <asm/fpu32.h>
-+#include <asm/desc.h>
- 
- /*
-  * Determines which flags the user has access to [1 = access, 0 = no access].
-@@ -224,6 +227,12 @@ asmlinkage long sys32_ptrace(long reques
- 	case PTRACE_SETFPXREGS:
- 	case PTRACE_GETFPXREGS:
- 	case PTRACE_GETEVENTMSG:
-+#ifdef CONFIG_PROC_MM
-+	case PTRACE_EX_FAULTINFO:
-+	case PTRACE_FAULTINFO:
-+	case PTRACE_LDT:
-+	case PTRACE_SWITCH_MM:
-+#endif
- 		break;
- 	} 
- 
-@@ -343,6 +352,65 @@ asmlinkage long sys32_ptrace(long reques
- 		ret = 0; 
- 		break;
- 	}
-+#ifdef CONFIG_PROC_MM
-+	case PTRACE_EX_FAULTINFO: {
-+		struct ptrace_ex_faultinfo32 fault;
-+
-+		fault = ((struct ptrace_ex_faultinfo32)
-+			{ .is_write	= (compat_int_t) child->thread.error_code,
-+			  .addr		= (compat_uptr_t) child->thread.cr2,
-+			  .trap_no	= (compat_int_t) child->thread.trap_no });
-+		ret = copy_to_user((unsigned long *) datap, &fault,
-+				   sizeof(fault));
-+		break;
-+	}
-+
-+	case PTRACE_FAULTINFO: {
-+		struct ptrace_faultinfo32 fault;
-+
-+		fault = ((struct ptrace_faultinfo32)
-+			{ .is_write	= (compat_int_t) child->thread.error_code,
-+			  .addr		= (compat_uptr_t) child->thread.cr2 });
-+		ret = copy_to_user((unsigned long *) datap, &fault,
-+				   sizeof(fault));
-+		break;
-+	}
-+
-+	case PTRACE_LDT: {
-+		struct ptrace_ldt32 ldt;
-+
-+		if(copy_from_user(&ldt, (unsigned long *) datap,
-+				  sizeof(ldt))){
-+			ret = -EIO;
-+			break;
-+		}
-+		ret = __modify_ldt(child->mm, ldt.func, compat_ptr(ldt.ptr), ldt.bytecount);
-+		break;
-+	}
-+
-+	case PTRACE_SWITCH_MM: {
-+		struct mm_struct *old = child->mm;
-+		struct mm_struct *new = proc_mm_get_mm(data);
-+
-+		if(IS_ERR(new)){
-+			ret = PTR_ERR(new);
-+			break;
-+		}
-+
-+		atomic_inc(&new->mm_users);
-+
-+		lock_fix_dumpable_setting(child, new);
-+
-+		child->mm = new;
-+		child->active_mm = new;
-+
-+		task_unlock(child);
-+
-+		mmput(old);
-+		ret = 0;
-+		break;
-+	}
-+#endif
- 
- 	case PTRACE_GETEVENTMSG:
- 		ret = put_user(child->ptrace_message,(unsigned int __user *)compat_ptr(data));
-Index: linux-2.6.16/arch/x86_64/ia32/sys_ia32.c
-===================================================================
---- linux-2.6.16.orig/arch/x86_64/ia32/sys_ia32.c
-+++ linux-2.6.16/arch/x86_64/ia32/sys_ia32.c
-@@ -855,11 +855,10 @@ sys32_adjtimex(struct timex32 __user *ut
- 	return ret;
- }
- 
--asmlinkage long sys32_mmap2(unsigned long addr, unsigned long len,
--	unsigned long prot, unsigned long flags,
-+long do32_mmap2(struct mm_struct *mm, unsigned long addr,
-+	unsigned long len, unsigned long prot, unsigned long flags,
- 	unsigned long fd, unsigned long pgoff)
- {
--	struct mm_struct *mm = current->mm;
- 	unsigned long error;
- 	struct file * file = NULL;
- 
-@@ -871,7 +870,7 @@ asmlinkage long sys32_mmap2(unsigned lon
- 	}
- 
- 	down_write(&mm->mmap_sem);
--	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-+	error = __do_mmap_pgoff(mm, file, addr, len, prot, flags, pgoff);
- 	up_write(&mm->mmap_sem);
- 
- 	if (file)
-@@ -879,6 +878,15 @@ asmlinkage long sys32_mmap2(unsigned lon
- 	return error;
- }
- 
-+/* XXX: this wrapper can be probably removed, we can simply use the 64-bit
-+ * version.*/
-+asmlinkage long sys32_mmap2(unsigned long addr, unsigned long len,
-+	unsigned long prot, unsigned long flags,
-+	unsigned long fd, unsigned long pgoff)
-+{
-+	return do32_mmap2(current->mm, addr, len, prot, flags, fd, pgoff);
-+}
-+
- asmlinkage long sys32_olduname(struct oldold_utsname __user * name)
- {
- 	int error;
-Index: linux-2.6.16/arch/x86_64/Kconfig
-===================================================================
---- linux-2.6.16.orig/arch/x86_64/Kconfig
-+++ linux-2.6.16/arch/x86_64/Kconfig
-@@ -378,6 +378,26 @@ config SWIOTLB
- 	default y
- 	depends on GART_IOMMU
- 
-+config PROC_MM
-+	bool "/proc/mm support"
-+	default y
-+
-+config PROC_MM_DUMPABLE
-+	bool "Make UML childs /proc/<pid> completely browsable"
-+	default n
-+	help
-+	  If in doubt, say N.
-+
-+	  This fiddles with some settings to make sure /proc/<pid> is completely
-+	  browsable by who started UML, at the expense of some additional
-+	  locking (maybe this could slow down the runned UMLs of a few percents,
-+	  I've not tested this).
-+
-+	  Also, if there is a bug in this feature, there is some little
-+	  possibility to do privilege escalation if you have UML installed
-+	  setuid (which you shouldn't have done) or if UML changes uid on
-+	  startup (which will be a good thing, when enabled) ...
-+
- config X86_MCE
- 	bool "Machine check support" if EMBEDDED
- 	default y
-Index: linux-2.6.16/arch/x86_64/kernel/ldt.c
-===================================================================
---- linux-2.6.16.orig/arch/x86_64/kernel/ldt.c
-+++ linux-2.6.16/arch/x86_64/kernel/ldt.c
-@@ -22,6 +22,7 @@
- #include <asm/ldt.h>
- #include <asm/desc.h>
- #include <asm/proto.h>
-+#include <asm/mmu_context.h>
- 
- #ifdef CONFIG_SMP /* avoids "defined but not used" warnig */
- static void flush_ldt(void *null)
-@@ -31,11 +32,12 @@ static void flush_ldt(void *null)
- }
- #endif
- 
--static int alloc_ldt(mm_context_t *pc, unsigned mincount, int reload)
-+static int alloc_ldt(struct mm_struct *mm, unsigned mincount, int reload)
- {
- 	void *oldldt;
- 	void *newldt;
- 	unsigned oldsize;
-+	mm_context_t * pc = &mm->context;
- 
- 	if (mincount <= (unsigned)pc->size)
- 		return 0;
-@@ -64,12 +66,14 @@ static int alloc_ldt(mm_context_t *pc, u
- 
- 		preempt_disable();
- 		mask = cpumask_of_cpu(smp_processor_id());
--		load_LDT(pc);
--		if (!cpus_equal(current->mm->cpu_vm_mask, mask))
-+		if (&current->active_mm->context == pc)
-+			load_LDT(pc);
-+		if (!cpus_equal(mm->cpu_vm_mask, mask))
- 			smp_call_function(flush_ldt, NULL, 1, 1);
- 		preempt_enable();
- #else
--		load_LDT(pc);
-+		if (&current->active_mm->context == pc)
-+			load_LDT(pc);
- #endif
- 	}
- 	if (oldsize) {
-@@ -81,12 +85,12 @@ static int alloc_ldt(mm_context_t *pc, u
- 	return 0;
- }
- 
--static inline int copy_ldt(mm_context_t *new, mm_context_t *old)
-+static inline int copy_ldt(struct mm_struct *new, struct mm_struct *old)
- {
--	int err = alloc_ldt(new, old->size, 0);
-+	int err = alloc_ldt(new, old->context.size, 0);
- 	if (err < 0)
- 		return err;
--	memcpy(new->ldt, old->ldt, old->size*LDT_ENTRY_SIZE);
-+	memcpy(new->context.ldt, old->context.ldt, old->context.size*LDT_ENTRY_SIZE);
- 	return 0;
- }
- 
-@@ -94,22 +98,24 @@ static inline int copy_ldt(mm_context_t 
-  * we do not have to muck with descriptors here, that is
-  * done in switch_mm() as needed.
-  */
--int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
-+int copy_context(struct mm_struct *mm, struct mm_struct *old_mm)
- {
--	struct mm_struct * old_mm;
- 	int retval = 0;
- 
--	init_MUTEX(&mm->context.sem);
--	mm->context.size = 0;
--	old_mm = current->mm;
- 	if (old_mm && old_mm->context.size > 0) {
- 		down(&old_mm->context.sem);
--		retval = copy_ldt(&mm->context, &old_mm->context);
-+		retval = copy_ldt(mm, old_mm);
- 		up(&old_mm->context.sem);
- 	}
- 	return retval;
- }
- 
-+int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
-+{
-+	init_new_empty_context(mm);
-+	return copy_context(mm, current->mm);
-+}
-+
- /*
-  * 
-  * Don't touch the LDT register - we're already in the next thread.
-@@ -125,11 +131,10 @@ void destroy_context(struct mm_struct *m
- 	}
- }
- 
--static int read_ldt(void __user * ptr, unsigned long bytecount)
-+static int read_ldt(struct mm_struct * mm, void __user * ptr, unsigned long bytecount)
- {
- 	int err;
- 	unsigned long size;
--	struct mm_struct * mm = current->mm;
- 
- 	if (!mm->context.size)
- 		return 0;
-@@ -170,10 +175,8 @@ static int read_default_ldt(void __user 
- 	return bytecount; 
- }
- 
--static int write_ldt(void __user * ptr, unsigned long bytecount, int oldmode)
-+static int write_ldt(struct mm_struct * mm, void __user * ptr, unsigned long bytecount, int oldmode)
- {
--	struct task_struct *me = current;
--	struct mm_struct * mm = me->mm;
- 	__u32 entry_1, entry_2, *lp;
- 	int error;
- 	struct user_desc ldt_info;
-@@ -198,7 +201,7 @@ static int write_ldt(void __user * ptr, 
- 
- 	down(&mm->context.sem);
- 	if (ldt_info.entry_number >= (unsigned)mm->context.size) {
--		error = alloc_ldt(&current->mm->context, ldt_info.entry_number+1, 1);
-+		error = alloc_ldt(mm, ldt_info.entry_number+1, 1);
- 		if (error < 0)
- 			goto out_unlock;
- 	}
-@@ -231,23 +234,29 @@ out:
- 	return error;
- }
- 
--asmlinkage int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
-+int __modify_ldt(struct mm_struct * mm, int func, void __user *ptr,
-+		unsigned long bytecount)
- {
- 	int ret = -ENOSYS;
- 
- 	switch (func) {
- 	case 0:
--		ret = read_ldt(ptr, bytecount);
-+		ret = read_ldt(mm, ptr, bytecount);
- 		break;
- 	case 1:
--		ret = write_ldt(ptr, bytecount, 1);
-+		ret = write_ldt(mm, ptr, bytecount, 1);
- 		break;
- 	case 2:
- 		ret = read_default_ldt(ptr, bytecount);
- 		break;
- 	case 0x11:
--		ret = write_ldt(ptr, bytecount, 0);
-+		ret = write_ldt(mm, ptr, bytecount, 0);
- 		break;
- 	}
- 	return ret;
- }
-+
-+asmlinkage int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
-+{
-+	return __modify_ldt(current->mm, func, ptr, bytecount);
-+}
-Index: linux-2.6.16/arch/x86_64/kernel/ptrace.c
-===================================================================
---- linux-2.6.16.orig/arch/x86_64/kernel/ptrace.c
-+++ linux-2.6.16/arch/x86_64/kernel/ptrace.c
-@@ -19,6 +19,7 @@
- #include <linux/audit.h>
- #include <linux/seccomp.h>
- #include <linux/signal.h>
-+#include <linux/proc_mm.h>
- 
- #include <asm/uaccess.h>
- #include <asm/pgtable.h>
-@@ -564,6 +565,75 @@ long arch_ptrace(struct task_struct *chi
- 		break;
- 	}
- 
-+#ifdef CONFIG_PROC_MM
-+	case PTRACE_EX_FAULTINFO: {
-+		struct ptrace_ex_faultinfo fault;
-+
-+		/* I checked in thread_struct comments that error_code and cr2
-+		 * are still part of the "fault info" section, so I guess that
-+		 * things are unchanged for now. Still to check manuals. BB*/
-+		fault = ((struct ptrace_ex_faultinfo)
-+			{ .is_write	= child->thread.error_code,
-+			  .addr		= child->thread.cr2,
-+			  .trap_no	= child->thread.trap_no });
-+		ret = copy_to_user((unsigned long *) data, &fault,
-+				   sizeof(fault));
-+		break;
-+	}
-+
-+	/*Don't extend this broken interface to x86-64*/
-+#if 0
-+	case PTRACE_FAULTINFO: {
-+		struct ptrace_faultinfo fault;
-+
-+		/* I checked in thread_struct comments that error_code and cr2
-+		 * are still part of the "fault info" section, so I guess that
-+		 * things are unchanged for now. Still to check manuals. BB*/
-+		fault = ((struct ptrace_faultinfo)
-+			{ .is_write	= child->thread.error_code,
-+			  .addr		= child->thread.cr2 });
-+		ret = copy_to_user((unsigned long *) data, &fault,
-+				   sizeof(fault));
-+		break;
-+	}
-+#endif
-+
-+	case PTRACE_LDT: {
-+		struct ptrace_ldt ldt;
-+
-+		if(copy_from_user(&ldt, (unsigned long *) data,
-+				  sizeof(ldt))){
-+			ret = -EIO;
-+			break;
-+		}
-+		ret = __modify_ldt(child->mm, ldt.func, ldt.ptr, ldt.bytecount);
-+		break;
-+	}
-+
-+	case PTRACE_SWITCH_MM: {
-+		struct mm_struct *old = child->mm;
-+		struct mm_struct *new = proc_mm_get_mm64(data);
-+
-+		if(IS_ERR(new)){
-+			ret = PTR_ERR(new);
-+			break;
-+		}
-+
-+		atomic_inc(&new->mm_users);
-+
-+		lock_fix_dumpable_setting(child, new);
-+
-+		child->mm = new;
-+		child->active_mm = new;
-+
-+		task_unlock(child);
-+
-+		mmput(old);
-+		ret = 0;
-+		break;
-+	}
-+#endif
-+
- 	default:
- 		ret = ptrace_request(child, request, addr, data);
- 		break;
-Index: linux-2.6.16/arch/x86_64/kernel/sys_x86_64.c
-===================================================================
---- linux-2.6.16.orig/arch/x86_64/kernel/sys_x86_64.c
-+++ linux-2.6.16/arch/x86_64/kernel/sys_x86_64.c
-@@ -19,6 +19,7 @@
- 
- #include <asm/uaccess.h>
- #include <asm/ia32.h>
-+#include <asm/proc_mm.h>
- 
- /*
-  * sys_pipe() is the normal C calling standard for creating
-@@ -37,7 +38,7 @@ asmlinkage long sys_pipe(int __user *fil
- 	return error;
- }
- 
--asmlinkage long sys_mmap(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags,
-+long do64_mmap(struct mm_struct *mm, unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags,
- 	unsigned long fd, unsigned long off)
- {
- 	long error;
-@@ -55,9 +56,9 @@ asmlinkage long sys_mmap(unsigned long a
- 		if (!file)
- 			goto out;
- 	}
--	down_write(&current->mm->mmap_sem);
--	error = do_mmap_pgoff(file, addr, len, prot, flags, off >> PAGE_SHIFT);
--	up_write(&current->mm->mmap_sem);
-+	down_write(&mm->mmap_sem);
-+	error = __do_mmap_pgoff(mm, file, addr, len, prot, flags, off >> PAGE_SHIFT);
-+	up_write(&mm->mmap_sem);
- 
- 	if (file)
- 		fput(file);
-@@ -65,6 +66,12 @@ out:
- 	return error;
- }
- 
-+asmlinkage long sys_mmap(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags,
-+	unsigned long fd, unsigned long off)
-+{
-+	return do64_mmap(current->mm, addr, len, prot, flags, fd, off);
-+}
-+
- static void find_start_end(unsigned long flags, unsigned long *begin,
- 			   unsigned long *end)
- {
-Index: linux-2.6.16/arch/x86_64/mm/Makefile
-===================================================================
---- linux-2.6.16.orig/arch/x86_64/mm/Makefile
-+++ linux-2.6.16/arch/x86_64/mm/Makefile
-@@ -7,5 +7,6 @@ obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpag
- obj-$(CONFIG_NUMA) += numa.o
- obj-$(CONFIG_K8_NUMA) += k8topology.o
- obj-$(CONFIG_ACPI_NUMA) += srat.o
-+obj-$(CONFIG_PROC_MM) += proc_mm.o
- 
- hugetlbpage-y = ../../i386/mm/hugetlbpage.o
-Index: linux-2.6.16/arch/x86_64/mm/proc_mm.c
-===================================================================
---- /dev/null
-+++ linux-2.6.16/arch/x86_64/mm/proc_mm.c
-@@ -0,0 +1,85 @@
-+#include <linux/proc_mm.h>
-+#include <linux/mm.h>
-+#include <linux/init.h>
-+#include <linux/proc_fs.h>
-+#include <linux/file.h>
-+#include <linux/mman.h>
-+#include <asm/uaccess.h>
-+#include <asm/mmu_context.h>
-+
-+ssize_t write_proc_mm_emul(struct file *file, const char *buffer,
-+			     size_t count, loff_t *ppos)
-+{
-+	struct mm_struct *mm = file->private_data;
-+	struct proc_mm_op32 req;
-+	int n, ret;
-+
-+	if(count > sizeof(req))
-+		return(-EINVAL);
-+
-+	n = copy_from_user(&req, buffer, count);
-+	if(n != 0)
-+		return(-EFAULT);
-+
-+	ret = count;
-+	switch(req.op){
-+	case MM_MMAP: {
-+		struct mm_mmap32 *map = &req.u.mmap;
-+
-+		/* Nobody ever noticed it, but do_mmap_pgoff() calls
-+		 * get_unmapped_area() which checks current->mm, if
-+		 * MAP_FIXED is not set, so mmap() could replace
-+		 * an old mapping.
-+		 */
-+		if (! (map->flags & MAP_FIXED))
-+			return(-EINVAL);
-+
-+		ret = __do_mmap(mm, map->addr, map->len, map->prot,
-+			       map->flags, map->fd, map->offset);
-+		if((ret & ~PAGE_MASK) == 0)
-+			ret = count;
-+
-+		break;
-+	}
-+	case MM_MUNMAP: {
-+		struct mm_munmap32 *unmap = &req.u.munmap;
-+
-+		down_write(&mm->mmap_sem);
-+		ret = do_munmap(mm, unmap->addr, unmap->len);
-+		up_write(&mm->mmap_sem);
-+
-+		if(ret == 0)
-+			ret = count;
-+		break;
-+	}
-+	case MM_MPROTECT: {
-+		struct mm_mprotect32 *protect = &req.u.mprotect;
-+
-+		ret = do_mprotect(mm, protect->addr, protect->len,
-+				  protect->prot);
-+		if(ret == 0)
-+			ret = count;
-+		break;
-+	}
-+
-+	case MM_COPY_SEGMENTS: {
-+		struct mm_struct *from = proc_mm_get_mm_emul(req.u.copy_segments);
-+
-+		if(IS_ERR(from)){
-+			ret = PTR_ERR(from);
-+			break;
-+		}
-+
-+		ret = copy_context(mm, from);
-+		if(ret == 0)
-+			ret = count;
-+		break;
-+	}
-+	default:
-+		ret = -EINVAL;
-+		break;
-+	}
-+
-+	return ret;
-+}
-+
-Index: linux-2.6.16/include/asm-i386/desc.h
-===================================================================
---- linux-2.6.16.orig/include/asm-i386/desc.h
-+++ linux-2.6.16/include/asm-i386/desc.h
-@@ -162,6 +162,9 @@ static inline unsigned long get_desc_bas
- 	return base;
- }
- 
-+extern int __modify_ldt(struct mm_struct * mm, int func, void __user *ptr,
-+		      unsigned long bytecount);
-+
- #endif /* !__ASSEMBLY__ */
- 
- #endif
-Index: linux-2.6.16/include/asm-i386/mmu_context.h
-===================================================================
---- linux-2.6.16.orig/include/asm-i386/mmu_context.h
-+++ linux-2.6.16/include/asm-i386/mmu_context.h
-@@ -6,13 +6,25 @@
- #include <asm/atomic.h>
- #include <asm/pgalloc.h>
- #include <asm/tlbflush.h>
-+#include <asm/semaphore.h>
- 
- /*
-- * Used for LDT copy/destruction.
-+ * Used for LDT initialization/destruction. You cannot copy an LDT with
-+ * init_new_context, since it thinks you are passing it a new LDT and won't
-+ * deallocate its old content.
-  */
- int init_new_context(struct task_struct *tsk, struct mm_struct *mm);
- void destroy_context(struct mm_struct *mm);
- 
-+/* LDT initialization for a clean environment - needed for SKAS.*/
-+static inline void init_new_empty_context(struct mm_struct *mm)
-+{
-+	init_MUTEX(&mm->context.sem);
-+	mm->context.size = 0;
-+}
-+
-+/* LDT copy for SKAS - for the above problem.*/
-+int copy_context(struct mm_struct *mm, struct mm_struct *old_mm);
- 
- static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
- {
-@@ -29,6 +41,10 @@ static inline void switch_mm(struct mm_s
- {
- 	int cpu = smp_processor_id();
- 
-+#ifdef CONFIG_SMP
-+	prev = per_cpu(cpu_tlbstate, cpu).active_mm;
-+#endif
-+
- 	if (likely(prev != next)) {
- 		/* stop flush ipis for the previous mm */
- 		cpu_clear(cpu, prev->cpu_vm_mask);
-@@ -50,7 +66,6 @@ static inline void switch_mm(struct mm_s
- #ifdef CONFIG_SMP
- 	else {
- 		per_cpu(cpu_tlbstate, cpu).state = TLBSTATE_OK;
--		BUG_ON(per_cpu(cpu_tlbstate, cpu).active_mm != next);
- 
- 		if (!cpu_test_and_set(cpu, next->cpu_vm_mask)) {
- 			/* We were in lazy tlb mode and leave_mm disabled 
-Index: linux-2.6.16/include/asm-i386/proc_mm.h
-===================================================================
---- /dev/null
-+++ linux-2.6.16/include/asm-i386/proc_mm.h
-@@ -0,0 +1,18 @@
-+#ifndef __ASM_PROC_MM
-+#define __ASM_PROC_MM
-+
-+#include <asm/page.h>
-+
-+extern long do_mmap2(struct mm_struct *mm, unsigned long addr,
-+		unsigned long len, unsigned long prot, unsigned long flags,
-+		unsigned long fd, unsigned long pgoff);
-+
-+static inline long __do_mmap(struct mm_struct *mm, unsigned long addr,
-+		     unsigned long len, unsigned long prot,
-+		     unsigned long flags, unsigned long fd,
-+		     unsigned long off)
-+{
-+	return do_mmap2(mm, addr, len, prot, flags, fd, off >> PAGE_SHIFT);
-+}
-+
-+#endif /* __ASM_PROC_MM */
-Index: linux-2.6.16/include/asm-i386/ptrace.h
-===================================================================
---- linux-2.6.16.orig/include/asm-i386/ptrace.h
-+++ linux-2.6.16/include/asm-i386/ptrace.h
-@@ -87,4 +87,33 @@ extern unsigned long profile_pc(struct p
- #endif
- #endif /* __KERNEL__ */
- 
-+/*For SKAS3 support.*/
-+#ifndef _LINUX_PTRACE_STRUCT_DEF
-+#define _LINUX_PTRACE_STRUCT_DEF
-+
-+#define PTRACE_FAULTINFO	  52
-+/* 53 was used for PTRACE_SIGPENDING, don't reuse it. */
-+#define PTRACE_LDT		  54
-+#define PTRACE_SWITCH_MM 	  55
-+#define PTRACE_EX_FAULTINFO	  56
-+
-+struct ptrace_faultinfo {
-+	int is_write;
-+	unsigned long addr;
-+};
-+
-+struct ptrace_ex_faultinfo {
-+	int is_write;
-+	unsigned long addr;
-+	int trap_no;
-+};
-+
-+struct ptrace_ldt {
-+	int func;
-+  	void *ptr;
-+	unsigned long bytecount;
-+};
-+
-+#endif /*ifndef _LINUX_PTRACE_STRUCT_DEF*/
-+
- #endif
-Index: linux-2.6.16/include/asm-x86_64/desc.h
-===================================================================
---- linux-2.6.16.orig/include/asm-x86_64/desc.h
-+++ linux-2.6.16/include/asm-x86_64/desc.h
-@@ -233,6 +233,9 @@ static inline void load_LDT(mm_context_t
- 
- extern struct desc_ptr idt_descr;
- 
-+extern int __modify_ldt(struct mm_struct * mm, int func, void __user *ptr,
-+		unsigned long bytecount);
-+
- #endif /* !__ASSEMBLY__ */
- 
- #endif
-Index: linux-2.6.16/include/asm-x86_64/mmu_context.h
-===================================================================
---- linux-2.6.16.orig/include/asm-x86_64/mmu_context.h
-+++ linux-2.6.16/include/asm-x86_64/mmu_context.h
-@@ -8,13 +8,28 @@
- #include <asm/pda.h>
- #include <asm/pgtable.h>
- #include <asm/tlbflush.h>
-+#include <asm/semaphore.h>
- 
- /*
-  * possibly do the LDT unload here?
-+ * Used for LDT initialization/destruction. You cannot copy an LDT with
-+ * init_new_context, since it thinks you are passing it a new LDT and won't
-+ * deallocate its old content.
-  */
-+
- int init_new_context(struct task_struct *tsk, struct mm_struct *mm);
- void destroy_context(struct mm_struct *mm);
- 
-+/* LDT initialization for a clean environment - needed for SKAS.*/
-+static inline void init_new_empty_context(struct mm_struct *mm)
-+{
-+	init_MUTEX(&mm->context.sem);
-+	mm->context.size = 0;
-+}
-+
-+/* LDT copy for SKAS - for the above problem.*/
-+int copy_context(struct mm_struct *mm, struct mm_struct *old_mm);
-+
- static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
- {
- #ifdef CONFIG_SMP
-@@ -32,6 +47,9 @@ static inline void switch_mm(struct mm_s
- 			     struct task_struct *tsk)
- {
- 	unsigned cpu = smp_processor_id();
-+#ifdef CONFIG_SMP
-+	prev = read_pda(active_mm);
-+#endif
- 	if (likely(prev != next)) {
- 		/* stop flush ipis for the previous mm */
- 		clear_bit(cpu, &prev->cpu_vm_mask);
-@@ -48,8 +66,6 @@ static inline void switch_mm(struct mm_s
- #ifdef CONFIG_SMP
- 	else {
- 		write_pda(mmu_state, TLBSTATE_OK);
--		if (read_pda(active_mm) != next)
--			out_of_line_bug();
- 		if(!test_and_set_bit(cpu, &next->cpu_vm_mask)) {
- 			/* We were in lazy tlb mode and leave_mm disabled 
- 			 * tlb flush IPI delivery. We must reload CR3
-Index: linux-2.6.16/include/asm-x86_64/proc_mm.h
-===================================================================
---- /dev/null
-+++ linux-2.6.16/include/asm-x86_64/proc_mm.h
-@@ -0,0 +1,58 @@
-+#ifndef __ASM_PROC_MM
-+#define __ASM_PROC_MM
-+#include <linux/types.h>
-+
-+#include <asm/compat.h>
-+
-+struct mm_mmap32 {
-+	compat_ulong_t addr;
-+	compat_ulong_t len;
-+	compat_ulong_t prot;
-+	compat_ulong_t flags;
-+	compat_ulong_t fd;
-+	compat_ulong_t offset;
-+};
-+
-+struct mm_munmap32 {
-+	compat_ulong_t addr;
-+	compat_ulong_t len;
-+};
-+
-+struct mm_mprotect32 {
-+	compat_ulong_t addr;
-+	compat_ulong_t len;
-+        compat_uint_t prot;
-+};
-+
-+struct proc_mm_op32 {
-+	compat_int_t op;
-+	union {
-+		struct mm_mmap32 mmap;
-+		struct mm_munmap32 munmap;
-+	        struct mm_mprotect32 mprotect;
-+		compat_int_t copy_segments;
-+	} u;
-+};
-+
-+extern ssize_t write_proc_mm_emul(struct file *file, const char *buffer,
-+			     size_t count, loff_t *ppos);
-+
-+extern struct mm_struct *proc_mm_get_mm64(int fd);
-+
-+extern long do64_mmap(struct mm_struct *mm, unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags,
-+	unsigned long fd, unsigned long off);
-+
-+static inline long __do_mmap(struct mm_struct *mm, unsigned long addr,
-+		     unsigned long len, unsigned long prot,
-+		     unsigned long flags, unsigned long fd,
-+		     unsigned long off)
-+{
-+	/* The latter one is stricter, since will actually check that off is page
-+	 * aligned. The first one skipped the check. */
-+
-+	/* return do32_mmap2(mm, addr, len, prot, flags, fd, off >>
-+	 * PAGE_SHIFT);*/
-+	return do64_mmap(mm, addr, len, prot, flags, fd, off);
-+}
-+
-+#endif /* __ASM_PROC_MM */
-Index: linux-2.6.16/include/asm-x86_64/ptrace.h
-===================================================================
---- linux-2.6.16.orig/include/asm-x86_64/ptrace.h
-+++ linux-2.6.16/include/asm-x86_64/ptrace.h
-@@ -64,6 +64,59 @@ struct pt_regs {
- /* top of stack page */ 
- };
- 
-+/* Stolen from
-+#include <linux/compat.h>; we can't include it because
-+there is a nasty ciclic include chain.
-+*/
-+
-+#include <asm/types.h>
-+
-+#define		compat_int_t	s32
-+#define		compat_long_t	s32
-+#define		compat_uint_t	u32
-+#define		compat_ulong_t	u32
-+#define		compat_uptr_t	u32
-+
-+struct ptrace_faultinfo32 {
-+	compat_int_t is_write;
-+	compat_ulong_t addr;
-+};
-+
-+struct ptrace_ex_faultinfo32 {
-+	compat_int_t is_write;
-+	compat_ulong_t addr;
-+	compat_int_t trap_no;
-+};
-+
-+struct ptrace_ldt32 {
-+	compat_int_t func;
-+	compat_uptr_t ptr; /*Actually a void pointer on i386, but must be converted.*/
-+	compat_ulong_t bytecount;
-+};
-+
-+struct ptrace_faultinfo {
-+	int is_write;
-+	unsigned long addr;
-+};
-+
-+struct ptrace_ex_faultinfo {
-+	int is_write;
-+	unsigned long addr;
-+	int trap_no;
-+};
-+
-+struct ptrace_ldt {
-+	int func;
-+  	void *ptr;
-+	unsigned long bytecount;
-+};
-+
-+#undef	compat_int_t
-+#undef	compat_long_t
-+#undef	compat_uint_t
-+#undef	compat_ulong_t
-+#undef	compat_uptr_t
-+
- #endif
- 
- /* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
-@@ -74,6 +127,12 @@ struct pt_regs {
- #define PTRACE_GETFPXREGS         18
- #define PTRACE_SETFPXREGS         19
- 
-+#define PTRACE_FAULTINFO 52
-+/* 53 was used for PTRACE_SIGPENDING, don't reuse it. */
-+#define PTRACE_LDT 54
-+#define PTRACE_SWITCH_MM 55
-+#define PTRACE_EX_FAULTINFO	  56
-+
- /* only useful for access 32bit programs */
- #define PTRACE_GET_THREAD_AREA    25
- #define PTRACE_SET_THREAD_AREA    26
-Index: linux-2.6.16/include/linux/mm.h
-===================================================================
---- linux-2.6.16.orig/include/linux/mm.h
-+++ linux-2.6.16/include/linux/mm.h
-@@ -918,9 +918,15 @@ extern int may_expand_vm(struct mm_struc
- 
- extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
- 
--extern unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
-+extern unsigned long __do_mmap_pgoff(struct mm_struct *mm, struct file *file,
-+				   unsigned long addr, unsigned long len,
-+				   unsigned long prot, unsigned long flag,
-+				   unsigned long pgoff);
-+static inline unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
- 	unsigned long len, unsigned long prot,
--	unsigned long flag, unsigned long pgoff);
-+	unsigned long flag, unsigned long pgoff) {
-+	return __do_mmap_pgoff(current->mm, file, addr, len, prot, flag, pgoff);
-+}
- 
- static inline unsigned long do_mmap(struct file *file, unsigned long addr,
- 	unsigned long len, unsigned long prot,
-@@ -937,6 +943,9 @@ out:
- 
- extern int do_munmap(struct mm_struct *, unsigned long, size_t);
- 
-+extern long do_mprotect(struct mm_struct *mm, unsigned long start,
-+			size_t len, unsigned long prot);
-+
- extern unsigned long do_brk(unsigned long, unsigned long);
- 
- /* filemap.c */
-Index: linux-2.6.16/include/linux/proc_mm.h
-===================================================================
---- /dev/null
-+++ linux-2.6.16/include/linux/proc_mm.h
-@@ -0,0 +1,114 @@
-+/*
-+ * Copyright (C) 2002 Jeff Dike (jdike at karaya.com)
-+ * Licensed under the GPL
-+ */
-+
-+#ifndef __PROC_MM_H
-+#define __PROC_MM_H
-+
-+#include <linux/config.h>
-+#include <linux/sched.h>
-+#include <linux/compiler.h>
-+
-+/* The differences between this one and do_mmap are that:
-+ * - we must perform controls for userspace-supplied params (which are
-+ *   arch-specific currently). And also fget(fd) if needed and so on...
-+ * - we must accept the struct mm_struct on which to act as first param, and the
-+ *   offset in byte rather than page units as last param.
-+ */
-+static inline long __do_mmap(struct mm_struct *mm, unsigned long addr,
-+		     unsigned long len, unsigned long prot,
-+		     unsigned long flags, unsigned long fd,
-+		     unsigned long off);
-+
-+/* This header can be used only on archs defining CONFIG_PROC_MM in their
-+ * configs, so asm/proc_mm.h can still exist only for the needed archs.
-+ * Including it only in the x86-64 case does not make sense.*/
-+#include <asm/proc_mm.h>
-+
-+/*XXX: this is defined on x86_64, but not on every 64-bit arch (not on sh64).*/
-+#ifdef CONFIG_64BIT
-+
-+#define write_proc_mm write_proc_mm_emul
-+#define write_proc_mm64 write_proc_mm_native
-+
-+/* It would make more sense to do this mapping the reverse direction, to map the
-+ * called name to the defined one and not the reverse. Like the 2nd example
-+ */
-+/*#define proc_mm_get_mm proc_mm_get_mm_emul
-+#define proc_mm_get_mm64 proc_mm_get_mm_native*/
-+
-+#define proc_mm_get_mm_emul proc_mm_get_mm
-+#define proc_mm_get_mm_native proc_mm_get_mm64
-+
-+#else
-+
-+#define write_proc_mm write_proc_mm_native
-+#undef write_proc_mm64
-+
-+/*#define proc_mm_get_mm proc_mm_get_mm_native
-+#undef proc_mm_get_mm64*/
-+
-+#define proc_mm_get_mm_native proc_mm_get_mm
-+#undef proc_mm_get_mm_emul
-+
-+#endif
-+
-+#define MM_MMAP 54
-+#define MM_MUNMAP 55
-+#define MM_MPROTECT 56
-+#define MM_COPY_SEGMENTS 57
-+
-+struct mm_mmap {
-+	unsigned long addr;
-+	unsigned long len;
-+	unsigned long prot;
-+	unsigned long flags;
-+	unsigned long fd;
-+	unsigned long offset;
-+};
-+
-+struct mm_munmap {
-+	unsigned long addr;
-+	unsigned long len;
-+};
-+
-+struct mm_mprotect {
-+	unsigned long addr;
-+	unsigned long len;
-+        unsigned int prot;
-+};
-+
-+struct proc_mm_op {
-+	int op;
-+	union {
-+		struct mm_mmap mmap;
-+		struct mm_munmap munmap;
-+	        struct mm_mprotect mprotect;
-+		int copy_segments;
-+	} u;
-+};
-+
-+extern struct mm_struct *proc_mm_get_mm(int fd);
-+
-+/* Cope with older kernels */
-+#ifndef __acquires
-+#define __acquires(x)
-+#endif
-+
-+#ifdef CONFIG_PROC_MM_DUMPABLE
-+/*
-+ * Since we take task_lock of child and it's needed also by the caller, we
-+ * return with it locked.
-+ */
-+extern void lock_fix_dumpable_setting(struct task_struct * child,
-+		struct mm_struct* new) __acquires(child->alloc_lock);
-+#else
-+static inline void lock_fix_dumpable_setting(struct task_struct * child,
-+		struct mm_struct* new) __acquires(child->alloc_lock)
-+{
-+	task_lock(child);
-+}
-+#endif
-+
-+#endif
-Index: linux-2.6.16/localversion-skas
-===================================================================
---- /dev/null
-+++ linux-2.6.16/localversion-skas
-@@ -0,0 +1 @@
-+-skas3-v9-pre9
-Index: linux-2.6.16/mm/Makefile
-===================================================================
---- linux-2.6.16.orig/mm/Makefile
-+++ linux-2.6.16/mm/Makefile
-@@ -22,3 +22,9 @@ obj-$(CONFIG_SLOB) += slob.o
- obj-$(CONFIG_SLAB) += slab.o
- obj-$(CONFIG_MEMORY_HOTPLUG) += memory_hotplug.o
- obj-$(CONFIG_FS_XIP) += filemap_xip.o
-+
-+obj-$(CONFIG_PROC_MM)	+= proc_mm.o
-+
-+ifeq ($(CONFIG_PROC_MM),y)
-+obj-m			+= proc_mm-mod.o
-+endif
-Index: linux-2.6.16/mm/mmap.c
-===================================================================
---- linux-2.6.16.orig/mm/mmap.c
-+++ linux-2.6.16/mm/mmap.c
-@@ -868,11 +868,11 @@ void vm_stat_account(struct mm_struct *m
-  * The caller must hold down_write(current->mm->mmap_sem).
-  */
- 
--unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
--			unsigned long len, unsigned long prot,
--			unsigned long flags, unsigned long pgoff)
-+unsigned long __do_mmap_pgoff(struct mm_struct *mm, struct file * file,
-+			    unsigned long addr, unsigned long len,
-+			    unsigned long prot, unsigned long flags,
-+			    unsigned long pgoff)
- {
--	struct mm_struct * mm = current->mm;
- 	struct vm_area_struct * vma, * prev;
- 	struct inode *inode;
- 	unsigned int vm_flags;
-@@ -1147,7 +1147,7 @@ unacct_error:
- 	return error;
- }
- 
--EXPORT_SYMBOL(do_mmap_pgoff);
-+EXPORT_SYMBOL(__do_mmap_pgoff);
- 
- /* Get an address range which is currently unmapped.
-  * For shmat() with addr=0.
-Index: linux-2.6.16/mm/mprotect.c
-===================================================================
---- linux-2.6.16.orig/mm/mprotect.c
-+++ linux-2.6.16/mm/mprotect.c
-@@ -176,8 +176,9 @@ fail:
- 	return error;
- }
- 
--asmlinkage long
--sys_mprotect(unsigned long start, size_t len, unsigned long prot)
-+long
-+do_mprotect(struct mm_struct *mm, unsigned long start, size_t len,
-+	     unsigned long prot)
- {
- 	unsigned long vm_flags, nstart, end, tmp, reqprot;
- 	struct vm_area_struct *vma, *prev;
-@@ -208,9 +209,9 @@ sys_mprotect(unsigned long start, size_t
- 
- 	vm_flags = calc_vm_prot_bits(prot);
- 
--	down_write(&current->mm->mmap_sem);
-+	down_write(&mm->mmap_sem);
- 
--	vma = find_vma_prev(current->mm, start, &prev);
-+	vma = find_vma_prev(mm, start, &prev);
- 	error = -ENOMEM;
- 	if (!vma)
- 		goto out;
-@@ -277,6 +278,15 @@ sys_mprotect(unsigned long start, size_t
- 		}
- 	}
- out:
--	up_write(&current->mm->mmap_sem);
-+	up_write(&mm->mmap_sem);
- 	return error;
- }
-+
-+asmlinkage long sys_mprotect(unsigned long start, size_t len, unsigned long prot)
-+{
-+	long ret = do_mprotect(current->mm, start, len, prot);
-+	/* A tail call would reorder parameters on the stack and they would then
-+	 * be restored at the wrong places. */
-+	prevent_tail_call(ret);
-+	return ret;
-+}
-Index: linux-2.6.16/mm/proc_mm.c
-===================================================================
---- /dev/null
-+++ linux-2.6.16/mm/proc_mm.c
-@@ -0,0 +1,300 @@
-+/*
-+ * Copyright (C) 2002 Jeff Dike (jdike at karaya.com)
-+ * Licensed under the GPL
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/compiler.h>
-+#include <linux/mm.h>
-+#include <linux/init.h>
-+#include <linux/proc_fs.h>
-+#include <linux/proc_mm.h>
-+#include <linux/file.h>
-+#include <linux/mman.h>
-+#include <asm/uaccess.h>
-+#include <asm/mmu_context.h>
-+
-+#ifdef CONFIG_PROC_MM_DUMPABLE
-+/* Checks if a task must be considered dumpable
-+ *
-+ * XXX: copied from fs/proc/base.c, removed task_lock, added rmb(): this must be
-+ * called with task_lock(task) held. */
-+static int task_dumpable(struct task_struct *task)
-+{
-+	int dumpable = 0;
-+	struct mm_struct *mm;
-+
-+	mm = task->mm;
-+	if (mm) {
-+		rmb();
-+		dumpable = mm->dumpable;
-+	}
-+	return dumpable;
-+}
-+
-+/*
-+ * This is to be used in PTRACE_SWITCH_MM handling. We are going to set
-+ * child->mm to new, and we must first correctly set new->dumpable.
-+ * Since we take task_lock of child and it's needed also by the caller, we
-+ * return with it locked.
-+ */
-+void lock_fix_dumpable_setting(struct task_struct* child, struct mm_struct* new)
-+	__acquires(child->alloc_lock)
-+{
-+	int dumpable = 1;
-+
-+	/* We must be safe.
-+	 * If the child is ptraced from a non-dumpable process,
-+	 * let's not be dumpable. If the child is non-dumpable itself,
-+	 * copy this property across mm's.
-+	 *
-+	 * Don't try to be smart for the opposite case and turn
-+	 * child->mm->dumpable to 1: I've not made sure it is safe.
-+	 */
-+
-+	task_lock(current);
-+	if (unlikely(!task_dumpable(current))) {
-+		dumpable = 0;
-+	}
-+	task_unlock(current);
-+
-+	task_lock(child);
-+	if (likely(dumpable) && unlikely(!task_dumpable(child))) {
-+		dumpable = 0;
-+	}
-+
-+	if (!dumpable) {
-+		new->dumpable = 0;
-+		wmb();
-+	}
-+}
-+#endif
-+
-+/* Naming conventions are a mess, so I note them down.
-+ *
-+ * Things ending in _mm can be for everything. It's only for
-+ * {open,release}_proc_mm.
-+ *
-+ * For the rest:
-+ *
-+ * _mm means /proc/mm, _mm64 means /proc/mm64. This is for the infrastructure
-+ * only (for instance proc_mm_get_mm checks whether the file is /proc/mm or
-+ * /proc/mm64; for instance the /proc handling).
-+ *
-+ * While for what is conversion dependant, we use the suffix _native and _emul.
-+ * In some cases, there is a mapping between these ones (defined by
-+ * <asm/proc_mm.h>).
-+ */
-+
-+/*These two are common to everything.*/
-+static int open_proc_mm(struct inode *inode, struct file *file)
-+{
-+	struct mm_struct *mm = mm_alloc();
-+	int ret;
-+
-+	ret = -ENOMEM;
-+	if(mm == NULL)
-+		goto out_mem;
-+
-+	init_new_empty_context(mm);
-+	arch_pick_mmap_layout(mm);
-+#ifdef CONFIG_PROC_MM_DUMPABLE
-+	mm->dumpable = current->mm->dumpable;
-+	wmb();
-+#endif
-+
-+	file->private_data = mm;
-+
-+	return 0;
-+
-+out_mem:
-+	return ret;
-+}
-+
-+static int release_proc_mm(struct inode *inode, struct file *file)
-+{
-+	struct mm_struct *mm = file->private_data;
-+
-+	mmput(mm);
-+	return 0;
-+}
-+
-+static struct file_operations proc_mm_fops;
-+
-+struct mm_struct *proc_mm_get_mm_native(int fd);
-+
-+static ssize_t write_proc_mm_native(struct file *file, const char *buffer,
-+			     size_t count, loff_t *ppos)
-+{
-+	struct mm_struct *mm = file->private_data;
-+	struct proc_mm_op req;
-+	int n, ret;
-+
-+	if(count > sizeof(req))
-+		return(-EINVAL);
-+
-+	n = copy_from_user(&req, buffer, count);
-+	if(n != 0)
-+		return(-EFAULT);
-+
-+	ret = count;
-+	switch(req.op){
-+	case MM_MMAP: {
-+		struct mm_mmap *map = &req.u.mmap;
-+
-+		/* Nobody ever noticed it, but do_mmap_pgoff() calls
-+		 * get_unmapped_area() which checks current->mm, if
-+		 * MAP_FIXED is not set, so mmap() could replace
-+		 * an old mapping.
-+		 */
-+		if (! (map->flags & MAP_FIXED))
-+			return(-EINVAL);
-+
-+		ret = __do_mmap(mm, map->addr, map->len, map->prot,
-+			       map->flags, map->fd, map->offset);
-+		if((ret & ~PAGE_MASK) == 0)
-+			ret = count;
-+
-+		break;
-+	}
-+	case MM_MUNMAP: {
-+		struct mm_munmap *unmap = &req.u.munmap;
-+
-+		down_write(&mm->mmap_sem);
-+		ret = do_munmap(mm, unmap->addr, unmap->len);
-+		up_write(&mm->mmap_sem);
-+
-+		if(ret == 0)
-+			ret = count;
-+		break;
-+	}
-+	case MM_MPROTECT: {
-+		struct mm_mprotect *protect = &req.u.mprotect;
-+
-+		ret = do_mprotect(mm, protect->addr, protect->len,
-+				  protect->prot);
-+		if(ret == 0)
-+			ret = count;
-+		break;
-+	}
-+
-+	case MM_COPY_SEGMENTS: {
-+		struct mm_struct *from = proc_mm_get_mm_native(req.u.copy_segments);
-+
-+		if(IS_ERR(from)){
-+			ret = PTR_ERR(from);
-+			break;
-+		}
-+
-+		ret = copy_context(mm, from);
-+		if(ret == 0)
-+			ret = count;
-+		break;
-+	}
-+	default:
-+		ret = -EINVAL;
-+		break;
-+	}
-+
-+	return ret;
-+}
-+
-+/*These three are all for /proc/mm.*/
-+struct mm_struct *proc_mm_get_mm(int fd)
-+{
-+	struct mm_struct *ret = ERR_PTR(-EBADF);
-+	struct file *file;
-+
-+	file = fget(fd);
-+	if (!file)
-+		goto out;
-+
-+	ret = ERR_PTR(-EINVAL);
-+	if(file->f_op != &proc_mm_fops)
-+		goto out_fput;
-+
-+	ret = file->private_data;
-+out_fput:
-+	fput(file);
-+out:
-+	return(ret);
-+}
-+
-+static struct file_operations proc_mm_fops = {
-+	.open		= open_proc_mm,
-+	.release	= release_proc_mm,
-+	.write		= write_proc_mm,
-+};
-+
-+/*Macro-ify it to avoid the duplication.*/
-+static int make_proc_mm(void)
-+{
-+	struct proc_dir_entry *ent;
-+
-+	ent = create_proc_entry("mm", 0222, &proc_root);
-+	if(ent == NULL){
-+		printk("make_proc_mm : Failed to register /proc/mm\n");
-+		return(0);
-+	}
-+	ent->proc_fops = &proc_mm_fops;
-+
-+	return 0;
-+}
-+
-+__initcall(make_proc_mm);
-+
-+/*XXX: change the option.*/
-+#ifdef CONFIG_64BIT
-+static struct file_operations proc_mm64_fops = {
-+	.open		= open_proc_mm,
-+	.release	= release_proc_mm,
-+	.write		= write_proc_mm64,
-+};
-+
-+static int make_proc_mm64(void)
-+{
-+	struct proc_dir_entry *ent;
-+
-+	ent = create_proc_entry("mm64", 0222, &proc_root);
-+	if(ent == NULL){
-+		printk("make_proc_mm : Failed to register /proc/mm64\n");
-+		return(0);
-+	}
-+	ent->proc_fops = &proc_mm64_fops;
-+
-+	return 0;
-+}
-+
-+__initcall(make_proc_mm64);
-+
-+struct mm_struct *proc_mm_get_mm64(int fd)
-+{
-+	struct mm_struct *ret = ERR_PTR(-EBADF);
-+	struct file *file;
-+
-+	file = fget(fd);
-+	if (!file)
-+		goto out;
-+
-+	ret = ERR_PTR(-EINVAL);
-+	/*This is the only change.*/
-+	if(file->f_op != &proc_mm64_fops)
-+		goto out_fput;
-+
-+	ret = file->private_data;
-+out_fput:
-+	fput(file);
-+out:
-+	return(ret);
-+}
-+#endif
-+/*
-+ * Overrides for Emacs so that we follow Linus's tabbing style.
-+ * Emacs will notice this stuff at the end of the file and automatically
-+ * adjust the settings for this buffer only.  This must remain at the end
-+ * of the file.
-+ * ---------------------------------------------------------------------------
-+ * Local variables:
-+ * c-file-style: "linux"
-+ * End:
-+ */
-Index: linux-2.6.16/mm/proc_mm-mod.c
-===================================================================
---- /dev/null
-+++ linux-2.6.16/mm/proc_mm-mod.c
-@@ -0,0 +1,51 @@
-+#include <linux/config.h>
-+#include <linux/kernel.h>
-+#include <linux/proc_mm.h>
-+#include <linux/ptrace.h>
-+#include <linux/module.h>
-+
-+#ifdef CONFIG_64BIT
-+#define PRINT_OFFSET(type, member) \
-+	printk(KERN_DEBUG "struct " #type "32->" #member " \t: %ld\n", (long) offsetof(struct type ## 32, member))
-+#else
-+#define PRINT_OFFSET(type, member) \
-+	printk(KERN_DEBUG "struct " #type "->" #member " \t: %ld\n", (long) offsetof(struct type, member))
-+#endif
-+
-+static int debug_printoffsets(void)
-+{
-+	printk(KERN_DEBUG "Skas core structures layout BEGIN:\n");
-+	PRINT_OFFSET(mm_mmap, addr);
-+	PRINT_OFFSET(mm_mmap, len);
-+	PRINT_OFFSET(mm_mmap, prot);
-+	PRINT_OFFSET(mm_mmap, flags);
-+	PRINT_OFFSET(mm_mmap, fd);
-+	PRINT_OFFSET(mm_mmap, offset);
-+
-+	PRINT_OFFSET(mm_munmap, addr);
-+	PRINT_OFFSET(mm_munmap, len);
-+
-+	PRINT_OFFSET(mm_mprotect, addr);
-+	PRINT_OFFSET(mm_mprotect, len);
-+	PRINT_OFFSET(mm_mprotect, prot);
-+
-+	PRINT_OFFSET(proc_mm_op, op);
-+	PRINT_OFFSET(proc_mm_op, u);
-+	PRINT_OFFSET(proc_mm_op, u.mmap);
-+	PRINT_OFFSET(proc_mm_op, u.munmap);
-+	PRINT_OFFSET(proc_mm_op, u.mprotect);
-+	PRINT_OFFSET(proc_mm_op, u.copy_segments);
-+
-+	PRINT_OFFSET(ptrace_faultinfo, is_write);
-+	PRINT_OFFSET(ptrace_faultinfo, addr);
-+
-+	PRINT_OFFSET(ptrace_ldt, func);
-+	PRINT_OFFSET(ptrace_ldt, ptr);
-+	PRINT_OFFSET(ptrace_ldt, bytecount);
-+	printk(KERN_DEBUG "Skas core structures layout END.\n");
-+
-+	return 0;
-+}
-+#undef PRINT_OFFSET
-+
-+module_init(debug_printoffsets);

Deleted: trunk/src/kernel-patch-skas/skas-2.6.17-rc5-v9-pre9.patch
===================================================================
--- trunk/src/kernel-patch-skas/skas-2.6.17-rc5-v9-pre9.patch	2006-08-27 15:01:30 UTC (rev 166)
+++ trunk/src/kernel-patch-skas/skas-2.6.17-rc5-v9-pre9.patch	2006-08-27 15:16:57 UTC (rev 167)
@@ -1,1863 +0,0 @@
-Index: linux-2.6.git/arch/i386/Kconfig
-===================================================================
---- linux-2.6.git.orig/arch/i386/Kconfig
-+++ linux-2.6.git/arch/i386/Kconfig
-@@ -512,6 +512,26 @@ config X86_PAE
- 	depends on HIGHMEM64G
- 	default y
- 
-+config PROC_MM
-+	bool "/proc/mm support"
-+	default y
-+
-+config PROC_MM_DUMPABLE
-+	bool "Make UML childs /proc/<pid> completely browsable"
-+	default n
-+	help
-+	  If in doubt, say N.
-+
-+	  This fiddles with some settings to make sure /proc/<pid> is completely
-+	  browsable by who started UML, at the expense of some additional
-+	  locking (maybe this could slow down the runned UMLs of a few percents,
-+	  I've not tested this).
-+
-+	  Also, if there is a bug in this feature, there is some little
-+	  possibility to do privilege escalation if you have UML installed
-+	  setuid (which you shouldn't have done) or if UML changes uid on
-+	  startup (which will be a good thing, when enabled) ...
-+
- # Common NUMA Features
- config NUMA
- 	bool "Numa Memory Allocation and Scheduler Support"
-Index: linux-2.6.git/arch/i386/kernel/ldt.c
-===================================================================
---- linux-2.6.git.orig/arch/i386/kernel/ldt.c
-+++ linux-2.6.git/arch/i386/kernel/ldt.c
-@@ -28,11 +28,12 @@ static void flush_ldt(void *null)
- }
- #endif
- 
--static int alloc_ldt(mm_context_t *pc, int mincount, int reload)
-+static int alloc_ldt(struct mm_struct *mm, int mincount, int reload)
- {
- 	void *oldldt;
- 	void *newldt;
- 	int oldsize;
-+	mm_context_t * pc = &mm->context;
- 
- 	if (mincount <= pc->size)
- 		return 0;
-@@ -59,13 +60,15 @@ static int alloc_ldt(mm_context_t *pc, i
- #ifdef CONFIG_SMP
- 		cpumask_t mask;
- 		preempt_disable();
--		load_LDT(pc);
-+		if (&current->active_mm->context == pc)
-+			load_LDT(pc);
- 		mask = cpumask_of_cpu(smp_processor_id());
--		if (!cpus_equal(current->mm->cpu_vm_mask, mask))
-+		if (!cpus_equal(mm->cpu_vm_mask, mask))
- 			smp_call_function(flush_ldt, NULL, 1, 1);
- 		preempt_enable();
- #else
--		load_LDT(pc);
-+		if (&current->active_mm->context == pc)
-+			load_LDT(pc);
- #endif
- 	}
- 	if (oldsize) {
-@@ -77,12 +80,12 @@ static int alloc_ldt(mm_context_t *pc, i
- 	return 0;
- }
- 
--static inline int copy_ldt(mm_context_t *new, mm_context_t *old)
-+static inline int copy_ldt(struct mm_struct *new, struct mm_struct *old)
- {
--	int err = alloc_ldt(new, old->size, 0);
-+	int err = alloc_ldt(new, old->context.size, 0);
- 	if (err < 0)
- 		return err;
--	memcpy(new->ldt, old->ldt, old->size*LDT_ENTRY_SIZE);
-+	memcpy(new->context.ldt, old->context.ldt, old->context.size*LDT_ENTRY_SIZE);
- 	return 0;
- }
- 
-@@ -90,22 +93,24 @@ static inline int copy_ldt(mm_context_t 
-  * we do not have to muck with descriptors here, that is
-  * done in switch_mm() as needed.
-  */
--int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
-+int copy_context(struct mm_struct *mm, struct mm_struct *old_mm)
- {
--	struct mm_struct * old_mm;
- 	int retval = 0;
- 
--	init_MUTEX(&mm->context.sem);
--	mm->context.size = 0;
--	old_mm = current->mm;
- 	if (old_mm && old_mm->context.size > 0) {
- 		down(&old_mm->context.sem);
--		retval = copy_ldt(&mm->context, &old_mm->context);
-+		retval = copy_ldt(mm, old_mm);
- 		up(&old_mm->context.sem);
- 	}
- 	return retval;
- }
- 
-+int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
-+{
-+	init_new_empty_context(mm);
-+	return copy_context(mm, current->mm);
-+}
-+
- /*
-  * No need to lock the MM as we are the last user
-  */
-@@ -122,11 +127,11 @@ void destroy_context(struct mm_struct *m
- 	}
- }
- 
--static int read_ldt(void __user * ptr, unsigned long bytecount)
-+static int read_ldt(struct mm_struct * mm, void __user * ptr,
-+		    unsigned long bytecount)
- {
- 	int err;
- 	unsigned long size;
--	struct mm_struct * mm = current->mm;
- 
- 	if (!mm->context.size)
- 		return 0;
-@@ -175,9 +180,8 @@ static int read_default_ldt(void __user 
- 	return err;
- }
- 
--static int write_ldt(void __user * ptr, unsigned long bytecount, int oldmode)
-+static int write_ldt(struct mm_struct * mm, void __user * ptr, unsigned long bytecount, int oldmode)
- {
--	struct mm_struct * mm = current->mm;
- 	__u32 entry_1, entry_2;
- 	int error;
- 	struct user_desc ldt_info;
-@@ -201,7 +205,7 @@ static int write_ldt(void __user * ptr, 
- 
- 	down(&mm->context.sem);
- 	if (ldt_info.entry_number >= mm->context.size) {
--		error = alloc_ldt(&current->mm->context, ldt_info.entry_number+1, 1);
-+		error = alloc_ldt(mm, ldt_info.entry_number+1, 1);
- 		if (error < 0)
- 			goto out_unlock;
- 	}
-@@ -231,23 +235,33 @@ out:
- 	return error;
- }
- 
--asmlinkage int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
-+int __modify_ldt(struct mm_struct * mm, int func, void __user *ptr,
-+	       unsigned long bytecount)
- {
- 	int ret = -ENOSYS;
- 
- 	switch (func) {
- 	case 0:
--		ret = read_ldt(ptr, bytecount);
-+		ret = read_ldt(mm, ptr, bytecount);
- 		break;
- 	case 1:
--		ret = write_ldt(ptr, bytecount, 1);
-+		ret = write_ldt(mm, ptr, bytecount, 1);
- 		break;
- 	case 2:
- 		ret = read_default_ldt(ptr, bytecount);
- 		break;
- 	case 0x11:
--		ret = write_ldt(ptr, bytecount, 0);
-+		ret = write_ldt(mm, ptr, bytecount, 0);
- 		break;
- 	}
- 	return ret;
- }
-+
-+asmlinkage int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
-+{
-+	int ret = __modify_ldt(current->mm, func, ptr, bytecount);
-+	/* A tail call would reorder parameters on the stack and they would then
-+	 * be restored at the wrong places. */
-+	prevent_tail_call(ret);
-+	return ret;
-+}
-Index: linux-2.6.git/arch/i386/kernel/ptrace.c
-===================================================================
---- linux-2.6.git.orig/arch/i386/kernel/ptrace.c
-+++ linux-2.6.git/arch/i386/kernel/ptrace.c
-@@ -17,6 +17,7 @@
- #include <linux/audit.h>
- #include <linux/seccomp.h>
- #include <linux/signal.h>
-+#include <linux/proc_mm.h>
- 
- #include <asm/uaccess.h>
- #include <asm/pgtable.h>
-@@ -625,6 +626,66 @@ long arch_ptrace(struct task_struct *chi
- 					(struct user_desc __user *) data);
- 		break;
- 
-+#ifdef CONFIG_PROC_MM
-+	case PTRACE_EX_FAULTINFO: {
-+		struct ptrace_ex_faultinfo fault;
-+
-+		fault = ((struct ptrace_ex_faultinfo)
-+			{ .is_write	= child->thread.error_code,
-+			  .addr		= child->thread.cr2,
-+			  .trap_no	= child->thread.trap_no });
-+		ret = copy_to_user((unsigned long *) data, &fault,
-+				   sizeof(fault));
-+		break;
-+	}
-+
-+	case PTRACE_FAULTINFO: {
-+		struct ptrace_faultinfo fault;
-+
-+		fault = ((struct ptrace_faultinfo)
-+			{ .is_write	= child->thread.error_code,
-+			  .addr		= child->thread.cr2 });
-+		ret = copy_to_user((unsigned long *) data, &fault,
-+				   sizeof(fault));
-+		break;
-+	}
-+
-+	case PTRACE_LDT: {
-+		struct ptrace_ldt ldt;
-+
-+		if(copy_from_user(&ldt, (unsigned long *) data,
-+				  sizeof(ldt))){
-+			ret = -EIO;
-+			break;
-+		}
-+		ret = __modify_ldt(child->mm, ldt.func, ldt.ptr, ldt.bytecount);
-+		break;
-+	}
-+
-+	case PTRACE_SWITCH_MM: {
-+		struct mm_struct *old = child->mm;
-+		struct mm_struct *new = proc_mm_get_mm(data);
-+
-+		if(IS_ERR(new)){
-+			ret = PTR_ERR(new);
-+			break;
-+		}
-+
-+		atomic_inc(&new->mm_users);
-+
-+		lock_fix_dumpable_setting(child, new);
-+
-+		child->mm = new;
-+		child->active_mm = new;
-+
-+		task_unlock(child);
-+
-+		mmput(old);
-+		ret = 0;
-+		break;
-+	}
-+#endif
-+
- 	default:
- 		ret = ptrace_request(child, request, addr, data);
- 		break;
-Index: linux-2.6.git/arch/i386/kernel/sys_i386.c
-===================================================================
---- linux-2.6.git.orig/arch/i386/kernel/sys_i386.c
-+++ linux-2.6.git/arch/i386/kernel/sys_i386.c
-@@ -22,6 +22,7 @@
- 
- #include <asm/uaccess.h>
- #include <asm/ipc.h>
-+#include <asm/proc_mm.h>
- 
- /*
-  * sys_pipe() is the normal C calling standard for creating
-@@ -40,13 +41,12 @@ asmlinkage int sys_pipe(unsigned long __
- 	return error;
- }
- 
--asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
--			  unsigned long prot, unsigned long flags,
--			  unsigned long fd, unsigned long pgoff)
-+long do_mmap2(struct mm_struct *mm, unsigned long addr, unsigned long len,
-+		unsigned long prot, unsigned long flags, unsigned long fd,
-+		unsigned long pgoff)
- {
- 	int error = -EBADF;
- 	struct file *file = NULL;
--	struct mm_struct *mm = current->mm;
- 
- 	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
- 	if (!(flags & MAP_ANONYMOUS)) {
-@@ -56,7 +56,7 @@ asmlinkage long sys_mmap2(unsigned long 
- 	}
- 
- 	down_write(&mm->mmap_sem);
--	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-+	error = __do_mmap_pgoff(mm, file, addr, len, prot, flags, pgoff);
- 	up_write(&mm->mmap_sem);
- 
- 	if (file)
-@@ -65,6 +65,18 @@ out:
- 	return error;
- }
- 
-+asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
-+       unsigned long prot, unsigned long flags,
-+       unsigned long fd, unsigned long pgoff)
-+{
-+	long ret = do_mmap2(current->mm, addr, len, prot, flags, fd, pgoff);
-+
-+	/* A tail call would reorder parameters on the stack and they would then
-+	 * be restored at the wrong places. */
-+	prevent_tail_call(ret);
-+	return ret;
-+}
-+
- /*
-  * Perform the select(nd, in, out, ex, tv) and mmap() system
-  * calls. Linux/i386 didn't use to be able to handle more than
-@@ -93,8 +105,11 @@ asmlinkage int old_mmap(struct mmap_arg_
- 	if (a.offset & ~PAGE_MASK)
- 		goto out;
- 
--	err = sys_mmap2(a.addr, a.len, a.prot, a.flags,
-+	err = do_mmap2(current->mm, a.addr, a.len, a.prot, a.flags,
- 			a.fd, a.offset >> PAGE_SHIFT);
-+	/* A tail call would reorder parameters on the stack and they would then
-+	 * be restored at the wrong places. */
-+	prevent_tail_call(err);
- out:
- 	return err;
- }
-Index: linux-2.6.git/arch/um/include/skas_ptrace.h
-===================================================================
---- linux-2.6.git.orig/arch/um/include/skas_ptrace.h
-+++ linux-2.6.git/arch/um/include/skas_ptrace.h
-@@ -6,6 +6,8 @@
- #ifndef __SKAS_PTRACE_H
- #define __SKAS_PTRACE_H
- 
-+#ifndef PTRACE_FAULTINFO
-+
- #define PTRACE_FAULTINFO 52
- #define PTRACE_SWITCH_MM 55
- 
-@@ -13,6 +15,8 @@
- 
- #endif
- 
-+#endif
-+
- /*
-  * Overrides for Emacs so that we follow Linus's tabbing style.
-  * Emacs will notice this stuff at the end of the file and automatically
-Index: linux-2.6.git/arch/x86_64/Kconfig
-===================================================================
---- linux-2.6.git.orig/arch/x86_64/Kconfig
-+++ linux-2.6.git/arch/x86_64/Kconfig
-@@ -407,6 +407,26 @@ config SWIOTLB
- 	default y
- 	depends on GART_IOMMU
- 
-+config PROC_MM
-+	bool "/proc/mm support"
-+	default y
-+
-+config PROC_MM_DUMPABLE
-+	bool "Make UML childs /proc/<pid> completely browsable"
-+	default n
-+	help
-+	  If in doubt, say N.
-+
-+	  This fiddles with some settings to make sure /proc/<pid> is completely
-+	  browsable by who started UML, at the expense of some additional
-+	  locking (maybe this could slow down the runned UMLs of a few percents,
-+	  I've not tested this).
-+
-+	  Also, if there is a bug in this feature, there is some little
-+	  possibility to do privilege escalation if you have UML installed
-+	  setuid (which you shouldn't have done) or if UML changes uid on
-+	  startup (which will be a good thing, when enabled) ...
-+
- config X86_MCE
- 	bool "Machine check support" if EMBEDDED
- 	default y
-Index: linux-2.6.git/arch/x86_64/ia32/ptrace32.c
-===================================================================
---- linux-2.6.git.orig/arch/x86_64/ia32/ptrace32.c
-+++ linux-2.6.git/arch/x86_64/ia32/ptrace32.c
-@@ -18,6 +18,8 @@
- #include <linux/unistd.h>
- #include <linux/mm.h>
- #include <linux/ptrace.h>
-+#include <linux/types.h>
-+#include <linux/proc_mm.h>
- #include <asm/ptrace.h>
- #include <asm/compat.h>
- #include <asm/uaccess.h>
-@@ -27,6 +29,7 @@
- #include <asm/debugreg.h>
- #include <asm/i387.h>
- #include <asm/fpu32.h>
-+#include <asm/desc.h>
- 
- /*
-  * Determines which flags the user has access to [1 = access, 0 = no access].
-@@ -224,6 +227,12 @@ asmlinkage long sys32_ptrace(long reques
- 	case PTRACE_SETFPXREGS:
- 	case PTRACE_GETFPXREGS:
- 	case PTRACE_GETEVENTMSG:
-+#ifdef CONFIG_PROC_MM
-+	case PTRACE_EX_FAULTINFO:
-+	case PTRACE_FAULTINFO:
-+	case PTRACE_LDT:
-+	case PTRACE_SWITCH_MM:
-+#endif
- 		break;
- 	} 
- 
-@@ -343,6 +352,65 @@ asmlinkage long sys32_ptrace(long reques
- 		ret = 0; 
- 		break;
- 	}
-+#ifdef CONFIG_PROC_MM
-+	case PTRACE_EX_FAULTINFO: {
-+		struct ptrace_ex_faultinfo32 fault;
-+
-+		fault = ((struct ptrace_ex_faultinfo32)
-+			{ .is_write	= (compat_int_t) child->thread.error_code,
-+			  .addr		= (compat_uptr_t) child->thread.cr2,
-+			  .trap_no	= (compat_int_t) child->thread.trap_no });
-+		ret = copy_to_user((unsigned long *) datap, &fault,
-+				   sizeof(fault));
-+		break;
-+	}
-+
-+	case PTRACE_FAULTINFO: {
-+		struct ptrace_faultinfo32 fault;
-+
-+		fault = ((struct ptrace_faultinfo32)
-+			{ .is_write	= (compat_int_t) child->thread.error_code,
-+			  .addr		= (compat_uptr_t) child->thread.cr2 });
-+		ret = copy_to_user((unsigned long *) datap, &fault,
-+				   sizeof(fault));
-+		break;
-+	}
-+
-+	case PTRACE_LDT: {
-+		struct ptrace_ldt32 ldt;
-+
-+		if(copy_from_user(&ldt, (unsigned long *) datap,
-+				  sizeof(ldt))){
-+			ret = -EIO;
-+			break;
-+		}
-+		ret = __modify_ldt(child->mm, ldt.func, compat_ptr(ldt.ptr), ldt.bytecount);
-+		break;
-+	}
-+
-+	case PTRACE_SWITCH_MM: {
-+		struct mm_struct *old = child->mm;
-+		struct mm_struct *new = proc_mm_get_mm(data);
-+
-+		if(IS_ERR(new)){
-+			ret = PTR_ERR(new);
-+			break;
-+		}
-+
-+		atomic_inc(&new->mm_users);
-+
-+		lock_fix_dumpable_setting(child, new);
-+
-+		child->mm = new;
-+		child->active_mm = new;
-+
-+		task_unlock(child);
-+
-+		mmput(old);
-+		ret = 0;
-+		break;
-+	}
-+#endif
- 
- 	case PTRACE_GETEVENTMSG:
- 		ret = put_user(child->ptrace_message,(unsigned int __user *)compat_ptr(data));
-Index: linux-2.6.git/arch/x86_64/ia32/sys_ia32.c
-===================================================================
---- linux-2.6.git.orig/arch/x86_64/ia32/sys_ia32.c
-+++ linux-2.6.git/arch/x86_64/ia32/sys_ia32.c
-@@ -766,11 +766,10 @@ sys32_sendfile(int out_fd, int in_fd, co
- 	return ret;
- }
- 
--asmlinkage long sys32_mmap2(unsigned long addr, unsigned long len,
--	unsigned long prot, unsigned long flags,
-+long do32_mmap2(struct mm_struct *mm, unsigned long addr,
-+	unsigned long len, unsigned long prot, unsigned long flags,
- 	unsigned long fd, unsigned long pgoff)
- {
--	struct mm_struct *mm = current->mm;
- 	unsigned long error;
- 	struct file * file = NULL;
- 
-@@ -782,7 +781,7 @@ asmlinkage long sys32_mmap2(unsigned lon
- 	}
- 
- 	down_write(&mm->mmap_sem);
--	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-+	error = __do_mmap_pgoff(mm, file, addr, len, prot, flags, pgoff);
- 	up_write(&mm->mmap_sem);
- 
- 	if (file)
-@@ -790,6 +789,15 @@ asmlinkage long sys32_mmap2(unsigned lon
- 	return error;
- }
- 
-+/* XXX: this wrapper can be probably removed, we can simply use the 64-bit
-+ * version.*/
-+asmlinkage long sys32_mmap2(unsigned long addr, unsigned long len,
-+	unsigned long prot, unsigned long flags,
-+	unsigned long fd, unsigned long pgoff)
-+{
-+	return do32_mmap2(current->mm, addr, len, prot, flags, fd, pgoff);
-+}
-+
- asmlinkage long sys32_olduname(struct oldold_utsname __user * name)
- {
- 	int error;
-Index: linux-2.6.git/arch/x86_64/kernel/ldt.c
-===================================================================
---- linux-2.6.git.orig/arch/x86_64/kernel/ldt.c
-+++ linux-2.6.git/arch/x86_64/kernel/ldt.c
-@@ -22,6 +22,7 @@
- #include <asm/ldt.h>
- #include <asm/desc.h>
- #include <asm/proto.h>
-+#include <asm/mmu_context.h>
- 
- #ifdef CONFIG_SMP /* avoids "defined but not used" warnig */
- static void flush_ldt(void *null)
-@@ -31,11 +32,12 @@ static void flush_ldt(void *null)
- }
- #endif
- 
--static int alloc_ldt(mm_context_t *pc, unsigned mincount, int reload)
-+static int alloc_ldt(struct mm_struct *mm, unsigned mincount, int reload)
- {
- 	void *oldldt;
- 	void *newldt;
- 	unsigned oldsize;
-+	mm_context_t * pc = &mm->context;
- 
- 	if (mincount <= (unsigned)pc->size)
- 		return 0;
-@@ -64,12 +66,14 @@ static int alloc_ldt(mm_context_t *pc, u
- 
- 		preempt_disable();
- 		mask = cpumask_of_cpu(smp_processor_id());
--		load_LDT(pc);
--		if (!cpus_equal(current->mm->cpu_vm_mask, mask))
-+		if (&current->active_mm->context == pc)
-+			load_LDT(pc);
-+		if (!cpus_equal(mm->cpu_vm_mask, mask))
- 			smp_call_function(flush_ldt, NULL, 1, 1);
- 		preempt_enable();
- #else
--		load_LDT(pc);
-+		if (&current->active_mm->context == pc)
-+			load_LDT(pc);
- #endif
- 	}
- 	if (oldsize) {
-@@ -81,12 +85,12 @@ static int alloc_ldt(mm_context_t *pc, u
- 	return 0;
- }
- 
--static inline int copy_ldt(mm_context_t *new, mm_context_t *old)
-+static inline int copy_ldt(struct mm_struct *new, struct mm_struct *old)
- {
--	int err = alloc_ldt(new, old->size, 0);
-+	int err = alloc_ldt(new, old->context.size, 0);
- 	if (err < 0)
- 		return err;
--	memcpy(new->ldt, old->ldt, old->size*LDT_ENTRY_SIZE);
-+	memcpy(new->context.ldt, old->context.ldt, old->context.size*LDT_ENTRY_SIZE);
- 	return 0;
- }
- 
-@@ -94,22 +98,24 @@ static inline int copy_ldt(mm_context_t 
-  * we do not have to muck with descriptors here, that is
-  * done in switch_mm() as needed.
-  */
--int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
-+int copy_context(struct mm_struct *mm, struct mm_struct *old_mm)
- {
--	struct mm_struct * old_mm;
- 	int retval = 0;
- 
--	init_MUTEX(&mm->context.sem);
--	mm->context.size = 0;
--	old_mm = current->mm;
- 	if (old_mm && old_mm->context.size > 0) {
- 		down(&old_mm->context.sem);
--		retval = copy_ldt(&mm->context, &old_mm->context);
-+		retval = copy_ldt(mm, old_mm);
- 		up(&old_mm->context.sem);
- 	}
- 	return retval;
- }
- 
-+int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
-+{
-+	init_new_empty_context(mm);
-+	return copy_context(mm, current->mm);
-+}
-+
- /*
-  * 
-  * Don't touch the LDT register - we're already in the next thread.
-@@ -125,11 +131,10 @@ void destroy_context(struct mm_struct *m
- 	}
- }
- 
--static int read_ldt(void __user * ptr, unsigned long bytecount)
-+static int read_ldt(struct mm_struct * mm, void __user * ptr, unsigned long bytecount)
- {
- 	int err;
- 	unsigned long size;
--	struct mm_struct * mm = current->mm;
- 
- 	if (!mm->context.size)
- 		return 0;
-@@ -170,10 +175,8 @@ static int read_default_ldt(void __user 
- 	return bytecount; 
- }
- 
--static int write_ldt(void __user * ptr, unsigned long bytecount, int oldmode)
-+static int write_ldt(struct mm_struct * mm, void __user * ptr, unsigned long bytecount, int oldmode)
- {
--	struct task_struct *me = current;
--	struct mm_struct * mm = me->mm;
- 	__u32 entry_1, entry_2, *lp;
- 	int error;
- 	struct user_desc ldt_info;
-@@ -198,7 +201,7 @@ static int write_ldt(void __user * ptr, 
- 
- 	down(&mm->context.sem);
- 	if (ldt_info.entry_number >= (unsigned)mm->context.size) {
--		error = alloc_ldt(&current->mm->context, ldt_info.entry_number+1, 1);
-+		error = alloc_ldt(mm, ldt_info.entry_number+1, 1);
- 		if (error < 0)
- 			goto out_unlock;
- 	}
-@@ -231,23 +234,29 @@ out:
- 	return error;
- }
- 
--asmlinkage int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
-+int __modify_ldt(struct mm_struct * mm, int func, void __user *ptr,
-+		unsigned long bytecount)
- {
- 	int ret = -ENOSYS;
- 
- 	switch (func) {
- 	case 0:
--		ret = read_ldt(ptr, bytecount);
-+		ret = read_ldt(mm, ptr, bytecount);
- 		break;
- 	case 1:
--		ret = write_ldt(ptr, bytecount, 1);
-+		ret = write_ldt(mm, ptr, bytecount, 1);
- 		break;
- 	case 2:
- 		ret = read_default_ldt(ptr, bytecount);
- 		break;
- 	case 0x11:
--		ret = write_ldt(ptr, bytecount, 0);
-+		ret = write_ldt(mm, ptr, bytecount, 0);
- 		break;
- 	}
- 	return ret;
- }
-+
-+asmlinkage int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
-+{
-+	return __modify_ldt(current->mm, func, ptr, bytecount);
-+}
-Index: linux-2.6.git/arch/x86_64/kernel/ptrace.c
-===================================================================
---- linux-2.6.git.orig/arch/x86_64/kernel/ptrace.c
-+++ linux-2.6.git/arch/x86_64/kernel/ptrace.c
-@@ -19,6 +19,7 @@
- #include <linux/audit.h>
- #include <linux/seccomp.h>
- #include <linux/signal.h>
-+#include <linux/proc_mm.h>
- 
- #include <asm/uaccess.h>
- #include <asm/pgtable.h>
-@@ -559,6 +560,75 @@ long arch_ptrace(struct task_struct *chi
- 		break;
- 	}
- 
-+#ifdef CONFIG_PROC_MM
-+	case PTRACE_EX_FAULTINFO: {
-+		struct ptrace_ex_faultinfo fault;
-+
-+		/* I checked in thread_struct comments that error_code and cr2
-+		 * are still part of the "fault info" section, so I guess that
-+		 * things are unchanged for now. Still to check manuals. BB*/
-+		fault = ((struct ptrace_ex_faultinfo)
-+			{ .is_write	= child->thread.error_code,
-+			  .addr		= child->thread.cr2,
-+			  .trap_no	= child->thread.trap_no });
-+		ret = copy_to_user((unsigned long *) data, &fault,
-+				   sizeof(fault));
-+		break;
-+	}
-+
-+	/*Don't extend this broken interface to x86-64*/
-+#if 0
-+	case PTRACE_FAULTINFO: {
-+		struct ptrace_faultinfo fault;
-+
-+		/* I checked in thread_struct comments that error_code and cr2
-+		 * are still part of the "fault info" section, so I guess that
-+		 * things are unchanged for now. Still to check manuals. BB*/
-+		fault = ((struct ptrace_faultinfo)
-+			{ .is_write	= child->thread.error_code,
-+			  .addr		= child->thread.cr2 });
-+		ret = copy_to_user((unsigned long *) data, &fault,
-+				   sizeof(fault));
-+		break;
-+	}
-+#endif
-+
-+	case PTRACE_LDT: {
-+		struct ptrace_ldt ldt;
-+
-+		if(copy_from_user(&ldt, (unsigned long *) data,
-+				  sizeof(ldt))){
-+			ret = -EIO;
-+			break;
-+		}
-+		ret = __modify_ldt(child->mm, ldt.func, ldt.ptr, ldt.bytecount);
-+		break;
-+	}
-+
-+	case PTRACE_SWITCH_MM: {
-+		struct mm_struct *old = child->mm;
-+		struct mm_struct *new = proc_mm_get_mm64(data);
-+
-+		if(IS_ERR(new)){
-+			ret = PTR_ERR(new);
-+			break;
-+		}
-+
-+		atomic_inc(&new->mm_users);
-+
-+		lock_fix_dumpable_setting(child, new);
-+
-+		child->mm = new;
-+		child->active_mm = new;
-+
-+		task_unlock(child);
-+
-+		mmput(old);
-+		ret = 0;
-+		break;
-+	}
-+#endif
-+
- 	default:
- 		ret = ptrace_request(child, request, addr, data);
- 		break;
-Index: linux-2.6.git/arch/x86_64/kernel/sys_x86_64.c
-===================================================================
---- linux-2.6.git.orig/arch/x86_64/kernel/sys_x86_64.c
-+++ linux-2.6.git/arch/x86_64/kernel/sys_x86_64.c
-@@ -19,6 +19,7 @@
- 
- #include <asm/uaccess.h>
- #include <asm/ia32.h>
-+#include <asm/proc_mm.h>
- 
- /*
-  * sys_pipe() is the normal C calling standard for creating
-@@ -37,7 +38,7 @@ asmlinkage long sys_pipe(int __user *fil
- 	return error;
- }
- 
--asmlinkage long sys_mmap(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags,
-+long do64_mmap(struct mm_struct *mm, unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags,
- 	unsigned long fd, unsigned long off)
- {
- 	long error;
-@@ -55,9 +56,9 @@ asmlinkage long sys_mmap(unsigned long a
- 		if (!file)
- 			goto out;
- 	}
--	down_write(&current->mm->mmap_sem);
--	error = do_mmap_pgoff(file, addr, len, prot, flags, off >> PAGE_SHIFT);
--	up_write(&current->mm->mmap_sem);
-+	down_write(&mm->mmap_sem);
-+	error = __do_mmap_pgoff(mm, file, addr, len, prot, flags, off >> PAGE_SHIFT);
-+	up_write(&mm->mmap_sem);
- 
- 	if (file)
- 		fput(file);
-@@ -65,6 +66,12 @@ out:
- 	return error;
- }
- 
-+asmlinkage long sys_mmap(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags,
-+	unsigned long fd, unsigned long off)
-+{
-+	return do64_mmap(current->mm, addr, len, prot, flags, fd, off);
-+}
-+
- static void find_start_end(unsigned long flags, unsigned long *begin,
- 			   unsigned long *end)
- {
-Index: linux-2.6.git/arch/x86_64/mm/Makefile
-===================================================================
---- linux-2.6.git.orig/arch/x86_64/mm/Makefile
-+++ linux-2.6.git/arch/x86_64/mm/Makefile
-@@ -7,5 +7,6 @@ obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpag
- obj-$(CONFIG_NUMA) += numa.o
- obj-$(CONFIG_K8_NUMA) += k8topology.o
- obj-$(CONFIG_ACPI_NUMA) += srat.o
-+obj-$(CONFIG_PROC_MM) += proc_mm.o
- 
- hugetlbpage-y = ../../i386/mm/hugetlbpage.o
-Index: linux-2.6.git/arch/x86_64/mm/proc_mm.c
-===================================================================
---- /dev/null
-+++ linux-2.6.git/arch/x86_64/mm/proc_mm.c
-@@ -0,0 +1,85 @@
-+#include <linux/proc_mm.h>
-+#include <linux/mm.h>
-+#include <linux/init.h>
-+#include <linux/proc_fs.h>
-+#include <linux/file.h>
-+#include <linux/mman.h>
-+#include <asm/uaccess.h>
-+#include <asm/mmu_context.h>
-+
-+ssize_t write_proc_mm_emul(struct file *file, const char *buffer,
-+			     size_t count, loff_t *ppos)
-+{
-+	struct mm_struct *mm = file->private_data;
-+	struct proc_mm_op32 req;
-+	int n, ret;
-+
-+	if(count > sizeof(req))
-+		return(-EINVAL);
-+
-+	n = copy_from_user(&req, buffer, count);
-+	if(n != 0)
-+		return(-EFAULT);
-+
-+	ret = count;
-+	switch(req.op){
-+	case MM_MMAP: {
-+		struct mm_mmap32 *map = &req.u.mmap;
-+
-+		/* Nobody ever noticed it, but do_mmap_pgoff() calls
-+		 * get_unmapped_area() which checks current->mm, if
-+		 * MAP_FIXED is not set, so mmap() could replace
-+		 * an old mapping.
-+		 */
-+		if (! (map->flags & MAP_FIXED))
-+			return(-EINVAL);
-+
-+		ret = __do_mmap(mm, map->addr, map->len, map->prot,
-+			       map->flags, map->fd, map->offset);
-+		if((ret & ~PAGE_MASK) == 0)
-+			ret = count;
-+
-+		break;
-+	}
-+	case MM_MUNMAP: {
-+		struct mm_munmap32 *unmap = &req.u.munmap;
-+
-+		down_write(&mm->mmap_sem);
-+		ret = do_munmap(mm, unmap->addr, unmap->len);
-+		up_write(&mm->mmap_sem);
-+
-+		if(ret == 0)
-+			ret = count;
-+		break;
-+	}
-+	case MM_MPROTECT: {
-+		struct mm_mprotect32 *protect = &req.u.mprotect;
-+
-+		ret = do_mprotect(mm, protect->addr, protect->len,
-+				  protect->prot);
-+		if(ret == 0)
-+			ret = count;
-+		break;
-+	}
-+
-+	case MM_COPY_SEGMENTS: {
-+		struct mm_struct *from = proc_mm_get_mm_emul(req.u.copy_segments);
-+
-+		if(IS_ERR(from)){
-+			ret = PTR_ERR(from);
-+			break;
-+		}
-+
-+		ret = copy_context(mm, from);
-+		if(ret == 0)
-+			ret = count;
-+		break;
-+	}
-+	default:
-+		ret = -EINVAL;
-+		break;
-+	}
-+
-+	return ret;
-+}
-+
-Index: linux-2.6.git/include/asm-i386/desc.h
-===================================================================
---- linux-2.6.git.orig/include/asm-i386/desc.h
-+++ linux-2.6.git/include/asm-i386/desc.h
-@@ -162,6 +162,9 @@ static inline unsigned long get_desc_bas
- 	return base;
- }
- 
-+extern int __modify_ldt(struct mm_struct * mm, int func, void __user *ptr,
-+		      unsigned long bytecount);
-+
- #endif /* !__ASSEMBLY__ */
- 
- #endif
-Index: linux-2.6.git/include/asm-i386/mmu_context.h
-===================================================================
---- linux-2.6.git.orig/include/asm-i386/mmu_context.h
-+++ linux-2.6.git/include/asm-i386/mmu_context.h
-@@ -6,13 +6,25 @@
- #include <asm/atomic.h>
- #include <asm/pgalloc.h>
- #include <asm/tlbflush.h>
-+#include <asm/semaphore.h>
- 
- /*
-- * Used for LDT copy/destruction.
-+ * Used for LDT initialization/destruction. You cannot copy an LDT with
-+ * init_new_context, since it thinks you are passing it a new LDT and won't
-+ * deallocate its old content.
-  */
- int init_new_context(struct task_struct *tsk, struct mm_struct *mm);
- void destroy_context(struct mm_struct *mm);
- 
-+/* LDT initialization for a clean environment - needed for SKAS.*/
-+static inline void init_new_empty_context(struct mm_struct *mm)
-+{
-+	init_MUTEX(&mm->context.sem);
-+	mm->context.size = 0;
-+}
-+
-+/* LDT copy for SKAS - for the above problem.*/
-+int copy_context(struct mm_struct *mm, struct mm_struct *old_mm);
- 
- static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
- {
-@@ -29,6 +41,10 @@ static inline void switch_mm(struct mm_s
- {
- 	int cpu = smp_processor_id();
- 
-+#ifdef CONFIG_SMP
-+	prev = per_cpu(cpu_tlbstate, cpu).active_mm;
-+#endif
-+
- 	if (likely(prev != next)) {
- 		/* stop flush ipis for the previous mm */
- 		cpu_clear(cpu, prev->cpu_vm_mask);
-@@ -50,7 +66,6 @@ static inline void switch_mm(struct mm_s
- #ifdef CONFIG_SMP
- 	else {
- 		per_cpu(cpu_tlbstate, cpu).state = TLBSTATE_OK;
--		BUG_ON(per_cpu(cpu_tlbstate, cpu).active_mm != next);
- 
- 		if (!cpu_test_and_set(cpu, next->cpu_vm_mask)) {
- 			/* We were in lazy tlb mode and leave_mm disabled 
-Index: linux-2.6.git/include/asm-i386/proc_mm.h
-===================================================================
---- /dev/null
-+++ linux-2.6.git/include/asm-i386/proc_mm.h
-@@ -0,0 +1,18 @@
-+#ifndef __ASM_PROC_MM
-+#define __ASM_PROC_MM
-+
-+#include <asm/page.h>
-+
-+extern long do_mmap2(struct mm_struct *mm, unsigned long addr,
-+		unsigned long len, unsigned long prot, unsigned long flags,
-+		unsigned long fd, unsigned long pgoff);
-+
-+static inline long __do_mmap(struct mm_struct *mm, unsigned long addr,
-+		     unsigned long len, unsigned long prot,
-+		     unsigned long flags, unsigned long fd,
-+		     unsigned long off)
-+{
-+	return do_mmap2(mm, addr, len, prot, flags, fd, off >> PAGE_SHIFT);
-+}
-+
-+#endif /* __ASM_PROC_MM */
-Index: linux-2.6.git/include/asm-i386/ptrace.h
-===================================================================
---- linux-2.6.git.orig/include/asm-i386/ptrace.h
-+++ linux-2.6.git/include/asm-i386/ptrace.h
-@@ -87,4 +87,33 @@ extern unsigned long profile_pc(struct p
- #endif
- #endif /* __KERNEL__ */
- 
-+/*For SKAS3 support.*/
-+#ifndef _LINUX_PTRACE_STRUCT_DEF
-+#define _LINUX_PTRACE_STRUCT_DEF
-+
-+#define PTRACE_FAULTINFO	  52
-+/* 53 was used for PTRACE_SIGPENDING, don't reuse it. */
-+#define PTRACE_LDT		  54
-+#define PTRACE_SWITCH_MM 	  55
-+#define PTRACE_EX_FAULTINFO	  56
-+
-+struct ptrace_faultinfo {
-+	int is_write;
-+	unsigned long addr;
-+};
-+
-+struct ptrace_ex_faultinfo {
-+	int is_write;
-+	unsigned long addr;
-+	int trap_no;
-+};
-+
-+struct ptrace_ldt {
-+	int func;
-+  	void *ptr;
-+	unsigned long bytecount;
-+};
-+
-+#endif /*ifndef _LINUX_PTRACE_STRUCT_DEF*/
-+
- #endif
-Index: linux-2.6.git/include/asm-x86_64/desc.h
-===================================================================
---- linux-2.6.git.orig/include/asm-x86_64/desc.h
-+++ linux-2.6.git/include/asm-x86_64/desc.h
-@@ -233,6 +233,9 @@ static inline void load_LDT(mm_context_t
- 
- extern struct desc_ptr idt_descr;
- 
-+extern int __modify_ldt(struct mm_struct * mm, int func, void __user *ptr,
-+		unsigned long bytecount);
-+
- #endif /* !__ASSEMBLY__ */
- 
- #endif
-Index: linux-2.6.git/include/asm-x86_64/mmu_context.h
-===================================================================
---- linux-2.6.git.orig/include/asm-x86_64/mmu_context.h
-+++ linux-2.6.git/include/asm-x86_64/mmu_context.h
-@@ -8,13 +8,28 @@
- #include <asm/pda.h>
- #include <asm/pgtable.h>
- #include <asm/tlbflush.h>
-+#include <asm/semaphore.h>
- 
- /*
-  * possibly do the LDT unload here?
-+ * Used for LDT initialization/destruction. You cannot copy an LDT with
-+ * init_new_context, since it thinks you are passing it a new LDT and won't
-+ * deallocate its old content.
-  */
-+
- int init_new_context(struct task_struct *tsk, struct mm_struct *mm);
- void destroy_context(struct mm_struct *mm);
- 
-+/* LDT initialization for a clean environment - needed for SKAS.*/
-+static inline void init_new_empty_context(struct mm_struct *mm)
-+{
-+	init_MUTEX(&mm->context.sem);
-+	mm->context.size = 0;
-+}
-+
-+/* LDT copy for SKAS - for the above problem.*/
-+int copy_context(struct mm_struct *mm, struct mm_struct *old_mm);
-+
- static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
- {
- #ifdef CONFIG_SMP
-@@ -32,6 +47,9 @@ static inline void switch_mm(struct mm_s
- 			     struct task_struct *tsk)
- {
- 	unsigned cpu = smp_processor_id();
-+#ifdef CONFIG_SMP
-+	prev = read_pda(active_mm);
-+#endif
- 	if (likely(prev != next)) {
- 		/* stop flush ipis for the previous mm */
- 		cpu_clear(cpu, prev->cpu_vm_mask);
-@@ -48,8 +66,6 @@ static inline void switch_mm(struct mm_s
- #ifdef CONFIG_SMP
- 	else {
- 		write_pda(mmu_state, TLBSTATE_OK);
--		if (read_pda(active_mm) != next)
--			out_of_line_bug();
- 		if (!cpu_test_and_set(cpu, next->cpu_vm_mask)) {
- 			/* We were in lazy tlb mode and leave_mm disabled 
- 			 * tlb flush IPI delivery. We must reload CR3
-Index: linux-2.6.git/include/asm-x86_64/proc_mm.h
-===================================================================
---- /dev/null
-+++ linux-2.6.git/include/asm-x86_64/proc_mm.h
-@@ -0,0 +1,58 @@
-+#ifndef __ASM_PROC_MM
-+#define __ASM_PROC_MM
-+#include <linux/types.h>
-+
-+#include <asm/compat.h>
-+
-+struct mm_mmap32 {
-+	compat_ulong_t addr;
-+	compat_ulong_t len;
-+	compat_ulong_t prot;
-+	compat_ulong_t flags;
-+	compat_ulong_t fd;
-+	compat_ulong_t offset;
-+};
-+
-+struct mm_munmap32 {
-+	compat_ulong_t addr;
-+	compat_ulong_t len;
-+};
-+
-+struct mm_mprotect32 {
-+	compat_ulong_t addr;
-+	compat_ulong_t len;
-+        compat_uint_t prot;
-+};
-+
-+struct proc_mm_op32 {
-+	compat_int_t op;
-+	union {
-+		struct mm_mmap32 mmap;
-+		struct mm_munmap32 munmap;
-+	        struct mm_mprotect32 mprotect;
-+		compat_int_t copy_segments;
-+	} u;
-+};
-+
-+extern ssize_t write_proc_mm_emul(struct file *file, const char *buffer,
-+			     size_t count, loff_t *ppos);
-+
-+extern struct mm_struct *proc_mm_get_mm64(int fd);
-+
-+extern long do64_mmap(struct mm_struct *mm, unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags,
-+	unsigned long fd, unsigned long off);
-+
-+static inline long __do_mmap(struct mm_struct *mm, unsigned long addr,
-+		     unsigned long len, unsigned long prot,
-+		     unsigned long flags, unsigned long fd,
-+		     unsigned long off)
-+{
-+	/* The latter one is stricter, since will actually check that off is page
-+	 * aligned. The first one skipped the check. */
-+
-+	/* return do32_mmap2(mm, addr, len, prot, flags, fd, off >>
-+	 * PAGE_SHIFT);*/
-+	return do64_mmap(mm, addr, len, prot, flags, fd, off);
-+}
-+
-+#endif /* __ASM_PROC_MM */
-Index: linux-2.6.git/include/asm-x86_64/ptrace.h
-===================================================================
---- linux-2.6.git.orig/include/asm-x86_64/ptrace.h
-+++ linux-2.6.git/include/asm-x86_64/ptrace.h
-@@ -64,6 +64,59 @@ struct pt_regs {
- /* top of stack page */ 
- };
- 
-+/* Stolen from
-+#include <linux/compat.h>; we can't include it because
-+there is a nasty ciclic include chain.
-+*/
-+
-+#include <asm/types.h>
-+
-+#define		compat_int_t	s32
-+#define		compat_long_t	s32
-+#define		compat_uint_t	u32
-+#define		compat_ulong_t	u32
-+#define		compat_uptr_t	u32
-+
-+struct ptrace_faultinfo32 {
-+	compat_int_t is_write;
-+	compat_ulong_t addr;
-+};
-+
-+struct ptrace_ex_faultinfo32 {
-+	compat_int_t is_write;
-+	compat_ulong_t addr;
-+	compat_int_t trap_no;
-+};
-+
-+struct ptrace_ldt32 {
-+	compat_int_t func;
-+	compat_uptr_t ptr; /*Actually a void pointer on i386, but must be converted.*/
-+	compat_ulong_t bytecount;
-+};
-+
-+struct ptrace_faultinfo {
-+	int is_write;
-+	unsigned long addr;
-+};
-+
-+struct ptrace_ex_faultinfo {
-+	int is_write;
-+	unsigned long addr;
-+	int trap_no;
-+};
-+
-+struct ptrace_ldt {
-+	int func;
-+  	void *ptr;
-+	unsigned long bytecount;
-+};
-+
-+#undef	compat_int_t
-+#undef	compat_long_t
-+#undef	compat_uint_t
-+#undef	compat_ulong_t
-+#undef	compat_uptr_t
-+
- #endif
- 
- /* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
-@@ -74,6 +127,12 @@ struct pt_regs {
- #define PTRACE_GETFPXREGS         18
- #define PTRACE_SETFPXREGS         19
- 
-+#define PTRACE_FAULTINFO 52
-+/* 53 was used for PTRACE_SIGPENDING, don't reuse it. */
-+#define PTRACE_LDT 54
-+#define PTRACE_SWITCH_MM 55
-+#define PTRACE_EX_FAULTINFO	  56
-+
- /* only useful for access 32bit programs */
- #define PTRACE_GET_THREAD_AREA    25
- #define PTRACE_SET_THREAD_AREA    26
-Index: linux-2.6.git/include/linux/mm.h
-===================================================================
---- linux-2.6.git.orig/include/linux/mm.h
-+++ linux-2.6.git/include/linux/mm.h
-@@ -919,9 +919,15 @@ extern int may_expand_vm(struct mm_struc
- 
- extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
- 
--extern unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
-+extern unsigned long __do_mmap_pgoff(struct mm_struct *mm, struct file *file,
-+				   unsigned long addr, unsigned long len,
-+				   unsigned long prot, unsigned long flag,
-+				   unsigned long pgoff);
-+static inline unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
- 	unsigned long len, unsigned long prot,
--	unsigned long flag, unsigned long pgoff);
-+	unsigned long flag, unsigned long pgoff) {
-+	return __do_mmap_pgoff(current->mm, file, addr, len, prot, flag, pgoff);
-+}
- 
- static inline unsigned long do_mmap(struct file *file, unsigned long addr,
- 	unsigned long len, unsigned long prot,
-@@ -938,6 +944,9 @@ out:
- 
- extern int do_munmap(struct mm_struct *, unsigned long, size_t);
- 
-+extern long do_mprotect(struct mm_struct *mm, unsigned long start,
-+			size_t len, unsigned long prot);
-+
- extern unsigned long do_brk(unsigned long, unsigned long);
- 
- /* filemap.c */
-Index: linux-2.6.git/include/linux/proc_mm.h
-===================================================================
---- /dev/null
-+++ linux-2.6.git/include/linux/proc_mm.h
-@@ -0,0 +1,114 @@
-+/*
-+ * Copyright (C) 2002 Jeff Dike (jdike at karaya.com)
-+ * Licensed under the GPL
-+ */
-+
-+#ifndef __PROC_MM_H
-+#define __PROC_MM_H
-+
-+#include <linux/config.h>
-+#include <linux/sched.h>
-+#include <linux/compiler.h>
-+
-+/* The differences between this one and do_mmap are that:
-+ * - we must perform controls for userspace-supplied params (which are
-+ *   arch-specific currently). And also fget(fd) if needed and so on...
-+ * - we must accept the struct mm_struct on which to act as first param, and the
-+ *   offset in byte rather than page units as last param.
-+ */
-+static inline long __do_mmap(struct mm_struct *mm, unsigned long addr,
-+		     unsigned long len, unsigned long prot,
-+		     unsigned long flags, unsigned long fd,
-+		     unsigned long off);
-+
-+/* This header can be used only on archs defining CONFIG_PROC_MM in their
-+ * configs, so asm/proc_mm.h can still exist only for the needed archs.
-+ * Including it only in the x86-64 case does not make sense.*/
-+#include <asm/proc_mm.h>
-+
-+/*XXX: this is defined on x86_64, but not on every 64-bit arch (not on sh64).*/
-+#ifdef CONFIG_64BIT
-+
-+#define write_proc_mm write_proc_mm_emul
-+#define write_proc_mm64 write_proc_mm_native
-+
-+/* It would make more sense to do this mapping the reverse direction, to map the
-+ * called name to the defined one and not the reverse. Like the 2nd example
-+ */
-+/*#define proc_mm_get_mm proc_mm_get_mm_emul
-+#define proc_mm_get_mm64 proc_mm_get_mm_native*/
-+
-+#define proc_mm_get_mm_emul proc_mm_get_mm
-+#define proc_mm_get_mm_native proc_mm_get_mm64
-+
-+#else
-+
-+#define write_proc_mm write_proc_mm_native
-+#undef write_proc_mm64
-+
-+/*#define proc_mm_get_mm proc_mm_get_mm_native
-+#undef proc_mm_get_mm64*/
-+
-+#define proc_mm_get_mm_native proc_mm_get_mm
-+#undef proc_mm_get_mm_emul
-+
-+#endif
-+
-+#define MM_MMAP 54
-+#define MM_MUNMAP 55
-+#define MM_MPROTECT 56
-+#define MM_COPY_SEGMENTS 57
-+
-+struct mm_mmap {
-+	unsigned long addr;
-+	unsigned long len;
-+	unsigned long prot;
-+	unsigned long flags;
-+	unsigned long fd;
-+	unsigned long offset;
-+};
-+
-+struct mm_munmap {
-+	unsigned long addr;
-+	unsigned long len;
-+};
-+
-+struct mm_mprotect {
-+	unsigned long addr;
-+	unsigned long len;
-+        unsigned int prot;
-+};
-+
-+struct proc_mm_op {
-+	int op;
-+	union {
-+		struct mm_mmap mmap;
-+		struct mm_munmap munmap;
-+	        struct mm_mprotect mprotect;
-+		int copy_segments;
-+	} u;
-+};
-+
-+extern struct mm_struct *proc_mm_get_mm(int fd);
-+
-+/* Cope with older kernels */
-+#ifndef __acquires
-+#define __acquires(x)
-+#endif
-+
-+#ifdef CONFIG_PROC_MM_DUMPABLE
-+/*
-+ * Since we take task_lock of child and it's needed also by the caller, we
-+ * return with it locked.
-+ */
-+extern void lock_fix_dumpable_setting(struct task_struct * child,
-+		struct mm_struct* new) __acquires(child->alloc_lock);
-+#else
-+static inline void lock_fix_dumpable_setting(struct task_struct * child,
-+		struct mm_struct* new) __acquires(child->alloc_lock)
-+{
-+	task_lock(child);
-+}
-+#endif
-+
-+#endif
-Index: linux-2.6.git/localversion-skas
-===================================================================
---- /dev/null
-+++ linux-2.6.git/localversion-skas
-@@ -0,0 +1 @@
-+-skas3-v9-pre9
-Index: linux-2.6.git/mm/Makefile
-===================================================================
---- linux-2.6.git.orig/mm/Makefile
-+++ linux-2.6.git/mm/Makefile
-@@ -24,3 +24,8 @@ obj-$(CONFIG_MEMORY_HOTPLUG) += memory_h
- obj-$(CONFIG_FS_XIP) += filemap_xip.o
- obj-$(CONFIG_MIGRATION) += migrate.o
- 
-+obj-$(CONFIG_PROC_MM)	+= proc_mm.o
-+
-+ifeq ($(CONFIG_PROC_MM),y)
-+obj-m			+= proc_mm-mod.o
-+endif
-Index: linux-2.6.git/mm/mmap.c
-===================================================================
---- linux-2.6.git.orig/mm/mmap.c
-+++ linux-2.6.git/mm/mmap.c
-@@ -875,11 +875,11 @@ void vm_stat_account(struct mm_struct *m
-  * The caller must hold down_write(current->mm->mmap_sem).
-  */
- 
--unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
--			unsigned long len, unsigned long prot,
--			unsigned long flags, unsigned long pgoff)
-+unsigned long __do_mmap_pgoff(struct mm_struct *mm, struct file * file,
-+			    unsigned long addr, unsigned long len,
-+			    unsigned long prot, unsigned long flags,
-+			    unsigned long pgoff)
- {
--	struct mm_struct * mm = current->mm;
- 	struct vm_area_struct * vma, * prev;
- 	struct inode *inode;
- 	unsigned int vm_flags;
-@@ -1153,7 +1153,7 @@ unacct_error:
- 	return error;
- }
- 
--EXPORT_SYMBOL(do_mmap_pgoff);
-+EXPORT_SYMBOL(__do_mmap_pgoff);
- 
- /* Get an address range which is currently unmapped.
-  * For shmat() with addr=0.
-Index: linux-2.6.git/mm/mprotect.c
-===================================================================
---- linux-2.6.git.orig/mm/mprotect.c
-+++ linux-2.6.git/mm/mprotect.c
-@@ -179,8 +179,9 @@ fail:
- 	return error;
- }
- 
--asmlinkage long
--sys_mprotect(unsigned long start, size_t len, unsigned long prot)
-+long
-+do_mprotect(struct mm_struct *mm, unsigned long start, size_t len,
-+	     unsigned long prot)
- {
- 	unsigned long vm_flags, nstart, end, tmp, reqprot;
- 	struct vm_area_struct *vma, *prev;
-@@ -211,9 +212,9 @@ sys_mprotect(unsigned long start, size_t
- 
- 	vm_flags = calc_vm_prot_bits(prot);
- 
--	down_write(&current->mm->mmap_sem);
-+	down_write(&mm->mmap_sem);
- 
--	vma = find_vma_prev(current->mm, start, &prev);
-+	vma = find_vma_prev(mm, start, &prev);
- 	error = -ENOMEM;
- 	if (!vma)
- 		goto out;
-@@ -275,6 +276,15 @@ sys_mprotect(unsigned long start, size_t
- 		}
- 	}
- out:
--	up_write(&current->mm->mmap_sem);
-+	up_write(&mm->mmap_sem);
- 	return error;
- }
-+
-+asmlinkage long sys_mprotect(unsigned long start, size_t len, unsigned long prot)
-+{
-+	long ret = do_mprotect(current->mm, start, len, prot);
-+	/* A tail call would reorder parameters on the stack and they would then
-+	 * be restored at the wrong places. */
-+	prevent_tail_call(ret);
-+	return ret;
-+}
-Index: linux-2.6.git/mm/proc_mm-mod.c
-===================================================================
---- /dev/null
-+++ linux-2.6.git/mm/proc_mm-mod.c
-@@ -0,0 +1,51 @@
-+#include <linux/config.h>
-+#include <linux/kernel.h>
-+#include <linux/proc_mm.h>
-+#include <linux/ptrace.h>
-+#include <linux/module.h>
-+
-+#ifdef CONFIG_64BIT
-+#define PRINT_OFFSET(type, member) \
-+	printk(KERN_DEBUG "struct " #type "32->" #member " \t: %ld\n", (long) offsetof(struct type ## 32, member))
-+#else
-+#define PRINT_OFFSET(type, member) \
-+	printk(KERN_DEBUG "struct " #type "->" #member " \t: %ld\n", (long) offsetof(struct type, member))
-+#endif
-+
-+static int debug_printoffsets(void)
-+{
-+	printk(KERN_DEBUG "Skas core structures layout BEGIN:\n");
-+	PRINT_OFFSET(mm_mmap, addr);
-+	PRINT_OFFSET(mm_mmap, len);
-+	PRINT_OFFSET(mm_mmap, prot);
-+	PRINT_OFFSET(mm_mmap, flags);
-+	PRINT_OFFSET(mm_mmap, fd);
-+	PRINT_OFFSET(mm_mmap, offset);
-+
-+	PRINT_OFFSET(mm_munmap, addr);
-+	PRINT_OFFSET(mm_munmap, len);
-+
-+	PRINT_OFFSET(mm_mprotect, addr);
-+	PRINT_OFFSET(mm_mprotect, len);
-+	PRINT_OFFSET(mm_mprotect, prot);
-+
-+	PRINT_OFFSET(proc_mm_op, op);
-+	PRINT_OFFSET(proc_mm_op, u);
-+	PRINT_OFFSET(proc_mm_op, u.mmap);
-+	PRINT_OFFSET(proc_mm_op, u.munmap);
-+	PRINT_OFFSET(proc_mm_op, u.mprotect);
-+	PRINT_OFFSET(proc_mm_op, u.copy_segments);
-+
-+	PRINT_OFFSET(ptrace_faultinfo, is_write);
-+	PRINT_OFFSET(ptrace_faultinfo, addr);
-+
-+	PRINT_OFFSET(ptrace_ldt, func);
-+	PRINT_OFFSET(ptrace_ldt, ptr);
-+	PRINT_OFFSET(ptrace_ldt, bytecount);
-+	printk(KERN_DEBUG "Skas core structures layout END.\n");
-+
-+	return 0;
-+}
-+#undef PRINT_OFFSET
-+
-+module_init(debug_printoffsets);
-Index: linux-2.6.git/mm/proc_mm.c
-===================================================================
---- /dev/null
-+++ linux-2.6.git/mm/proc_mm.c
-@@ -0,0 +1,300 @@
-+/*
-+ * Copyright (C) 2002 Jeff Dike (jdike at karaya.com)
-+ * Licensed under the GPL
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/compiler.h>
-+#include <linux/mm.h>
-+#include <linux/init.h>
-+#include <linux/proc_fs.h>
-+#include <linux/proc_mm.h>
-+#include <linux/file.h>
-+#include <linux/mman.h>
-+#include <asm/uaccess.h>
-+#include <asm/mmu_context.h>
-+
-+#ifdef CONFIG_PROC_MM_DUMPABLE
-+/* Checks if a task must be considered dumpable
-+ *
-+ * XXX: copied from fs/proc/base.c, removed task_lock, added rmb(): this must be
-+ * called with task_lock(task) held. */
-+static int task_dumpable(struct task_struct *task)
-+{
-+	int dumpable = 0;
-+	struct mm_struct *mm;
-+
-+	mm = task->mm;
-+	if (mm) {
-+		rmb();
-+		dumpable = mm->dumpable;
-+	}
-+	return dumpable;
-+}
-+
-+/*
-+ * This is to be used in PTRACE_SWITCH_MM handling. We are going to set
-+ * child->mm to new, and we must first correctly set new->dumpable.
-+ * Since we take task_lock of child and it's needed also by the caller, we
-+ * return with it locked.
-+ */
-+void lock_fix_dumpable_setting(struct task_struct* child, struct mm_struct* new)
-+	__acquires(child->alloc_lock)
-+{
-+	int dumpable = 1;
-+
-+	/* We must be safe.
-+	 * If the child is ptraced from a non-dumpable process,
-+	 * let's not be dumpable. If the child is non-dumpable itself,
-+	 * copy this property across mm's.
-+	 *
-+	 * Don't try to be smart for the opposite case and turn
-+	 * child->mm->dumpable to 1: I've not made sure it is safe.
-+	 */
-+
-+	task_lock(current);
-+	if (unlikely(!task_dumpable(current))) {
-+		dumpable = 0;
-+	}
-+	task_unlock(current);
-+
-+	task_lock(child);
-+	if (likely(dumpable) && unlikely(!task_dumpable(child))) {
-+		dumpable = 0;
-+	}
-+
-+	if (!dumpable) {
-+		new->dumpable = 0;
-+		wmb();
-+	}
-+}
-+#endif
-+
-+/* Naming conventions are a mess, so I note them down.
-+ *
-+ * Things ending in _mm can be for everything. It's only for
-+ * {open,release}_proc_mm.
-+ *
-+ * For the rest:
-+ *
-+ * _mm means /proc/mm, _mm64 means /proc/mm64. This is for the infrastructure
-+ * only (for instance proc_mm_get_mm checks whether the file is /proc/mm or
-+ * /proc/mm64; for instance the /proc handling).
-+ *
-+ * While for what is conversion dependant, we use the suffix _native and _emul.
-+ * In some cases, there is a mapping between these ones (defined by
-+ * <asm/proc_mm.h>).
-+ */
-+
-+/*These two are common to everything.*/
-+static int open_proc_mm(struct inode *inode, struct file *file)
-+{
-+	struct mm_struct *mm = mm_alloc();
-+	int ret;
-+
-+	ret = -ENOMEM;
-+	if(mm == NULL)
-+		goto out_mem;
-+
-+	init_new_empty_context(mm);
-+	arch_pick_mmap_layout(mm);
-+#ifdef CONFIG_PROC_MM_DUMPABLE
-+	mm->dumpable = current->mm->dumpable;
-+	wmb();
-+#endif
-+
-+	file->private_data = mm;
-+
-+	return 0;
-+
-+out_mem:
-+	return ret;
-+}
-+
-+static int release_proc_mm(struct inode *inode, struct file *file)
-+{
-+	struct mm_struct *mm = file->private_data;
-+
-+	mmput(mm);
-+	return 0;
-+}
-+
-+static struct file_operations proc_mm_fops;
-+
-+struct mm_struct *proc_mm_get_mm_native(int fd);
-+
-+static ssize_t write_proc_mm_native(struct file *file, const char *buffer,
-+			     size_t count, loff_t *ppos)
-+{
-+	struct mm_struct *mm = file->private_data;
-+	struct proc_mm_op req;
-+	int n, ret;
-+
-+	if(count > sizeof(req))
-+		return(-EINVAL);
-+
-+	n = copy_from_user(&req, buffer, count);
-+	if(n != 0)
-+		return(-EFAULT);
-+
-+	ret = count;
-+	switch(req.op){
-+	case MM_MMAP: {
-+		struct mm_mmap *map = &req.u.mmap;
-+
-+		/* Nobody ever noticed it, but do_mmap_pgoff() calls
-+		 * get_unmapped_area() which checks current->mm, if
-+		 * MAP_FIXED is not set, so mmap() could replace
-+		 * an old mapping.
-+		 */
-+		if (! (map->flags & MAP_FIXED))
-+			return(-EINVAL);
-+
-+		ret = __do_mmap(mm, map->addr, map->len, map->prot,
-+			       map->flags, map->fd, map->offset);
-+		if((ret & ~PAGE_MASK) == 0)
-+			ret = count;
-+
-+		break;
-+	}
-+	case MM_MUNMAP: {
-+		struct mm_munmap *unmap = &req.u.munmap;
-+
-+		down_write(&mm->mmap_sem);
-+		ret = do_munmap(mm, unmap->addr, unmap->len);
-+		up_write(&mm->mmap_sem);
-+
-+		if(ret == 0)
-+			ret = count;
-+		break;
-+	}
-+	case MM_MPROTECT: {
-+		struct mm_mprotect *protect = &req.u.mprotect;
-+
-+		ret = do_mprotect(mm, protect->addr, protect->len,
-+				  protect->prot);
-+		if(ret == 0)
-+			ret = count;
-+		break;
-+	}
-+
-+	case MM_COPY_SEGMENTS: {
-+		struct mm_struct *from = proc_mm_get_mm_native(req.u.copy_segments);
-+
-+		if(IS_ERR(from)){
-+			ret = PTR_ERR(from);
-+			break;
-+		}
-+
-+		ret = copy_context(mm, from);
-+		if(ret == 0)
-+			ret = count;
-+		break;
-+	}
-+	default:
-+		ret = -EINVAL;
-+		break;
-+	}
-+
-+	return ret;
-+}
-+
-+/*These three are all for /proc/mm.*/
-+struct mm_struct *proc_mm_get_mm(int fd)
-+{
-+	struct mm_struct *ret = ERR_PTR(-EBADF);
-+	struct file *file;
-+
-+	file = fget(fd);
-+	if (!file)
-+		goto out;
-+
-+	ret = ERR_PTR(-EINVAL);
-+	if(file->f_op != &proc_mm_fops)
-+		goto out_fput;
-+
-+	ret = file->private_data;
-+out_fput:
-+	fput(file);
-+out:
-+	return(ret);
-+}
-+
-+static struct file_operations proc_mm_fops = {
-+	.open		= open_proc_mm,
-+	.release	= release_proc_mm,
-+	.write		= write_proc_mm,
-+};
-+
-+/*Macro-ify it to avoid the duplication.*/
-+static int make_proc_mm(void)
-+{
-+	struct proc_dir_entry *ent;
-+
-+	ent = create_proc_entry("mm", 0222, &proc_root);
-+	if(ent == NULL){
-+		printk("make_proc_mm : Failed to register /proc/mm\n");
-+		return(0);
-+	}
-+	ent->proc_fops = &proc_mm_fops;
-+
-+	return 0;
-+}
-+
-+__initcall(make_proc_mm);
-+
-+/*XXX: change the option.*/
-+#ifdef CONFIG_64BIT
-+static struct file_operations proc_mm64_fops = {
-+	.open		= open_proc_mm,
-+	.release	= release_proc_mm,
-+	.write		= write_proc_mm64,
-+};
-+
-+static int make_proc_mm64(void)
-+{
-+	struct proc_dir_entry *ent;
-+
-+	ent = create_proc_entry("mm64", 0222, &proc_root);
-+	if(ent == NULL){
-+		printk("make_proc_mm : Failed to register /proc/mm64\n");
-+		return(0);
-+	}
-+	ent->proc_fops = &proc_mm64_fops;
-+
-+	return 0;
-+}
-+
-+__initcall(make_proc_mm64);
-+
-+struct mm_struct *proc_mm_get_mm64(int fd)
-+{
-+	struct mm_struct *ret = ERR_PTR(-EBADF);
-+	struct file *file;
-+
-+	file = fget(fd);
-+	if (!file)
-+		goto out;
-+
-+	ret = ERR_PTR(-EINVAL);
-+	/*This is the only change.*/
-+	if(file->f_op != &proc_mm64_fops)
-+		goto out_fput;
-+
-+	ret = file->private_data;
-+out_fput:
-+	fput(file);
-+out:
-+	return(ret);
-+}
-+#endif
-+/*
-+ * Overrides for Emacs so that we follow Linus's tabbing style.
-+ * Emacs will notice this stuff at the end of the file and automatically
-+ * adjust the settings for this buffer only.  This must remain at the end
-+ * of the file.
-+ * ---------------------------------------------------------------------------
-+ * Local variables:
-+ * c-file-style: "linux"
-+ * End:
-+ */

Copied: trunk/src/linux-patch-skas/debian (from rev 159, trunk/src/kernel-patch-skas/debian)

Deleted: trunk/src/linux-patch-skas/debian/changelog
===================================================================
--- trunk/src/kernel-patch-skas/debian/changelog	2006-08-24 19:09:05 UTC (rev 159)
+++ trunk/src/linux-patch-skas/debian/changelog	2006-08-27 15:16:57 UTC (rev 167)
@@ -1,97 +0,0 @@
-kernel-patch-skas (3-10) unstable; urgency=low
-
-  * replaced pkg name from kernel-patch-skas to linux-patch-skas.
-  * updated 2.6.17 support with patch from Paolo Giarrusso repos.
-  * put kernel-patch-skas under the u-m-l Maintainers wing
-  * Update 2.4.25 patch with latest available from Paolo Giarrusso.
-  * add 2.6.10 patch from Paolo Giarrusso. (Closes: #293685)
-  * filled the gap until 2.6.16 with patches from Paolo Giarrusso..
-  * updated debhelper compatibility version.
-
- -- Mattia Dongili <malattia at debian.org>  Sun, 14 May 2006 18:20:02 +0200
-
-kernel-patch-skas (3-9.3) unstable; urgency=low
-
-  * NMU
-  * Mark 2.4.27 and 2.4.26 as supported by the 2.4.25 patch (Closes: #257583)
-
- -- Bill Allombert <ballombe at debian.org>  Fri, 27 May 2005 17:20:28 +0200
-
-kernel-patch-skas (3-9.2) unstable; urgency=high
-
-  * NMU
-  * Retrofitted 2.6.8.1 patch for 2.6.8 (closes: #281554)
-  * debian/copyright: removed dh_make boilerplatedness
-
- -- Andrew Pollock <apollock at debian.org>  Sun,  8 May 2005 12:44:15 +1000
-
-kernel-patch-skas (3-9.1) unstable; urgency=low
-
-  * Add patch from Paolo Giarrusso for kernel 2.6.9 (Closes: #281554) 
-
- -- Jonas Meurer <mejo at debian.org>  Tue, 23 Nov 2004 16:05:15 +0100
-
-kernel-patch-skas (3-9) unstable; urgency=low
-
-  * Add patch from Paolo Giarrusso for kernel 2.6.7
-
- -- Matt Zimmerman <mdz at debian.org>  Wed, 21 Jul 2004 14:23:14 -0700
-
-kernel-patch-skas (3-8) unstable; urgency=low
-
-  * Add patch from Paolo Giarrusso for kernel 2.6.6
-
- -- Matt Zimmerman <mdz at debian.org>  Fri, 28 May 2004 10:10:07 -0700
-
-kernel-patch-skas (3-7) unstable; urgency=low
-
-  * Remove some unused variables in debian/rules (Closes: #248036)
-  * Switch from $DH_COMPAT to debian/compat
-
- -- Matt Zimmerman <mdz at debian.org>  Thu, 13 May 2004 20:54:41 -0700
-
-kernel-patch-skas (3-6) unstable; urgency=low
-
-  * Update 2.6 patch to host-skas3-2.6.3-v1.patch from Paolo Giarrusso
-    (Closes: #233622)
-  * Mark 2.6 patch as compatible with 2.6.4 and 2.6.5
-
- -- Matt Zimmerman <mdz at debian.org>  Thu, 22 Apr 2004 23:32:05 -0700
-
-kernel-patch-skas (3-5) unstable; urgency=low
-
-  * Start including third-party patches which bring skas up to date with
-    current kernels
-    - host-skas3-2.4.25.patch from Paolo Giarrusso, aka Blaisorblade
-      (Closes: #237014)
-      - No longer lets you try to disable PROC_MM (Closes: #223680)
-    - linux-2.6.1-skas3.patch from Stephen D. Williams
-  
- -- Matt Zimmerman <mdz at debian.org>  Sat, 13 Mar 2004 15:58:07 -0800
-
-kernel-patch-skas (3-4) unstable; urgency=low
-
-  * Applies fine to 2.4.2[234], update kpatches and Suggests
-
- -- Matt Zimmerman <mdz at debian.org>  Thu,  8 Jan 2004 11:13:59 -0800
-
-kernel-patch-skas (3-3) unstable; urgency=low
-
-  * Suggest kernel-source-2.4.21 (latest we support)
-  * Add kpatches stanza for kernel version 2.4.22 so that the patch is
-    automatically applied
-
- -- Matt Zimmerman <mdz at debian.org>  Wed, 17 Dec 2003 13:34:11 -0800
-
-kernel-patch-skas (3-2) unstable; urgency=low
-
-  * Update kpatches to indicate that this patch works with 2.4.21, and no
-    longer works with Debian 2.4.20 (Closes: #201072)
-
- -- Matt Zimmerman <mdz at debian.org>  Sun, 13 Jul 2003 19:42:02 -0400
-
-kernel-patch-skas (3-1) unstable; urgency=low
-
-  * Initial release (Closes: #176961)
-
- -- Matt Zimmerman <mdz at debian.org>  Sat, 15 Feb 2003 23:20:10 -0500

Copied: trunk/src/linux-patch-skas/debian/changelog (from rev 165, trunk/src/kernel-patch-skas/debian/changelog)

Deleted: trunk/src/linux-patch-skas/debian/control
===================================================================
--- trunk/src/kernel-patch-skas/debian/control	2006-08-24 19:09:05 UTC (rev 159)
+++ trunk/src/linux-patch-skas/debian/control	2006-08-27 15:16:57 UTC (rev 167)
@@ -1,20 +0,0 @@
-Source: linux-patch-skas
-Section: devel
-Priority: extra
-Maintainer: User Mode Linux Maintainers <pkg-uml-pkgs at lists.alioth.debian.org>
-Uploaders: Andreas Schuldei <andreas at schuldei.org>, Mattia Dongili <malattia at debian.org>, Stefano Melchior <stefano.melchior at openlabs.it>
-Build-Depends: debhelper (>> 4.0.0)
-Build-Depends-Indep: debhelper (>> 4.0.0), dh-kpatches
-Standards-Version: 3.7.2
-
-Package: linux-patch-skas
-Architecture: all
-Depends: ${kpatch:Depends}
-Suggests: linux-source-2.6 | kernel-source-2.6 | kernel-source-2.4
-Conflicts: kernel-patch-skas
-Replaces: kernel-patch-skas
-Provides: kernel-patch-skas
-Description: Separate Kernel Address Space patch
- This patch was created in order to provide enhanced security and performance
- for user-mode linux by allowing the UML kernel to run in a separate address
- space from the UML user processes.

Copied: trunk/src/linux-patch-skas/debian/control (from rev 165, trunk/src/kernel-patch-skas/debian/control)

Copied: trunk/src/linux-patch-skas/debian/patches (from rev 161, trunk/src/kernel-patch-skas/debian/patches)

Deleted: trunk/src/linux-patch-skas/debian/rules
===================================================================
--- trunk/src/kernel-patch-skas/debian/rules	2006-08-24 19:09:05 UTC (rev 159)
+++ trunk/src/linux-patch-skas/debian/rules	2006-08-27 15:16:57 UTC (rev 167)
@@ -1,64 +0,0 @@
-#!/usr/bin/make -f
-# Sample debian/rules that uses debhelper.
-# GNU copyright 1997 to 1999 by Joey Hess.
-
-# Uncomment this to turn on verbose mode.
-#export DH_VERBOSE=1
-
-configure: configure-stamp
-configure-stamp:
-	dh_testdir
-
-	touch configure-stamp
-
-build: configure-stamp build-stamp
-build-stamp:
-	dh_testdir
-
-	touch build-stamp
-
-clean:
-	dh_testdir
-	dh_testroot
-	rm -f configure-stamp build-stamp
-
-	dh_clean
-
-install: build
-	dh_testdir
-	dh_testroot
-	dh_clean -k
-	dh_installdirs
-	dh_installkpatches
-
-# Build architecture-independent files here.
-binary-indep: build install
-	dh_testdir
-	dh_testroot
-#	dh_installdebconf	
-	dh_installdocs
-#	dh_installexamples
-#	dh_installmenu
-#	dh_installlogrotate
-#	dh_installemacsen
-#	dh_installpam
-#	dh_installmime
-#	dh_installinit
-#	dh_installcron
-#	dh_installman
-#	dh_installinfo
-#	dh_undocumented
-	dh_installchangelogs 
-	dh_link
-	dh_compress
-	dh_fixperms
-	dh_installdeb
-#	dh_perl
-	dh_gencontrol
-	dh_md5sums
-	dh_builddeb
-
-binary-arch:
-
-binary: binary-indep
-.PHONY: build clean binary-indep binary-arch binary install configure

Copied: trunk/src/linux-patch-skas/debian/rules (from rev 166, trunk/src/kernel-patch-skas/debian/rules)

Copied: trunk/src/linux-patch-skas/host-skas3-2.4.25-v3.patch (from rev 160, trunk/src/kernel-patch-skas/host-skas3-2.4.25-v3.patch)

Copied: trunk/src/linux-patch-skas/host-skas3-2.6.3-v1.patch (from rev 160, trunk/src/kernel-patch-skas/host-skas3-2.6.3-v1.patch)

Copied: trunk/src/linux-patch-skas/host-skas3-2.6.6-v1.patch (from rev 160, trunk/src/kernel-patch-skas/host-skas3-2.6.6-v1.patch)

Copied: trunk/src/linux-patch-skas/host-skas3-2.6.7-v1.patch (from rev 160, trunk/src/kernel-patch-skas/host-skas3-2.6.7-v1.patch)

Copied: trunk/src/linux-patch-skas/host-skas3-2.6.8-v6.patch (from rev 160, trunk/src/kernel-patch-skas/host-skas3-2.6.8-v6.patch)

Copied: trunk/src/linux-patch-skas/host-skas3-2.6.9-v7.patch (from rev 160, trunk/src/kernel-patch-skas/host-skas3-2.6.9-v7.patch)

Copied: trunk/src/linux-patch-skas/host-skas3.patch (from rev 160, trunk/src/kernel-patch-skas/host-skas3.patch)

Copied: trunk/src/linux-patch-skas/skas-2.6.10-v8.patch (from rev 160, trunk/src/kernel-patch-skas/skas-2.6.10-v8.patch)

Copied: trunk/src/linux-patch-skas/skas-2.6.11-v8.2.patch (from rev 160, trunk/src/kernel-patch-skas/skas-2.6.11-v8.2.patch)

Copied: trunk/src/linux-patch-skas/skas-2.6.12-v9-pre7.patch (from rev 160, trunk/src/kernel-patch-skas/skas-2.6.12-v9-pre7.patch)

Copied: trunk/src/linux-patch-skas/skas-2.6.13-rc7-v9-pre7.patch (from rev 160, trunk/src/kernel-patch-skas/skas-2.6.13-rc7-v9-pre7.patch)

Copied: trunk/src/linux-patch-skas/skas-2.6.14-v9-pre7.patch (from rev 160, trunk/src/kernel-patch-skas/skas-2.6.14-v9-pre7.patch)

Copied: trunk/src/linux-patch-skas/skas-2.6.15-v9-pre8.patch (from rev 160, trunk/src/kernel-patch-skas/skas-2.6.15-v9-pre8.patch)

Copied: trunk/src/linux-patch-skas/skas-2.6.16-v9-pre9.patch (from rev 160, trunk/src/kernel-patch-skas/skas-2.6.16-v9-pre9.patch)

Copied: trunk/src/linux-patch-skas/skas-2.6.17-rc5-v9-pre9.patch (from rev 160, trunk/src/kernel-patch-skas/skas-2.6.17-rc5-v9-pre9.patch)




More information about the Pkg-uml-commit mailing list