[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 && (¤t->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(¤t->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(¤t->mm->mmap_sem);
-- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-- up_write(¤t->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(¤t->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(¤t->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(¤t->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(¤t->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, ¤t->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(¤t->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(¤t->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, ¤t->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(¤t->mm->mmap_sem);
-- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-- up_write(¤t->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 && (¤t->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(¤t->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(¤t->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(¤t->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, ¤t->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(¤t->mm->mmap_sem);
-- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-- up_write(¤t->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 && (¤t->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(¤t->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(¤t->mm->mmap_sem);
-- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-- up_write(¤t->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 && (¤t->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(¤t->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(¤t->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(¤t->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, ¤t->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 && (¤t->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(¤t->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(¤t->mm->mmap_sem);
-- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-- up_write(¤t->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(¤t->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(¤t->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(¤t->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(¤t->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, ¤t->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(¤t->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(¤t->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(¤t->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(¤t->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, ¤t->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 && (¤t->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(¤t->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(¤t->mm->mmap_sem);
-- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-- up_write(¤t->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(¤t->mm->mmap_sem);
-- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-- up_write(¤t->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(¤t->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(¤t->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, ¤t->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(¤t->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(¤t->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(¤t->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(¤t->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 (¤t->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 (¤t->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(¤t->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(¤t->mm->mmap_sem);
-- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-- up_write(¤t->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(¤t->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(¤t->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 (¤t->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 (¤t->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(¤t->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(¤t->mm->mmap_sem);
-- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-- up_write(¤t->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(¤t->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(¤t->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 (¤t->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 (¤t->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(¤t->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(¤t->mm->mmap_sem);
-- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-- up_write(¤t->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 (¤t->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 (¤t->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(¤t->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(¤t->mm->mmap_sem);
-- error = do_mmap_pgoff(file, addr, len, prot, flags, off >> PAGE_SHIFT);
-- up_write(¤t->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(¤t->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(¤t->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 (¤t->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 (¤t->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(¤t->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(¤t->mm->mmap_sem);
-- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-- up_write(¤t->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 (¤t->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 (¤t->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(¤t->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(¤t->mm->mmap_sem);
-- error = do_mmap_pgoff(file, addr, len, prot, flags, off >> PAGE_SHIFT);
-- up_write(¤t->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 (¤t->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 (¤t->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(¤t->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(¤t->mm->mmap_sem);
-- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-- up_write(¤t->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 (¤t->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 (¤t->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(¤t->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(¤t->mm->mmap_sem);
-- error = do_mmap_pgoff(file, addr, len, prot, flags, off >> PAGE_SHIFT);
-- up_write(¤t->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(¤t->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(¤t->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 (¤t->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 (¤t->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(¤t->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(¤t->mm->mmap_sem);
-- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-- up_write(¤t->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 (¤t->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 (¤t->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(¤t->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(¤t->mm->mmap_sem);
-- error = do_mmap_pgoff(file, addr, len, prot, flags, off >> PAGE_SHIFT);
-- up_write(¤t->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(¤t->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(¤t->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 (¤t->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 (¤t->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(¤t->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(¤t->mm->mmap_sem);
-- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
-- up_write(¤t->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 (¤t->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 (¤t->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(¤t->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(¤t->mm->mmap_sem);
-- error = do_mmap_pgoff(file, addr, len, prot, flags, off >> PAGE_SHIFT);
-- up_write(¤t->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(¤t->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(¤t->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 (¤t->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 (¤t->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(¤t->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 (¤t->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 (¤t->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(¤t->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(¤t->mm->mmap_sem);
-- error = do_mmap_pgoff(file, addr, len, prot, flags, off >> PAGE_SHIFT);
-- up_write(¤t->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(¤t->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(¤t->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