summaryrefslogtreecommitdiff
path: root/linux-uml/linux-uml-2.6.7/proc_sysemu.patch
diff options
context:
space:
mode:
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.patch242
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;
+_