SKAS4 - Host get_mm and switch_mm
Subsystems (8)
RFC PATCH 3/12 SKAS4 - Host get_mm and switch_mm
This is the new_mm, switch_mm, and /proc/<pid>/mm implementation for 32- and 64-bit x86 and UML, plus 32-bit support on 64-bit x86.
arch/um/include/skas_ptrace.h +4 -13
@@ -1,5 +1,5 @@/* -* Copyright (C) 2000, 2001, 2002 Jeff Dike ([email protected]) +* Copyright (C) 2000 - 2008 Jeff Dike (jdike@{addtoit,linux.intel}.com) * Licensed under the GPL */
@@ -7,19 +7,10 @@#define __SKAS_PTRACE_H#define PTRACE_FAULTINFO 52 -#define PTRACE_SWITCH_MM 55 +#ifndef OLD_PTRACE_SWITCH_MM +#define OLD_PTRACE_SWITCH_MM 55 +#endif #include "sysdep/skas_ptrace.h" #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: -*/
arch/um/include/sysdep-i386/ptrace_user.h +2 -0
@@ -43,6 +43,8 @@#define FP_SIZE ((HOST_XFP_SIZE > HOST_FP_SIZE) ? HOST_XFP_SIZE : HOST_FP_SIZE) +#define FP_SIZE ((HOST_XFP_SIZE > HOST_FP_SIZE) ? HOST_XFP_SIZE : HOST_FP_SIZE) +#ifndef FRAME_SIZE #define FRAME_SIZE (17)#endif
arch/um/include/sysdep-x86_64/ptrace_user.h +2 -0
@@ -72,6 +72,8 @@#define FP_SIZE (HOST_FP_SIZE) +#define FP_SIZE (HOST_FP_SIZE) +#endif /*
arch/um/kernel/ptrace.c +34 -1
@@ -192,7 +192,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) }#endif #ifdef CONFIG_PROC_MM -case PTRACE_SWITCH_MM : { +case OLD_PTRACE_SWITCH_MM : {struct mm_struct *old = child->mm;struct mm_struct *new =proc_mm_get_mm (data);
@@ -292,3 +292,36 @@ void syscall_trace(struct uml_pt_regs *regs, int entryexit) current->exit_code =0 ; } } + +int ptrace_to_pt_regs (struct pt_regs *to,struct user_regs __user *from) +{ +struct user_regs regs; +int rem; + + rem =copy_from_user (®s, from,sizeof (regs)); +if (rem) +return -EFAULT ; + +memcpy (&to->regs.gp, ®s.regs,sizeof (to->regs.gp)); + +return put_fp_registers (userspace_pid[0 ], + (unsigned long *) ®s.fpregs); +} + +int pt_regs_to_ptrace (struct user_regs __user *to,struct pt_regs *from) +{ +struct user_regs regs; +int err; + + err =get_fp_registers (userspace_pid[0 ], + (unsigned long *) ®s.fpregs); +if (err) +return err; + +memcpy (®s.regs, &from->regs.gp,sizeof (regs.regs)); + +if (copy_to_user (to, ®s,sizeof (regs))) +return -EFAULT ; + +return 0 ; +}
arch/um/kernel/syscall.c +10 -0
@@ -148,3 +148,13 @@ int kernel_execve(const char *filename, char *const argv[], char *const envp[])return ret; } + +extern long do_switch_mm (int fd,long __user *save,long __user *new, +unsigned long ip,unsigned long sp, +struct pt_regs *regs); + +long sys_switch_mm (int fd,long __user *save,long __user *new, +unsigned long ip,unsigned long sp) +{ +return do_switch_mm (fd, save, new, ip, sp, ¤t->thread.regs); +}
arch/um/os-Linux/skas/process.c +1 -1
@@ -716,7 +716,7 @@ void __switch_mm(struct mm_id *mm_idp)/* FIXME: need cpu pid in __switch_mm */ if (proc_mm) { - err =ptrace (PTRACE_SWITCH_MM , userspace_pid[0 ],0 , + err =ptrace (OLD_PTRACE_SWITCH_MM , userspace_pid[0 ],0 , mm_idp->u.mm_fd);if (err) { printk(UM_KERN_ERR "__switch_mm - PTRACE_SWITCH_MM "
arch/um/sys-x86_64/syscall_table.c +1 -0
@@ -39,6 +39,7 @@#define stub_rt_sigsuspend sys_rt_sigsuspend#define stub_sigaltstack sys_sigaltstack#define stub_rt_sigreturn sys_rt_sigreturn +#define stub_switch_mm sys_switch_mm#define __SYSCALL (nr, sym) extern asmlinkage void sym(void) ;#undef _ASM_X86_64_UNISTD_H_
arch/x86/ia32/ia32entry.S +3 -0
@@ -373,6 +373,7 @@ quiet_ni_syscall: PTREGSCALL stub32_vfork, sys_vfork, %rdi PTREGSCALL stub32_iopl, sys_iopl, %rsi PTREGSCALL stub32_rt_sigsuspend, sys_rt_sigsuspend, %rdx + PTREGSCALL stub32_switch_mm, sys_switch_mm, %r9 ENTRY(ia32_ptregs_common) popq %r11
@@ -727,4 +728,6 @@ ia32_sys_call_table: .quad sys32_fallocate .quad compat_sys_timerfd_settime /* 325 */ .quad compat_sys_timerfd_gettime + .quad sys_new_mm + .quad stub32_switch_mm ia32_syscall_end:
arch/x86/kernel/entry_64.S +1 -0
@@ -425,6 +425,7 @@ END(\label) PTREGSCALL stub_rt_sigsuspend, sys_rt_sigsuspend, %rdx PTREGSCALL stub_sigaltstack, sys_sigaltstack, %rdx PTREGSCALL stub_iopl, sys_iopl, %rsi + PTREGSCALL stub_switch_mm, sys_switch_mm, %r9 ENTRY(ptregscall_common) popq %r11
arch/x86/kernel/ptrace.c +174 -5
219 lines not on this page · raw message
arch/x86/kernel/sys_i386_32.c +12 -0
@@ -21,6 +21,7 @@#include <asm/uaccess.h> #include <asm/unistd.h> +#include <asm/user.h> /* * sys_pipe() is the normal C calling standard for creating
@@ -261,3 +262,14 @@ int kernel_execve(const char *filename, char *const argv[], char *const envp[]) : "0" (__NR_execve),"ri" (filename),"c" (argv), "d" (envp) : "memory");return __res; } + +extern long do_switch_mm (int fd,struct __user user_regs *save, +struct __user user_regs *new,unsigned long ip, +unsigned long sp,struct pt_regs *regs); + +asmlinkage long sys_switch_mm (struct pt_regs regs) +{ +return do_switch_mm (regs.bx, (struct __user user_regs *) regs.cx, + (struct __user user_regs *) regs.dx, regs.si, + regs.di, ®s); +}
arch/x86/kernel/sys_x86_64.c +11 -0
@@ -251,3 +251,14 @@ asmlinkage long sys_uname(struct new_utsname __user * name) err |=copy_to_user (&name->machine,"i686" ,5 );return err ? -EFAULT :0 ; } + +extern long do_switch_mm (int fd,struct __user user_regs *save, +struct __user user_regs *new,unsigned long ip, +unsigned long sp,struct pt_regs *regs); + +asmlinkage long sys_switch_mm (int fd,struct __user user_regs *save, +struct __user user_regs *new,unsigned long ip, +unsigned long sp,struct pt_regs *regs) +{ +return do_switch_mm (fd, save, new, ip, sp, regs); +}
arch/x86/kernel/syscall_table_32.S +2 -0
@@ -326,3 +326,5 @@ ENTRY(sys_call_table) .long sys_fallocate .long sys_timerfd_settime /* 325 */ .long sys_timerfd_gettime + .long sys_new_mm + .long sys_switch_mm
fs/proc/base.c +32 -0
@@ -2279,6 +2279,37 @@ static int proc_pid_io_accounting(struct task_struct *task, char *buffer) }#endif +static int proc_pid_mm_open (struct inode *inode,struct file *file) +{ +struct task_struct *task =pid_task (proc_pid (inode),PIDTYPE_PID ); +struct mm_struct *mm; + +if (task ==NULL ) +return -ENOENT ; + + mm =get_task_mm (task); +if (mm ==NULL ) +return -EINVAL ; + + file->private_data = mm; +return 0 ; +} + +static int proc_pid_mm_release (struct inode *inode,struct file *file) +{ +struct mm_struct *mm = file->private_data; + +if (mm !=NULL ) +mmput (mm); + +return 0 ; +} + +const struct file_operations proc_pid_mm_operations = { + .open = proc_pid_mm_open, + .release = proc_pid_mm_release, +}; +/* * Thread groups */
@@ -2350,6 +2381,7 @@ static const struct pid_entry tgid_base_stuff[] = {#ifdef CONFIG_TASK_IO_ACCOUNTING INF ("io" ,S_IRUGO , pid_io_accounting), #endif + REG("mm", S_IRUSR | S_IWUSR, pid_mm), }; static int proc_tgid_base_readdir(struct file * filp,
include/asm-um/ptrace-generic.h +9 -0
@@ -34,6 +34,15 @@ struct pt_regs {#define instruction_pointer (regs) PT_REGS_IP(regs) +struct user_regs { +unsigned long regs[MAX_REG_NR ]; +void *ptr; +unsigned long fpregs[FP_SIZE ]; +}; + +extern int ptrace_to_pt_regs (struct pt_regs *to,struct user_regs __user *from); +extern int pt_regs_to_ptrace (struct user_regs __user *to,struct pt_regs *from); +struct task_struct ; extern long subarch_ptrace(struct task_struct *child, long request, long addr,
include/asm-um/ptrace-i386.h +11 -2
@@ -8,8 +8,11 @@#define HOST_AUDIT_ARCH AUDIT_ARCH_I386 -#include "linux/compiler.h" -#include "asm/ptrace-generic.h" +#include "user_constants.h" +#define FP_SIZE ((HOST_XFP_SIZE > HOST_FP_SIZE) ? HOST_XFP_SIZE : HOST_FP_SIZE) + +#include <linux/compiler.h> +#include <asm/ptrace-generic.h> #include <asm/user.h> #include "sysdep/ptrace.h"
@@ -40,6 +43,12 @@#define user_mode (r) UPT_IS_USER(&(r)->regs) +#define pt_regs_ip (r) (r).regs.gp[EIP] +#define pt_regs_sp (r) (r).regs.gp[UESP] + +#define ptrace_ip (r) (r)->regs[EIP] +#define ptrace_sp (r) (r)->regs[UESP] +/* * Forward declaration to avoid including sysdep/tls.h, which causes a * circular include, and compilation failures.
include/asm-um/ptrace-x86_64.h +9 -0
@@ -7,6 +7,9 @@#ifndef __UM_PTRACE_X86_64_H#define __UM_PTRACE_X86_64_H +#include "user_constants.h" +#define FP_SIZE (HOST_FP_SIZE) +#include "linux/compiler.h" #include "asm/errno.h" #include "asm/host_ldt.h"
@@ -62,6 +65,12 @@#define PT_FIX_EXEC_STACK (sp) do ; while(0) +#define pt_regs_ip (r) (r).regs.gp[RIP / sizeof(long)] +#define pt_regs_sp (r) (r).regs.gp[RSP / sizeof(long)] + +#define ptrace_ip (r) (r)->regs[RIP / sizeof(long)] +#define ptrace_sp (r) (r)->regs[RSP / sizeof(long)] +#define profile_pc (regs) PT_REGS_IP(regs) static inline int ptrace_get_thread_area(struct task_struct *child, int idx,
include/asm-x86/Kbuild +1 -0
@@ -21,5 +21,6 @@ unifdef-y += posix_types_64.h unifdef-y += ptrace.h unifdef-y += unistd_32.h unifdef-y += unistd_64.h +unifdef-y += user.h unifdef-y += vm86.h unifdef-y += vsyscall.h
include/asm-x86/ptrace.h +59 -1
78 lines not on this page · raw message
include/asm-x86/unistd_32.h +2 -0
@@ -332,6 +332,8 @@#define __NR_fallocate 324#define __NR_timerfd_settime 325#define __NR_timerfd_gettime 326 +#define __NR_new_mm 327 +#define __NR_switch_mm 328#ifdef __KERNEL__
include/asm-x86/unistd_64.h +4 -0
@@ -639,6 +639,10 @@ __SYSCALL(__NR_fallocate, sys_fallocate) __SYSCALL(__NR_timerfd_settime, sys_timerfd_settime)#define __NR_timerfd_gettime 287 __SYSCALL(__NR_timerfd_gettime, sys_timerfd_gettime) +#define __NR_new_mm 288 +__SYSCALL(__NR_new_mm, sys_new_mm) +#define __NR_switch_mm 289 +__SYSCALL(__NR_switch_mm, stub_switch_mm)#ifndef __NO_STUBS
include/linux/ptrace.h +2 -0
@@ -21,6 +21,8 @@#define PTRACE_SYSCALL 24 +#define PTRACE_SWITCH_MM 34 +/* 0x4200-0x4300 are reserved for architecture-independent additions. */ #define PTRACE_SETOPTIONS 0x4200#define PTRACE_GETEVENTMSG 0x4201
include/linux/sched.h +1 -0
@@ -1750,6 +1750,7 @@ static inline int sas_ss_flags(unsigned long sp)* Routines for handling mm_structs */ extern struct mm_struct *mm_alloc (void ); +extern struct mm_struct *dup_mm (struct task_struct *tsk);/* mmdrop drops the mm and the page tables */ extern void __mmdrop (struct mm_struct *);
kernel/fork.c +1 -1
@@ -498,7 +498,7 @@ void mm_release(struct task_struct *tsk, struct mm_struct *mm)* Allocate a new mm structure and copy contents from the * mm structure of the passed in task structure. */ -static struct mm_struct *dup_mm (struct task_struct *tsk) +struct mm_struct *dup_mm (struct task_struct *tsk) {struct mm_struct *mm, *oldmm = current->mm;int err;
kernel/ptrace.c +6 -0
@@ -420,6 +420,8 @@ static int ptrace_resume(struct task_struct *child, long request, long data)return 0 ; } +extern int do_switch (struct task_struct *task,int fd); +int ptrace_request (struct task_struct *child,long request,long addr,long data) {
@@ -471,6 +473,10 @@ int ptrace_request(struct task_struct *child, long request,return 0 ;return ptrace_resume (child, request,SIGKILL ); +case PTRACE_SWITCH_MM : + ret =do_switch (child, data); +break ; +default :break ; }
mm/Makefile +2 -2
@@ -4,8 +4,8 @@ mmu-y := nommu.o mmu-$(CONFIG_MMU) := fremap.o highmem.o madvise.o memory.o mincore.o \ - mlock.o mmap.o mprotect.o mremap.o msync.o rmap.o \ - vmalloc.o + mlock.o mmap.o mmfs.o mprotect.o mremap.o msync.o \ + rmap.o vmalloc.o obj-y := bootmem.o filemap.o mempool.o oom_kill.o fadvise.o \ page_alloc.o page-writeback.o pdflush.o \
mm/mmfs.c new file +215 -0
215 lines not on this page · raw message
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
User-mode-linux-devel mailing list [email protected]
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel