--- linux-2.6.6/arch/i386/kernel/sys_i386.c.~1~ 2004-05-10 21:34:36.000000000 +0200 +++ linux-2.6.6/arch/i386/kernel/sys_i386.c 2004-05-11 17:04: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,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.6/arch/i386/kernel/ptrace.c.~1~ 2004-05-10 21:36:05.000000000 +0200 +++ linux-2.6.6/arch/i386/kernel/ptrace.c 2004-05-11 17:04:18.000000000 +0200 @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -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.6/arch/i386/kernel/ldt.c.~1~ 2004-05-10 21:34:36.000000000 +0200 +++ linux-2.6.6/arch/i386/kernel/ldt.c 2004-05-11 17:04:18.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); +} --- linux-2.6.6/arch/i386/Kconfig.~1~ 2004-05-10 21:36:04.000000000 +0200 +++ linux-2.6.6/arch/i386/Kconfig 2004-05-11 17:04:18.000000000 +0200 @@ -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.6/arch/um/include/skas_ptrace.h.~1~ 2004-05-11 17:03:03.000000000 +0200 +++ linux-2.6.6/arch/um/include/skas_ptrace.h 2004-05-11 17:04:18.000000000 +0200 @@ -6,6 +6,10 @@ #ifndef __SKAS_PTRACE_H #define __SKAS_PTRACE_H + +#ifndef _LINUX_PTRACE_STRUCT_DEF +#define _LINUX_PTRACE_STRUCT_DEF + struct ptrace_faultinfo { int is_write; unsigned long addr; @@ -17,6 +21,8 @@ unsigned long bytecount; }; +#endif /*ifndef _LINUX_PTRACE_STRUCT_DEF*/ + #define PTRACE_FAULTINFO 52 #define PTRACE_SIGPENDING 53 #define PTRACE_LDT 54 --- linux-2.6.6/arch/um/kernel/ptrace.c.~1~ 2004-05-11 17:03:28.000000000 +0200 +++ linux-2.6.6/arch/um/kernel/ptrace.c 2004-05-11 17:04:18.000000000 +0200 @@ -24,11 +24,6 @@ { } -extern long do_mmap2(struct task_struct *task, unsigned long addr, - unsigned long len, unsigned long prot, - unsigned long flags, unsigned long fd, - unsigned long pgoff); - int sys_ptrace(long request, long pid, long addr, long data) { struct task_struct *child; --- linux-2.6.6/arch/um/kernel/syscall_kern.c.~1~ 2004-05-11 17:03:28.000000000 +0200 +++ linux-2.6.6/arch/um/kernel/syscall_kern.c 2004-05-11 17:04:18.000000000 +0200 @@ -82,7 +82,7 @@ } down_write(&mm->mmap_sem); - error = do_mmap_pgoff(mm, file, addr, len, prot, flags, pgoff); + error = __do_mmap_pgoff(mm, file, addr, len, prot, flags, pgoff); up_write(&mm->mmap_sem); if (file) --- linux-2.6.6/include/linux/mm.h.~1~ 2004-05-11 17:03:28.000000000 +0200 +++ linux-2.6.6/include/linux/mm.h 2004-05-11 17:04:18.000000000 +0200 @@ -505,9 +505,6 @@ */ typedef int (*shrinker_t)(int nr_to_scan, unsigned int gfp_mask); -extern long do_mprotect(struct mm_struct *mm, unsigned long start, - size_t len, unsigned long prot); - /* * Add an aging callback. The int is the number of 'seeks' it takes * to recreate one of the objects that these functions age. @@ -518,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 @@ -551,10 +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 mm_struct *mm, struct file *file, +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) { + 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, @@ -564,8 +569,7 @@ if ((offset + PAGE_ALIGN(len)) < offset) goto out; if (!(offset & ~PAGE_MASK)) - ret = do_mmap_pgoff(current->mm, file, addr, len, prot, flag, - offset >> PAGE_SHIFT); + ret = do_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT); out: return ret; } --- linux-2.6.6/include/asm-i386/desc.h.~1~ 2004-05-10 21:34:36.000000000 +0200 +++ linux-2.6.6/include/asm-i386/desc.h 2004-05-11 17:04:18.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 --- linux-2.6.6/include/asm-i386/processor.h.~1~ 2004-05-10 21:37:21.000000000 +0200 +++ linux-2.6.6/include/asm-i386/processor.h 2004-05-11 17:04:18.000000000 +0200 @@ -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.6/include/asm-i386/ptrace.h.~1~ 2004-05-10 21:34:36.000000000 +0200 +++ linux-2.6.6/include/asm-i386/ptrace.h 2004-05-11 17:04:18.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 --- linux-2.6.6/include/asm-i386/mmu_context.h.~1~ 2004-05-10 21:34:36.000000000 +0200 +++ linux-2.6.6/include/asm-i386/mmu_context.h 2004-05-11 17:04:18.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 --- linux-2.6.6/include/asm-um/processor-generic.h.~1~ 2004-05-11 17:03:04.000000000 +0200 +++ linux-2.6.6/include/asm-um/processor-generic.h 2004-05-11 17:04:18.000000000 +0200 @@ -99,9 +99,9 @@ extern unsigned long thread_saved_pc(struct task_struct *t); -static inline void mm_copy_segments(struct mm_struct *from_mm, - struct mm_struct *new_mm) +static inline int __init_new_context(struct mm_struct *mm, struct mm_struct *old_mm) { + return 0; } #define init_stack (init_thread_union.stack) --- linux-2.6.6/mm/Makefile.~1~ 2004-05-11 17:03:28.000000000 +0200 +++ linux-2.6.6/mm/Makefile 2004-05-11 17:04:18.000000000 +0200 @@ -12,5 +12,6 @@ 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 obj-$(CONFIG_HUGETLBFS) += hugetlb.o +obj-$(CONFIG_PROC_MM) += proc_mm.o + --- linux-2.6.6/mm/mmap.c.~1~ 2004-05-11 17:03:28.000000000 +0200 +++ linux-2.6.6/mm/mmap.c 2004-05-11 17:04:18.000000000 +0200 @@ -480,7 +480,7 @@ * The caller must hold down_write(current->mm->mmap_sem). */ -unsigned long do_mmap_pgoff(struct mm_struct *mm, struct file * file, +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) @@ -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.6/mm/mprotect.c.~1~ 2004-05-11 17:03:28.000000000 +0200 +++ linux-2.6.6/mm/mprotect.c 2004-05-11 17:04:18.000000000 +0200 @@ -223,7 +223,7 @@ return error; } -asmlinkage long +long do_mprotect(struct mm_struct *mm, unsigned long start, size_t len, unsigned long prot) { --- linux-2.6.6/mm/proc_mm.c.~1~ 2004-05-11 17:03:28.000000000 +0200 +++ linux-2.6.6/mm/proc_mm.c 2004-05-11 17:04:18.000000000 +0200 @@ -93,7 +93,7 @@ break; } - mm_copy_segments(from, mm); + __init_new_context(mm, from); break; } default: