Commit 863468e5 authored by Jeff Dike's avatar Jeff Dike

Merged a number of small skas changes.

parent c86507d1
...@@ -44,7 +44,6 @@ extern void generic_free(void *data); ...@@ -44,7 +44,6 @@ extern void generic_free(void *data);
extern void register_winch(int fd, void *device_data); extern void register_winch(int fd, void *device_data);
extern void register_winch_irq(int fd, int tty_fd, int pid, void *line); extern void register_winch_irq(int fd, int tty_fd, int pid, void *line);
extern void setup_tracer_winch(void);
#define __channel_help(fn, prefix) \ #define __channel_help(fn, prefix) \
__uml_help(fn, prefix "[0-9]*=<channel description>\n" \ __uml_help(fn, prefix "[0-9]*=<channel description>\n" \
......
...@@ -25,7 +25,6 @@ extern void *sbrk(int increment); ...@@ -25,7 +25,6 @@ extern void *sbrk(int increment);
extern void *malloc(int size); extern void *malloc(int size);
extern void perror(char *err); extern void perror(char *err);
extern int kill(int pid, int sig); extern int kill(int pid, int sig);
extern int getpid(void);
extern int getuid(void); extern int getuid(void);
extern int pause(void); extern int pause(void);
extern int write(int, const void *, int); extern int write(int, const void *, int);
...@@ -34,6 +33,7 @@ extern int close(int); ...@@ -34,6 +33,7 @@ extern int close(int);
extern int read(unsigned int, char *, int); extern int read(unsigned int, char *, int);
extern int pipe(int *); extern int pipe(int *);
extern int sched_yield(void); extern int sched_yield(void);
extern int ptrace(int op, int pid, long addr, long data);
#endif #endif
/* /*
......
...@@ -13,6 +13,7 @@ struct vm_reserved { ...@@ -13,6 +13,7 @@ struct vm_reserved {
}; };
extern void set_usable_vm(unsigned long start, unsigned long end); extern void set_usable_vm(unsigned long start, unsigned long end);
extern void set_kmem_end(unsigned long new);
#endif #endif
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
extern void timer(void); extern void timer(void);
extern void switch_timers(int to_real); extern void switch_timers(int to_real);
extern void user_time_init(void); extern void set_interval(int timer_type);
extern void idle_sleep(int secs); extern void idle_sleep(int secs);
extern void enable_timer(void); extern void enable_timer(void);
extern void time_lock(void); extern void time_lock(void);
......
...@@ -414,28 +414,8 @@ __uml_setup("mem=", uml_mem_setup, ...@@ -414,28 +414,8 @@ __uml_setup("mem=", uml_mem_setup,
struct page *arch_validate(struct page *page, int mask, int order) struct page *arch_validate(struct page *page, int mask, int order)
{ {
unsigned long addr, zero = 0; return(CHOOSE_MODE_PROC(arch_validate_tt, arch_validate_skas, page,
int i; mask, order));
again:
if(page == NULL) return(page);
if(PageHighMem(page)) return(page);
addr = (unsigned long) page_address(page);
for(i = 0; i < (1 << order); i++){
current->thread.fault_addr = (void *) addr;
if(__do_copy_to_user((void *) addr, &zero,
sizeof(zero),
&current->thread.fault_addr,
&current->thread.fault_catcher)){
if(!(mask & __GFP_WAIT)) return(NULL);
else break;
}
addr += PAGE_SIZE;
}
if(i == (1 << order)) return(page);
page = alloc_pages(mask, order);
goto again;
} }
DECLARE_MUTEX(vm_reserved_sem); DECLARE_MUTEX(vm_reserved_sem);
......
...@@ -71,7 +71,7 @@ int external_pid(void *t) ...@@ -71,7 +71,7 @@ int external_pid(void *t)
{ {
struct task_struct *task = t ? t : current; struct task_struct *task = t ? t : current;
return(task->thread.mode.tt.extern_pid); return(CHOOSE_MODE_PROC(external_pid_tt, external_pid_skas, task));
} }
int pid_to_processor_id(int pid) int pid_to_processor_id(int pid)
...@@ -310,6 +310,7 @@ int user_context(unsigned long sp) ...@@ -310,6 +310,7 @@ int user_context(unsigned long sp)
} }
extern void remove_umid_dir(void); extern void remove_umid_dir(void);
__uml_exitcall(remove_umid_dir); __uml_exitcall(remove_umid_dir);
extern exitcall_t __uml_exitcall_begin, __uml_exitcall_end; extern exitcall_t __uml_exitcall_begin, __uml_exitcall_end;
...@@ -353,11 +354,6 @@ int clear_user_proc(void *buf, int size) ...@@ -353,11 +354,6 @@ int clear_user_proc(void *buf, int size)
return(clear_user(buf, size)); return(clear_user(buf, size));
} }
void set_thread_sc(void *sc)
{
current->thread.regs.regs.mode.tt = sc;
}
int smp_sigio_handler(void) int smp_sigio_handler(void)
{ {
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "linux/smp_lock.h" #include "linux/smp_lock.h"
#include "linux/security.h" #include "linux/security.h"
#include "linux/ptrace.h" #include "linux/ptrace.h"
#include "linux/proc_mm.h"
#include "asm/ptrace.h" #include "asm/ptrace.h"
#include "asm/uaccess.h" #include "asm/uaccess.h"
#include "kern_util.h" #include "kern_util.h"
...@@ -21,6 +22,11 @@ void ptrace_disable(struct task_struct *child) ...@@ -21,6 +22,11 @@ void ptrace_disable(struct task_struct *child)
{ {
} }
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) int sys_ptrace(long request, long pid, long addr, long data)
{ {
struct task_struct *child; struct task_struct *child;
...@@ -182,13 +188,13 @@ int sys_ptrace(long request, long pid, long addr, long data) ...@@ -182,13 +188,13 @@ int sys_ptrace(long request, long pid, long addr, long data)
#ifdef PTRACE_GETREGS #ifdef PTRACE_GETREGS
case PTRACE_GETREGS: { /* Get all gp regs from the child. */ case PTRACE_GETREGS: { /* Get all gp regs from the child. */
if (!access_ok(VERIFY_WRITE, (unsigned *)data, if (!access_ok(VERIFY_WRITE, (unsigned long *)data,
FRAME_SIZE_OFFSET)) { FRAME_SIZE_OFFSET)) {
ret = -EIO; ret = -EIO;
break; break;
} }
for ( i = 0; i < FRAME_SIZE_OFFSET; i += sizeof(long) ) { for ( i = 0; i < FRAME_SIZE_OFFSET; i += sizeof(long) ) {
__put_user(getreg(child, i),(unsigned long *) data); __put_user(getreg(child, i), (unsigned long *) data);
data += sizeof(long); data += sizeof(long);
} }
ret = 0; ret = 0;
...@@ -231,6 +237,57 @@ int sys_ptrace(long request, long pid, long addr, long data) ...@@ -231,6 +237,57 @@ int sys_ptrace(long request, long pid, long addr, long data)
case PTRACE_SETFPXREGS: /* Set the child FPU state. */ case PTRACE_SETFPXREGS: /* Set the child FPU state. */
ret = set_fpxregs(data, child); ret = set_fpxregs(data, child);
break; break;
#endif
case PTRACE_FAULTINFO: {
struct ptrace_faultinfo fault;
fault = ((struct ptrace_faultinfo)
{ .is_write = child->thread.err,
.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;
}
/* This one is confusing, so just punt and return -EIO for
* now
*/
ret = -EIO;
break;
}
#ifdef 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 #endif
default: default:
ret = -EIO; ret = -EIO;
......
...@@ -39,14 +39,13 @@ struct openpty_arg { ...@@ -39,14 +39,13 @@ struct openpty_arg {
int err; int err;
}; };
static int openpty_cb(void *arg) static void openpty_cb(void *arg)
{ {
struct openpty_arg *info = arg; struct openpty_arg *info = arg;
info->err = 0; info->err = 0;
if(openpty(&info->master, &info->slave, NULL, NULL, NULL)) if(openpty(&info->master, &info->slave, NULL, NULL, NULL))
info->err = errno; info->err = errno;
return(0);
} }
void __init check_one_sigio(void (*proc)(int, int)) void __init check_one_sigio(void (*proc)(int, int))
...@@ -54,13 +53,9 @@ void __init check_one_sigio(void (*proc)(int, int)) ...@@ -54,13 +53,9 @@ void __init check_one_sigio(void (*proc)(int, int))
struct sigaction old, new; struct sigaction old, new;
struct termios tt; struct termios tt;
struct openpty_arg pty = { master : -1, slave : -1 }; struct openpty_arg pty = { master : -1, slave : -1 };
int master, slave, flags, err; int master, slave, flags;
err = run_helper_thread(openpty_cb, &pty, CLONE_FILES, NULL, 2); initial_thread_cb(openpty_cb, &pty);
if(err < 0){
printk("run_helper_thread failed, errno = %d\n", -err);
return;
}
if(pty.err){ if(pty.err){
printk("openpty failed, errno = %d\n", pty.err); printk("openpty failed, errno = %d\n", pty.err);
return; return;
...@@ -387,7 +382,7 @@ void write_sigio_workaround(void) ...@@ -387,7 +382,7 @@ void write_sigio_workaround(void)
goto out_close2; goto out_close2;
write_sigio_pid = run_helper_thread(write_sigio_thread, NULL, write_sigio_pid = run_helper_thread(write_sigio_thread, NULL,
CLONE_FILES, &stack, 0); CLONE_FILES | CLONE_VM, &stack, 0);
if(write_sigio_pid < 0) goto out_close2; if(write_sigio_pid < 0) goto out_close2;
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
# #
obj-y = exec_kern.o exec_user.o mem_user.o mmu.o process.o process_kern.o \ obj-y = exec_kern.o exec_user.o mem_user.o mmu.o process.o process_kern.o \
syscall_user.o trap_user.o sys-$(SUBARCH)/ syscall_kern.o syscall_user.o time.o trap_user.o sys-$(SUBARCH)/
USER_OBJS = $(filter %_user.o,$(obj-y)) process.o time.o USER_OBJS = $(filter %_user.o,$(obj-y)) process.o time.o
USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file)) USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
......
/*
* Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
* Licensed under the GPL
*/
#include "linux/sys.h"
#include "asm/errno.h"
#include "asm/unistd.h"
#include "asm/ptrace.h"
#include "asm/current.h"
#include "sysdep/syscalls.h"
#include "kern_util.h"
extern syscall_handler_t *sys_call_table[];
long execute_syscall_skas(void *r)
{
struct pt_regs *regs = r;
long res;
int syscall;
current->thread.nsyscalls++;
nsyscalls++;
syscall = regs->regs.syscall;
if((syscall >= NR_syscalls) || (syscall < 0))
res = -ENOSYS;
else res = EXECUTE_SYSCALL(syscall, regs);
return(res);
}
/*
* 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:
*/
/*
* Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
* Licensed under the GPL
*/
#include <sys/signal.h>
#include <sys/time.h>
#include "time_user.h"
#include "process.h"
#include "user.h"
void user_time_init_skas(void)
{
if(signal(SIGALRM, (__sighandler_t) alarm_handler) == SIG_ERR)
panic("Couldn't set SIGALRM handler");
if(signal(SIGVTALRM, (__sighandler_t) alarm_handler) == SIG_ERR)
panic("Couldn't set SIGVTALRM handler");
set_interval(ITIMER_VIRTUAL);
}
/*
* 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:
*/
...@@ -116,7 +116,8 @@ static int idle_proc(void *cpup) ...@@ -116,7 +116,8 @@ static int idle_proc(void *cpup)
panic("CPU#%d failed to create IPI pipe, errno = %d", cpu, panic("CPU#%d failed to create IPI pipe, errno = %d", cpu,
-err); -err);
activate_ipi(cpu_data[cpu].ipi_pipe[0], current->thread.extern_pid); activate_ipi(cpu_data[cpu].ipi_pipe[0],
current->thread.mode.tt.extern_pid);
wmb(); wmb();
if (test_and_set_bit(cpu, &smp_callin_map)) { if (test_and_set_bit(cpu, &smp_callin_map)) {
...@@ -143,10 +144,12 @@ static struct task_struct *idle_thread(int cpu) ...@@ -143,10 +144,12 @@ static struct task_struct *idle_thread(int cpu)
if(IS_ERR(new_task)) panic("do_fork failed in idle_thread"); if(IS_ERR(new_task)) panic("do_fork failed in idle_thread");
cpu_tasks[cpu] = ((struct cpu_task) cpu_tasks[cpu] = ((struct cpu_task)
{ .pid = new_task->thread.extern_pid, { .pid = new_task->thread.mode.tt.extern_pid,
.task = new_task } ); .task = new_task } );
idle_threads[cpu] = new_task; idle_threads[cpu] = new_task;
write(new_task->thread.switch_pipe[1], &c, sizeof(c)); CHOOSE_MODE(write(new_task->thread.mode.tt.switch_pipe[1], &c,
sizeof(c)),
({ panic("skas mode doesn't support SMP"); }));
return(new_task); return(new_task);
} }
...@@ -162,7 +165,8 @@ void smp_prepare_cpus(unsigned int maxcpus) ...@@ -162,7 +165,8 @@ void smp_prepare_cpus(unsigned int maxcpus)
err = os_pipe(cpu_data[0].ipi_pipe, 1, 1); err = os_pipe(cpu_data[0].ipi_pipe, 1, 1);
if(err) panic("CPU#0 failed to create IPI pipe, errno = %d", -err); if(err) panic("CPU#0 failed to create IPI pipe, errno = %d", -err);
activate_ipi(cpu_data[0].ipi_pipe[0], current->thread.extern_pid); activate_ipi(cpu_data[0].ipi_pipe[0],
current->thread.mode.tt.extern_pid);
for(cpu = 1; cpu < ncpus; cpu++){ for(cpu = 1; cpu < ncpus; cpu++){
printk("Booting processor %d...\n", cpu); printk("Booting processor %d...\n", cpu);
......
...@@ -20,6 +20,11 @@ ...@@ -20,6 +20,11 @@
#include "kern_util.h" #include "kern_util.h"
#include "user_util.h" #include "user_util.h"
#include "sysdep/syscalls.h" #include "sysdep/syscalls.h"
#include "mode_kern.h"
#include "choose-mode.h"
/* Unlocked, I don't care if this is a bit off */
int nsyscalls = 0;
long um_mount(char * dev_name, char * dir_name, char * type, long um_mount(char * dev_name, char * dir_name, char * type,
unsigned long new_flags, void * data) unsigned long new_flags, void * data)
...@@ -298,122 +303,9 @@ int sys_sigaltstack(const stack_t *uss, stack_t *uoss) ...@@ -298,122 +303,9 @@ int sys_sigaltstack(const stack_t *uss, stack_t *uoss)
return(do_sigaltstack(uss, uoss, PT_REGS_SP(&current->thread.regs))); return(do_sigaltstack(uss, uoss, PT_REGS_SP(&current->thread.regs)));
} }
static inline int check_area(void *ptr, int size)
{
return(verify_area(VERIFY_WRITE, ptr, size));
}
static int check_readlink(struct pt_regs *regs)
{
return(check_area((void *) regs->regs.args[1], regs->regs.args[2]));
}
static int check_utime(struct pt_regs *regs)
{
return(check_area((void *) regs->regs.args[1],
sizeof(struct utimbuf)));
}
static int check_oldstat(struct pt_regs *regs)
{
return(check_area((void *) regs->regs.args[1],
sizeof(struct __old_kernel_stat)));
}
static int check_stat(struct pt_regs *regs)
{
return(check_area((void *) regs->regs.args[1], sizeof(struct stat)));
}
static int check_stat64(struct pt_regs *regs)
{
return(check_area((void *) regs->regs.args[1], sizeof(struct stat64)));
}
struct bogus {
int kernel_ds;
int (*check_params)(struct pt_regs *);
};
struct bogus this_is_bogus[256] = {
[ __NR_mknod ] = { 1, NULL },
[ __NR_mkdir ] = { 1, NULL },
[ __NR_rmdir ] = { 1, NULL },
[ __NR_unlink ] = { 1, NULL },
[ __NR_symlink ] = { 1, NULL },
[ __NR_link ] = { 1, NULL },
[ __NR_rename ] = { 1, NULL },
[ __NR_umount ] = { 1, NULL },
[ __NR_mount ] = { 1, NULL },
[ __NR_pivot_root ] = { 1, NULL },
[ __NR_chdir ] = { 1, NULL },
[ __NR_chroot ] = { 1, NULL },
[ __NR_open ] = { 1, NULL },
[ __NR_quotactl ] = { 1, NULL },
[ __NR_sysfs ] = { 1, NULL },
[ __NR_readlink ] = { 1, check_readlink },
[ __NR_acct ] = { 1, NULL },
[ __NR_execve ] = { 1, NULL },
[ __NR_uselib ] = { 1, NULL },
[ __NR_statfs ] = { 1, NULL },
[ __NR_truncate ] = { 1, NULL },
[ __NR_access ] = { 1, NULL },
[ __NR_chmod ] = { 1, NULL },
[ __NR_chown ] = { 1, NULL },
[ __NR_lchown ] = { 1, NULL },
[ __NR_utime ] = { 1, check_utime },
[ __NR_oldlstat ] = { 1, check_oldstat },
[ __NR_oldstat ] = { 1, check_oldstat },
[ __NR_stat ] = { 1, check_stat },
[ __NR_lstat ] = { 1, check_stat },
[ __NR_stat64 ] = { 1, check_stat64 },
[ __NR_lstat64 ] = { 1, check_stat64 },
[ __NR_chown32 ] = { 1, NULL },
};
/* sys_utimes */
static int check_bogosity(struct pt_regs *regs)
{
struct bogus *bogon = &this_is_bogus[regs->regs.syscall];
if(!bogon->kernel_ds) return(0);
if(bogon->check_params && (*bogon->check_params)(regs))
return(-EFAULT);
set_fs(KERNEL_DS);
return(0);
}
/* Unlocked, I don't care if this is a bit off */
int nsyscalls = 0;
extern syscall_handler_t *sys_call_table[];
long execute_syscall(void *r) long execute_syscall(void *r)
{ {
struct pt_regs *regs = r; return(CHOOSE_MODE_PROC(execute_syscall_tt, execute_syscall_skas, r));
long res;
int syscall;
current->thread.nsyscalls++;
nsyscalls++;
syscall = regs->regs.syscall;
if((syscall >= NR_syscalls) || (syscall < 0))
res = -ENOSYS;
else if(honeypot && check_bogosity(regs))
res = -EFAULT;
else res = EXECUTE_SYSCALL(syscall, regs);
set_fs(USER_DS);
if(current->thread.mode.tt.singlestep_syscall){
current->thread.mode.tt.singlestep_syscall = 0;
current->ptrace &= ~PT_DTRACE;
force_sig(SIGTRAP, current);
}
return(res);
} }
spinlock_t syscall_lock = SPIN_LOCK_UNLOCKED; spinlock_t syscall_lock = SPIN_LOCK_UNLOCKED;
......
...@@ -23,22 +23,21 @@ void timer(void) ...@@ -23,22 +23,21 @@ void timer(void)
gettimeofday(&xtime, NULL); gettimeofday(&xtime, NULL);
} }
static void set_interval(int timer_type) void set_interval(int timer_type)
{ {
struct itimerval interval; int usec = 1000000/hz();
struct itimerval interval = ((struct itimerval) { { 0, usec },
{ 0, usec } });
interval.it_interval.tv_sec = 0;
interval.it_interval.tv_usec = 1000000/hz();
interval.it_value.tv_sec = 0;
interval.it_value.tv_usec = 1000000/hz();
if(setitimer(timer_type, &interval, NULL) == -1) if(setitimer(timer_type, &interval, NULL) == -1)
panic("setitimer failed - errno = %d\n", errno); panic("setitimer failed - errno = %d\n", errno);
} }
void enable_timer(void) void enable_timer(void)
{ {
struct itimerval enable = ((struct itimerval) { { 0, 1000000/hz() }, int usec = 1000000/hz();
{ 0, 1000000/hz() }}); struct itimerval enable = ((struct itimerval) { { 0, usec },
{ 0, usec }});
if(setitimer(ITIMER_VIRTUAL, &enable, NULL)) if(setitimer(ITIMER_VIRTUAL, &enable, NULL))
printk("enable_timer - setitimer failed, errno = %d\n", printk("enable_timer - setitimer failed, errno = %d\n",
errno); errno);
...@@ -76,13 +75,6 @@ void idle_timer(void) ...@@ -76,13 +75,6 @@ void idle_timer(void)
set_interval(ITIMER_REAL); set_interval(ITIMER_REAL);
} }
void user_time_init(void)
{
if(signal(SIGVTALRM, (__sighandler_t) alarm_handler) == SIG_ERR)
panic("Couldn't set SIGVTALRM handler");
set_interval(ITIMER_VIRTUAL);
}
void time_init(void) void time_init(void)
{ {
if(signal(SIGVTALRM, boot_timer_handler) == SIG_ERR) if(signal(SIGVTALRM, boot_timer_handler) == SIG_ERR)
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "kern_util.h" #include "kern_util.h"
#include "user_util.h" #include "user_util.h"
#include "time_user.h" #include "time_user.h"
#include "mode.h"
u64 jiffies_64; u64 jiffies_64;
...@@ -142,7 +143,7 @@ int __init timer_init(void) ...@@ -142,7 +143,7 @@ int __init timer_init(void)
{ {
int err; int err;
user_time_init(); CHOOSE_MODE(user_time_init_tt(), user_time_init_skas());
if((err = request_irq(TIMER_IRQ, um_timer, SA_INTERRUPT, "timer", if((err = request_irq(TIMER_IRQ, um_timer, SA_INTERRUPT, "timer",
NULL)) != 0) NULL)) != 0)
printk(KERN_ERR "timer_init : request_irq failed - " printk(KERN_ERR "timer_init : request_irq failed - "
......
...@@ -96,57 +96,24 @@ struct signal_info sig_info[] = { ...@@ -96,57 +96,24 @@ struct signal_info sig_info[] = {
is_irq : 0 }, is_irq : 0 },
}; };
void sig_handler_common(int sig, struct sigcontext *sc)
{
struct uml_pt_regs save_regs, *r;
struct signal_info *info;
int save_errno = errno, is_user;
unprotect_kernel_mem();
r = (struct uml_pt_regs *) TASK_REGS(get_current());
save_regs = *r;
is_user = user_context(SC_SP(sc));
r->is_user = is_user;
r->mode.tt = sc;
if(sig != SIGUSR2) r->syscall = -1;
change_sig(SIGUSR1, 1);
info = &sig_info[sig];
if(!info->is_irq) unblock_signals();
(*info->handler)(sig, r);
if(is_user){
interrupt_end();
block_signals();
change_sig(SIGUSR1, 0);
set_user_mode(NULL);
}
*r = save_regs;
errno = save_errno;
if(is_user) protect_kernel_mem();
}
void sig_handler(int sig, struct sigcontext sc) void sig_handler(int sig, struct sigcontext sc)
{ {
sig_handler_common(sig, &sc); CHOOSE_MODE_PROC(sig_handler_common_tt, sig_handler_common_skas,
sig, &sc);
} }
extern int timer_irq_inited, missed_ticks[]; extern int timer_irq_inited, missed_ticks[];
void alarm_handler(int sig, struct sigcontext sc) void alarm_handler(int sig, struct sigcontext sc)
{ {
int user;
if(!timer_irq_inited) return; if(!timer_irq_inited) return;
missed_ticks[cpu()]++; missed_ticks[cpu()]++;
user = user_context(SC_SP(&sc));
if(sig == SIGALRM) if(sig == SIGALRM)
switch_timers(0); switch_timers(0);
sig_handler_common(sig, &sc); CHOOSE_MODE_PROC(sig_handler_common_tt, sig_handler_common_skas,
sig, &sc);
if(sig == SIGALRM) if(sig == SIGALRM)
switch_timers(1); switch_timers(1);
......
...@@ -3,12 +3,15 @@ ...@@ -3,12 +3,15 @@
# Licensed under the GPL # Licensed under the GPL
# #
obj-y = exec_kern.o exec_user.o gdb.o gdb_kern.o mem.o process_kern.o \ obj-y = exec_kern.o exec_user.o gdb.o gdb_kern.o ksyms.o mem.o process_kern.o \
syscall_user.o tracer.o uaccess_user.o sys-$(SUBARCH)/ syscall_kern.o syscall_user.o time.o tracer.o trap_user.o \
uaccess_user.o sys-$(SUBARCH)/
obj-$(CONFIG_PT_PROXY) += ptproxy/ obj-$(CONFIG_PT_PROXY) += ptproxy/
USER_OBJS := $(filter %_user.o,$(obj-y)) gdb.o tracer.o export-objs = ksyms.o
USER_OBJS := $(filter %_user.o,$(obj-y)) gdb.o time.o tracer.o
USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file)) USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
include $(TOPDIR)/Rules.make include $(TOPDIR)/Rules.make
......
/*
* Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
* Licensed under the GPL
*/
#include "linux/module.h"
#include "asm/uaccess.h"
#include "mode.h"
EXPORT_SYMBOL(__do_copy_from_user);
EXPORT_SYMBOL(__do_copy_to_user);
EXPORT_SYMBOL(__do_strncpy_from_user);
EXPORT_SYMBOL(__do_strnlen_user);
EXPORT_SYMBOL(__do_clear_user);
EXPORT_SYMBOL(tracing_pid);
EXPORT_SYMBOL(honeypot);
/*
* 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:
*/
/*
* Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
* Licensed under the GPL
*/
#include "linux/types.h"
#include "linux/utime.h"
#include "linux/sys.h"
#include "asm/unistd.h"
#include "asm/ptrace.h"
#include "asm/uaccess.h"
#include "sysdep/syscalls.h"
#include "kern_util.h"
static inline int check_area(void *ptr, int size)
{
return(verify_area(VERIFY_WRITE, ptr, size));
}
static int check_readlink(struct pt_regs *regs)
{
return(check_area((void *) regs->regs.args[1], regs->regs.args[2]));
}
static int check_utime(struct pt_regs *regs)
{
return(check_area((void *) regs->regs.args[1],
sizeof(struct utimbuf)));
}
static int check_oldstat(struct pt_regs *regs)
{
return(check_area((void *) regs->regs.args[1],
sizeof(struct __old_kernel_stat)));
}
static int check_stat(struct pt_regs *regs)
{
return(check_area((void *) regs->regs.args[1], sizeof(struct stat)));
}
static int check_stat64(struct pt_regs *regs)
{
return(check_area((void *) regs->regs.args[1], sizeof(struct stat64)));
}
struct bogus {
int kernel_ds;
int (*check_params)(struct pt_regs *);
};
struct bogus this_is_bogus[256] = {
[ __NR_mknod ] = { 1, NULL },
[ __NR_mkdir ] = { 1, NULL },
[ __NR_rmdir ] = { 1, NULL },
[ __NR_unlink ] = { 1, NULL },
[ __NR_symlink ] = { 1, NULL },
[ __NR_link ] = { 1, NULL },
[ __NR_rename ] = { 1, NULL },
[ __NR_umount ] = { 1, NULL },
[ __NR_mount ] = { 1, NULL },
[ __NR_pivot_root ] = { 1, NULL },
[ __NR_chdir ] = { 1, NULL },
[ __NR_chroot ] = { 1, NULL },
[ __NR_open ] = { 1, NULL },
[ __NR_quotactl ] = { 1, NULL },
[ __NR_sysfs ] = { 1, NULL },
[ __NR_readlink ] = { 1, check_readlink },
[ __NR_acct ] = { 1, NULL },
[ __NR_execve ] = { 1, NULL },
[ __NR_uselib ] = { 1, NULL },
[ __NR_statfs ] = { 1, NULL },
[ __NR_truncate ] = { 1, NULL },
[ __NR_access ] = { 1, NULL },
[ __NR_chmod ] = { 1, NULL },
[ __NR_chown ] = { 1, NULL },
[ __NR_lchown ] = { 1, NULL },
[ __NR_utime ] = { 1, check_utime },
[ __NR_oldlstat ] = { 1, check_oldstat },
[ __NR_oldstat ] = { 1, check_oldstat },
[ __NR_stat ] = { 1, check_stat },
[ __NR_lstat ] = { 1, check_stat },
[ __NR_stat64 ] = { 1, check_stat64 },
[ __NR_lstat64 ] = { 1, check_stat64 },
[ __NR_chown32 ] = { 1, NULL },
};
/* sys_utimes */
static int check_bogosity(struct pt_regs *regs)
{
struct bogus *bogon = &this_is_bogus[regs->regs.syscall];
if(!bogon->kernel_ds) return(0);
if(bogon->check_params && (*bogon->check_params)(regs))
return(-EFAULT);
set_fs(KERNEL_DS);
return(0);
}
/* Unlocked, I don't care if this is a bit off */
int nsyscalls = 0;
extern syscall_handler_t *sys_call_table[];
long execute_syscall_tt(void *r)
{
struct pt_regs *regs = r;
long res;
int syscall;
current->thread.nsyscalls++;
nsyscalls++;
syscall = regs->regs.syscall;
if((syscall >= NR_syscalls) || (syscall < 0))
res = -ENOSYS;
else if(honeypot && check_bogosity(regs))
res = -EFAULT;
else res = EXECUTE_SYSCALL(syscall, regs);
set_fs(USER_DS);
if(current->thread.mode.tt.singlestep_syscall){
current->thread.mode.tt.singlestep_syscall = 0;
current->ptrace &= ~PT_DTRACE;
force_sig(SIGTRAP, current);
}
return(res);
}
/*
* 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:
*/
/*
* Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
* Licensed under the GPL
*/
#include <signal.h>
#include <sys/time.h>
#include <time_user.h>
#include "process.h"
#include "user.h"
void user_time_init_tt(void)
{
if(signal(SIGVTALRM, (__sighandler_t) alarm_handler) == SIG_ERR)
panic("Couldn't set SIGVTALRM handler");
set_interval(ITIMER_VIRTUAL);
}
/*
* 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:
*/
/*
* Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
* Licensed under the GPL
*/
#include <stdlib.h>
#include <errno.h>
#include <signal.h>
#include <asm/sigcontext.h>
#include "sysdep/ptrace.h"
#include "signal_user.h"
#include "user_util.h"
#include "kern_util.h"
#include "task.h"
#include "tt.h"
void sig_handler_common_tt(int sig, struct sigcontext *sc)
{
struct uml_pt_regs save_regs, *r;
struct signal_info *info;
int save_errno = errno, is_user;
unprotect_kernel_mem();
r = (struct uml_pt_regs *) TASK_REGS(get_current());
save_regs = *r;
is_user = user_context(SC_SP(sc));
r->is_user = is_user;
r->mode.tt = sc;
if(sig != SIGUSR2) r->syscall = -1;
change_sig(SIGUSR1, 1);
info = &sig_info[sig];
if(!info->is_irq) unblock_signals();
(*info->handler)(sig, r);
if(is_user){
interrupt_end();
block_signals();
change_sig(SIGUSR1, 0);
set_user_mode(NULL);
}
*r = save_regs;
errno = save_errno;
if(is_user) protect_kernel_mem();
}
/*
* 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:
*/
...@@ -17,6 +17,8 @@ ...@@ -17,6 +17,8 @@
#include "umid.h" #include "umid.h"
#include "init.h" #include "init.h"
#include "os.h" #include "os.h"
#include "user_util.h"
#include "choose-mode.h"
#define UMID_LEN 64 #define UMID_LEN 64
#define UML_DIR "~/.uml/" #define UML_DIR "~/.uml/"
...@@ -91,7 +93,7 @@ static int __init create_pid_file(void) ...@@ -91,7 +93,7 @@ static int __init create_pid_file(void)
return 0; return 0;
} }
sprintf(pid, "%d\n", (tracing_pid == -1) ? os_getpid() : tracing_pid); sprintf(pid, "%d\n", os_getpid());
if(write(fd, pid, strlen(pid)) != strlen(pid)) if(write(fd, pid, strlen(pid)) != strlen(pid))
printk("Write of pid file failed - errno = %d\n", errno); printk("Write of pid file failed - errno = %d\n", errno);
close(fd); close(fd);
...@@ -179,7 +181,7 @@ int not_dead_yet(char *dir) ...@@ -179,7 +181,7 @@ int not_dead_yet(char *dir)
dead = 1; dead = 1;
} }
if(((kill(p, 0) < 0) && (errno == ESRCH)) || if(((kill(p, 0) < 0) && (errno == ESRCH)) ||
(p == tracing_pid)) (p == CHOOSE_MODE(tracing_pid, os_getpid())))
dead = 1; dead = 1;
} }
if(!dead) return(1); if(!dead) return(1);
......
...@@ -3,15 +3,82 @@ ...@@ -3,15 +3,82 @@
* Licensed under the GPL * Licensed under the GPL
*/ */
#include "linux/config.h"
#include "linux/slab.h"
#include "asm/uaccess.h" #include "asm/uaccess.h"
#include "asm/ptrace.h"
#include "choose-mode.h"
#include "kern.h"
#ifdef CONFIG_MODE_TT
extern int modify_ldt(int func, void *ptr, unsigned long bytecount); extern int modify_ldt(int func, void *ptr, unsigned long bytecount);
int sys_modify_ldt(int func, void *ptr, unsigned long bytecount) int sys_modify_ldt_tt(int func, void *ptr, unsigned long bytecount)
{ {
if(verify_area(VERIFY_READ, ptr, bytecount)) return(-EFAULT); if(verify_area(VERIFY_READ, ptr, bytecount)) return(-EFAULT);
return(modify_ldt(func, ptr, bytecount)); return(modify_ldt(func, ptr, bytecount));
} }
#endif
#ifdef CONFIG_MODE_SKAS
extern int userspace_pid;
int sys_modify_ldt_skas(int func, void *ptr, unsigned long bytecount)
{
struct ptrace_ldt ldt;
void *buf;
int res, n;
buf = kmalloc(bytecount, GFP_KERNEL);
if(buf == NULL)
return(-ENOMEM);
res = 0;
switch(func){
case 1:
case 0x11:
res = copy_from_user(buf, ptr, bytecount);
break;
}
if(res != 0){
res = -EFAULT;
goto out;
}
ldt = ((struct ptrace_ldt) { .func = func,
.ptr = buf,
.bytecount = bytecount });
res = ptrace(PTRACE_LDT, userspace_pid, 0, (unsigned long) &ldt);
if(res < 0)
goto out;
switch(func){
case 0:
case 2:
n = res;
res = copy_to_user(ptr, buf, n);
if(res != 0)
res = -EFAULT;
else
res = n;
break;
}
out:
kfree(buf);
return(res);
}
#endif
int sys_modify_ldt(int func, void *ptr, unsigned long bytecount)
{
return(CHOOSE_MODE_PROC(sys_modify_ldt_tt, sys_modify_ldt_skas, func,
ptr, bytecount));
}
/* /*
* Overrides for Emacs so that we follow Linus's tabbing style. * Overrides for Emacs so that we follow Linus's tabbing style.
......
...@@ -169,11 +169,12 @@ static inline unsigned long twd_fxsr_to_i387( struct i387_fxsave_struct *fxsave ...@@ -169,11 +169,12 @@ static inline unsigned long twd_fxsr_to_i387( struct i387_fxsave_struct *fxsave
} }
/* /*
b * FXSR floating point environment conversions. * FXSR floating point environment conversions.
*/ */
static inline int convert_fxsr_to_user(struct _fpstate *buf, #ifdef CONFIG_MODE_TT
struct pt_regs *regs) static inline int convert_fxsr_to_user_tt(struct _fpstate *buf,
struct pt_regs *regs)
{ {
struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs)); struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs));
unsigned long env[7]; unsigned long env[7];
...@@ -200,9 +201,17 @@ static inline int convert_fxsr_to_user(struct _fpstate *buf, ...@@ -200,9 +201,17 @@ static inline int convert_fxsr_to_user(struct _fpstate *buf,
} }
return 0; return 0;
} }
#endif
static inline int convert_fxsr_from_user(struct pt_regs *regs, static inline int convert_fxsr_to_user(struct _fpstate *buf,
struct _fpstate *buf) struct pt_regs *regs)
{
return(CHOOSE_MODE(convert_fxsr_to_user_tt(buf, regs), 0));
}
#ifdef CONFIG_MODE_TT
static inline int convert_fxsr_from_user_tt(struct pt_regs *regs,
struct _fpstate *buf)
{ {
struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs)); struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs));
unsigned long env[7]; unsigned long env[7];
...@@ -230,6 +239,13 @@ static inline int convert_fxsr_from_user(struct pt_regs *regs, ...@@ -230,6 +239,13 @@ static inline int convert_fxsr_from_user(struct pt_regs *regs,
} }
return 0; return 0;
} }
#endif
static inline int convert_fxsr_from_user(struct pt_regs *regs,
struct _fpstate *buf)
{
return(CHOOSE_MODE(convert_fxsr_from_user_tt(regs, buf), 0));
}
int get_fpregs(unsigned long buf, struct task_struct *child) int get_fpregs(unsigned long buf, struct task_struct *child)
{ {
...@@ -251,7 +267,8 @@ int set_fpregs(unsigned long buf, struct task_struct *child) ...@@ -251,7 +267,8 @@ int set_fpregs(unsigned long buf, struct task_struct *child)
else return(0); else return(0);
} }
int get_fpxregs(unsigned long buf, struct task_struct *tsk) #ifdef CONFIG_MODE_TT
int get_fpxregs_tt(unsigned long buf, struct task_struct *tsk)
{ {
struct pt_regs *regs = &tsk->thread.regs; struct pt_regs *regs = &tsk->thread.regs;
struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs)); struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs));
...@@ -262,8 +279,15 @@ int get_fpxregs(unsigned long buf, struct task_struct *tsk) ...@@ -262,8 +279,15 @@ int get_fpxregs(unsigned long buf, struct task_struct *tsk)
if(err) return -EFAULT; if(err) return -EFAULT;
else return 0; else return 0;
} }
#endif
int set_fpxregs(unsigned long buf, struct task_struct *tsk) int get_fpxregs(unsigned long buf, struct task_struct *tsk)
{
return(CHOOSE_MODE(get_fpxregs_tt(buf, tsk), 0));
}
#ifdef CONFIG_MODE_TT
int set_fpxregs_tt(unsigned long buf, struct task_struct *tsk)
{ {
struct pt_regs *regs = &tsk->thread.regs; struct pt_regs *regs = &tsk->thread.regs;
struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs)); struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs));
...@@ -274,6 +298,12 @@ int set_fpxregs(unsigned long buf, struct task_struct *tsk) ...@@ -274,6 +298,12 @@ int set_fpxregs(unsigned long buf, struct task_struct *tsk)
if(err) return -EFAULT; if(err) return -EFAULT;
else return 0; else return 0;
} }
#endif
int set_fpxregs(unsigned long buf, struct task_struct *tsk)
{
return(CHOOSE_MODE(set_fpxregs_tt(buf, tsk), 0));
}
#ifdef notdef #ifdef notdef
int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu) int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu)
...@@ -291,8 +321,10 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu) ...@@ -291,8 +321,10 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu)
return(1); return(1);
} }
#endif #endif
static inline void copy_fpu_fxsave(struct pt_regs *regs,
struct user_i387_struct *buf) #ifdef CONFIG_MODE_TT
static inline void copy_fpu_fxsave_tt(struct pt_regs *regs,
struct user_i387_struct *buf)
{ {
struct i387_fxsave_struct *fpu = SC_FXSR_ENV(PT_REGS_SC(regs)); struct i387_fxsave_struct *fpu = SC_FXSR_ENV(PT_REGS_SC(regs));
unsigned short *to; unsigned short *to;
...@@ -307,6 +339,13 @@ static inline void copy_fpu_fxsave(struct pt_regs *regs, ...@@ -307,6 +339,13 @@ static inline void copy_fpu_fxsave(struct pt_regs *regs,
memcpy( to, from, 5 * sizeof(unsigned short) ); memcpy( to, from, 5 * sizeof(unsigned short) );
} }
} }
#endif
static inline void copy_fpu_fxsave(struct pt_regs *regs,
struct user_i387_struct *buf)
{
(void) CHOOSE_MODE(copy_fpu_fxsave_tt(regs, buf), 0);
}
int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu ) int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu )
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment