diff options
Diffstat (limited to 'linux-uml/linux-uml-2.6.7/proc_sysemu.patch')
-rw-r--r-- | linux-uml/linux-uml-2.6.7/proc_sysemu.patch | 242 |
1 files changed, 242 insertions, 0 deletions
diff --git a/linux-uml/linux-uml-2.6.7/proc_sysemu.patch b/linux-uml/linux-uml-2.6.7/proc_sysemu.patch index e69de29bb2..4f17341421 100644 --- a/linux-uml/linux-uml-2.6.7/proc_sysemu.patch +++ b/linux-uml/linux-uml-2.6.7/proc_sysemu.patch @@ -0,0 +1,242 @@ + +Adds /proc/sysemu to toggle SYSEMU usage. + +Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade_spam@yahoo.it> +--- + + uml-linux-2.6.7-paolo/arch/um/kernel/process.c | 4 + uml-linux-2.6.7-paolo/arch/um/kernel/skas/include/ptrace-skas.h | 4 + uml-linux-2.6.7-paolo/arch/um/kernel/skas/process.c | 62 ++++------ + uml-linux-2.6.7-paolo/arch/um/kernel/skas/process_kern.c | 59 +++++++++ + 4 files changed, 93 insertions(+), 36 deletions(-) + +diff -puN arch/um/kernel/process.c~proc_sysemu arch/um/kernel/process.c +--- uml-linux-2.6.7/arch/um/kernel/process.c~proc_sysemu 2004-06-29 21:03:04.416965888 +0200 ++++ uml-linux-2.6.7-paolo/arch/um/kernel/process.c 2004-06-29 21:03:04.422964976 +0200 +@@ -246,7 +246,7 @@ void __init check_ptrace(void) + printk("OK\n"); + + printk("Checking syscall emulation patch for ptrace..."); +- use_sysemu = 0; ++ set_using_sysemu(0); + pid = start_ptraced_child(&stack); + if(ptrace(PTRACE_SYSEMU, pid, 0, 0) >= 0) { + struct user_regs_struct regs; +@@ -269,7 +269,7 @@ void __init check_ptrace(void) + + if (!force_sysemu_disabled) { + printk("found\n"); +- use_sysemu = 1; ++ set_using_sysemu(1); + } else { + printk("found but disabled\n"); + } +diff -puN arch/um/kernel/skas/include/ptrace-skas.h~proc_sysemu arch/um/kernel/skas/include/ptrace-skas.h +--- uml-linux-2.6.7/arch/um/kernel/skas/include/ptrace-skas.h~proc_sysemu 2004-06-29 21:03:04.417965736 +0200 ++++ uml-linux-2.6.7-paolo/arch/um/kernel/skas/include/ptrace-skas.h 2004-06-29 21:03:04.422964976 +0200 +@@ -15,7 +15,9 @@ + #ifndef PTRACE_SYSEMU + #define PTRACE_SYSEMU 31 + #endif +-extern int use_sysemu; ++ ++void set_using_sysemu(int value); ++int get_using_sysemu(void); + + #include "skas_ptregs.h" + +diff -puN arch/um/kernel/skas/process.c~proc_sysemu arch/um/kernel/skas/process.c +--- uml-linux-2.6.7/arch/um/kernel/skas/process.c~proc_sysemu 2004-06-29 21:03:04.418965584 +0200 ++++ uml-linux-2.6.7-paolo/arch/um/kernel/skas/process.c 2004-06-29 21:03:04.423964824 +0200 +@@ -28,10 +28,6 @@ + #include "chan_user.h" + #include "signal_user.h" + +-#ifdef PTRACE_SYSEMU +-int use_sysemu = 0; +-#endif +- + int is_skas_winch(int pid, int fd, void *data) + { + if(pid != getpid()) +@@ -61,7 +57,8 @@ static void handle_segv(int pid) + segv(fault.addr, 0, FAULT_WRITE(fault.is_write), 1, NULL); + } + +-static void handle_trap(int pid, union uml_pt_regs *regs) ++/*To use the same value of using_sysemu as the caller, ask it that value (in local_using_sysemu)*/ ++static void handle_trap(int pid, union uml_pt_regs *regs, int local_using_sysemu) + { + int err, syscall_nr, status; + +@@ -72,27 +69,23 @@ static void handle_trap(int pid, union u + return; + } + +-#ifdef PTRACE_SYSEMU +- if (!use_sysemu) ++ if (!local_using_sysemu) + { +-#endif +- err = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, __NR_getpid); +- if(err < 0) +- panic("handle_trap - nullifying syscall failed errno = %d\n", +- errno); ++ err = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, __NR_getpid); ++ if(err < 0) ++ panic("handle_trap - nullifying syscall failed errno = %d\n", ++ errno); ++ ++ err = ptrace(PTRACE_SYSCALL, pid, 0, 0); ++ if(err < 0) ++ panic("handle_trap - continuing to end of syscall failed, " ++ "errno = %d\n", errno); + +- err = ptrace(PTRACE_SYSCALL, pid, 0, 0); +- if(err < 0) +- panic("handle_trap - continuing to end of syscall failed, " +- "errno = %d\n", errno); +- +- err = waitpid(pid, &status, WUNTRACED); +- if((err < 0) || !WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP)) +- panic("handle_trap - failed to wait at end of syscall, " +- "errno = %d, status = %d\n", errno, status); +-#ifdef PTRACE_SYSEMU ++ err = waitpid(pid, &status, WUNTRACED); ++ if((err < 0) || !WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP)) ++ panic("handle_trap - failed to wait at end of syscall, " ++ "errno = %d, status = %d\n", errno, status); + } +-#endif + + handle_syscall(regs); + } +@@ -147,15 +140,16 @@ void start_userspace(int cpu) + void userspace(union uml_pt_regs *regs) + { + int err, status, op, pid = userspace_pid[0]; ++ int local_using_sysemu; /*To prevent races if using_sysemu changes under us.*/ + + restore_registers(regs); + +-#ifdef PTRACE_SYSEMU +- if (use_sysemu) ++ local_using_sysemu = get_using_sysemu(); ++ ++ if (local_using_sysemu) + err = ptrace(PTRACE_SYSEMU, pid, 0, 0); + else +-#endif +- err = ptrace(PTRACE_SYSCALL, pid, 0, 0); ++ err = ptrace(PTRACE_SYSCALL, pid, 0, 0); + if(err) + panic("userspace - PTRACE_SYSCALL failed, errno = %d\n", + errno); +@@ -174,7 +168,7 @@ void userspace(union uml_pt_regs *regs) + handle_segv(pid); + break; + case SIGTRAP: +- handle_trap(pid, regs); ++ handle_trap(pid, regs, local_using_sysemu); + break; + case SIGIO: + case SIGVTALRM: +@@ -193,14 +187,16 @@ void userspace(union uml_pt_regs *regs) + + restore_registers(regs); + +-#ifdef PTRACE_SYSEMU +- if (use_sysemu) ++ /*Now we ended the syscall, so re-read local_using_sysemu.*/ ++ local_using_sysemu = get_using_sysemu(); ++ ++ if (local_using_sysemu) + op = singlestepping_skas() ? PTRACE_SINGLESTEP : + PTRACE_SYSEMU; + else +-#endif +- op = singlestepping_skas() ? PTRACE_SINGLESTEP : +- PTRACE_SYSCALL; ++ op = singlestepping_skas() ? PTRACE_SINGLESTEP : ++ PTRACE_SYSCALL; ++ + err = ptrace(op, pid, 0, 0); + if(err) + panic("userspace - PTRACE_SYSCALL failed, " +diff -puN arch/um/kernel/skas/process_kern.c~proc_sysemu arch/um/kernel/skas/process_kern.c +--- uml-linux-2.6.7/arch/um/kernel/skas/process_kern.c~proc_sysemu 2004-06-29 21:03:04.419965432 +0200 ++++ uml-linux-2.6.7-paolo/arch/um/kernel/skas/process_kern.c 2004-06-29 21:03:04.423964824 +0200 +@@ -6,6 +6,12 @@ + #include "linux/sched.h" + #include "linux/slab.h" + #include "linux/ptrace.h" ++#include "linux/proc_fs.h" ++#include "linux/file.h" ++#include "linux/errno.h" ++#include "linux/init.h" ++#include "asm/uaccess.h" ++#include "asm/atomic.h" + #include "kern_util.h" + #include "time_user.h" + #include "signal_user.h" +@@ -17,6 +23,59 @@ + #include "kern.h" + #include "mode.h" + ++#ifdef PTRACE_SYSEMU ++static atomic_t using_sysemu; ++#endif ++ ++void set_using_sysemu(int value) ++{ ++ atomic_set(&using_sysemu, value); ++} ++ ++int get_using_sysemu(void) ++{ ++ return atomic_read(&using_sysemu); ++} ++ ++int proc_read_sysemu(char *buf, char **start, off_t offset, int size,int *eof, void *data) ++{ ++ if (snprintf(buf, size, "%d\n", get_using_sysemu()) < size) /*No overflow*/ ++ *eof = 1; ++ ++ return strlen(buf); ++} ++ ++int proc_write_sysemu(struct file *file,const char *buf, unsigned long count,void *data) ++{ ++ char tmp[2]; ++ ++ if (copy_from_user(tmp, buf, 1)) ++ return -EFAULT; ++ ++ if (tmp[0] == '0' || tmp[0] == '1') ++ set_using_sysemu(tmp[0] - '0'); ++ return count; /*We use the first char, but pretend to write everything*/ ++} ++ ++int __init make_proc_sysemu(void) ++{ ++ struct proc_dir_entry *ent; ++ ++ ent = create_proc_entry("sysemu", 00600, &proc_root); ++ ent->read_proc = proc_read_sysemu; ++ ent->write_proc = proc_write_sysemu; ++ ++ if (ent == NULL) ++ { ++ printk("Failed to register /proc/sysemu\n"); ++ return(0); ++ } ++ ++ return 0; ++} ++ ++late_initcall(make_proc_sysemu); ++ + int singlestepping_skas(void) + { + int ret = current->ptrace & PT_DTRACE; +_ |