Commit 0fc3a8cd authored by Jeff Dike's avatar Jeff Dike

Small fixes to sync up the 2.4 and 2.5 pools.

Also fixed a stupid signal handling bug.
parent 64d40969
......@@ -187,7 +187,7 @@ void register_winch(int fd, void *device_data)
if(!isatty(fd)) return;
pid = tcgetpgrp(fd);
pid = tcgetpgrp(fd);
if(!CHOOSE_MODE(is_tracer_winch(pid, fd, device_data), 0) &&
(pid == -1)){
thread = winch_tramp(fd, device_data, &thread_fd);
......
......@@ -73,7 +73,6 @@ extern void setup_hostinfo(void);
extern void add_arg(char *cmd_line, char *arg);
extern void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int));
extern void init_new_thread_signals(int altstack);
extern void attach_process(int pid);
extern void do_exec(int old_pid, int new_pid);
extern void tracer_panic(char *msg, ...);
extern char *get_umid(int only_if_set);
......
......@@ -29,11 +29,11 @@ static int copy_restorer(void (*restorer)(void), unsigned long start,
static int copy_sc_to_user(void *to, struct pt_regs *from)
{
return(CHOOSE_MODE(copy_sc_to_user_tt(to, from->regs.mode.tt,
&signal_frame_sc_sr.arch),
copy_sc_to_user_skas(to, &from->regs,
current->thread.cr2,
current->thread.err)));
return(CHOOSE_MODE(copy_sc_to_user_tt(to, from->regs.mode.tt,
&signal_frame_sc_sr.arch),
copy_sc_to_user_skas(to, &from->regs,
current->thread.cr2,
current->thread.err)));
}
int setup_signal_stack_si(unsigned long stack_top, int sig,
......
......@@ -39,6 +39,7 @@
#include "mode.h"
#ifdef CONFIG_MODE_SKAS
#include "skas_ptrace.h"
#include "skas.h"
#endif
void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int))
......@@ -130,12 +131,6 @@ int start_fork_tramp(void *thread_arg, unsigned long temp_stack,
return(arg.pid);
}
void trace_myself(void)
{
if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0)
panic("ptrace failed in trace_myself");
}
void suspend_new_thread(int fd)
{
char c;
......@@ -227,19 +222,19 @@ void __init check_ptrace(void)
break;
}
}
stop_ptraced_child(pid, stack, 0);
stop_ptraced_child(pid, stack, 0);
printk("OK\n");
}
int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr)
{
jmp_buf buf;
int n;
int n;
*jmp_ptr = &buf;
n = setjmp(buf);
if(n != 0)
return(n);
n = setjmp(buf);
if(n != 0)
return(n);
(*fn)(arg);
return(0);
}
......@@ -254,31 +249,6 @@ void forward_pending_sigio(int target)
kill(target, SIGIO);
}
#ifdef CONFIG_MODE_SKAS
static void init_registers(int pid)
{
int err;
if(ptrace(PTRACE_GETREGS, pid, 0, exec_regs) < 0)
panic("check_ptrace : PTRACE_GETREGS failed, errno = %d",
errno);
err = ptrace(PTRACE_GETFPXREGS, pid, 0, exec_fpx_regs);
if(!err)
return;
have_fpx_regs = 0;
if(errno != EIO)
panic("check_ptrace : PTRACE_GETFPXREGS failed, errno = %d",
errno);
err = ptrace(PTRACE_GETFPREGS, pid, 0, exec_fp_regs);
if(err)
panic("check_ptrace : PTRACE_GETFPREGS failed, errno = %d",
errno);
}
#endif
int can_do_skas(void)
{
#ifdef CONFIG_MODE_SKAS
......@@ -311,7 +281,7 @@ int can_do_skas(void)
return(ret);
#else
return(0);
#endif
#endif
}
/*
......
......@@ -33,6 +33,7 @@ extern int new_mm(int from);
extern void save_registers(struct uml_pt_regs *regs);
extern void restore_registers(struct uml_pt_regs *regs);
extern void start_userspace(void);
extern void init_registers(int pid);
#endif
......
......@@ -351,6 +351,29 @@ void kill_off_processes_skas(void)
os_kill_process(userspace_pid, 1);
}
void init_registers(int pid)
{
int err;
if(ptrace(PTRACE_GETREGS, pid, 0, exec_regs) < 0)
panic("check_ptrace : PTRACE_GETREGS failed, errno = %d",
errno);
err = ptrace(PTRACE_GETFPXREGS, pid, 0, exec_fpx_regs);
if(!err)
return;
have_fpx_regs = 0;
if(errno != EIO)
panic("check_ptrace : PTRACE_GETFPXREGS failed, errno = %d",
errno);
err = ptrace(PTRACE_GETFPREGS, pid, 0, exec_fp_regs);
if(err)
panic("check_ptrace : PTRACE_GETFPREGS failed, errno = %d",
errno);
}
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically
......
......@@ -50,6 +50,8 @@ void user_signal(int sig, struct uml_pt_regs *regs)
regs->mode.skas.trap_type = 0;
info = &sig_info[sig];
(*info->handler)(sig, regs);
unblock_signals();
}
/*
......
......@@ -18,8 +18,8 @@ struct {
int record_syscall_start(int syscall)
{
int max, index;
int max, index;
max = sizeof(syscall_record)/sizeof(syscall_record[0]);
index = next_syscall_index(max);
......@@ -32,8 +32,8 @@ int record_syscall_start(int syscall)
void record_syscall_end(int index, int result)
{
syscall_record[index].result = result;
gettimeofday(&syscall_record[index].end, NULL);
syscall_record[index].result = result;
gettimeofday(&syscall_record[index].end, NULL);
}
/*
......
......@@ -74,7 +74,7 @@ void usr2_handler(int sig, struct uml_pt_regs *regs)
{
CHOOSE_MODE(syscall_handler_tt(sig, regs), (void) 0);
}
struct signal_info sig_info[] = {
[ SIGTRAP ] { handler : relay_signal,
is_irq : 0 },
......@@ -119,11 +119,11 @@ void alarm_handler(int sig, struct sigcontext sc)
switch_timers(1);
}
void do_longjmp(void *p, int val)
void do_longjmp(void *b, int val)
{
jmp_buf *jbuf = (jmp_buf *) p;
jmp_buf *buf = b;
longjmp(*jbuf, val);
longjmp(*buf, val);
}
/*
......
......@@ -117,7 +117,7 @@ struct gdb_data {
static void config_gdb_cb(void *arg)
{
struct gdb_data *data = arg;
struct task_struct *task;
void *task;
int pid;
data->err = -1;
......@@ -228,19 +228,19 @@ int debugger_signal(int status, pid_t pid){ return(0); }
void child_signal(pid_t pid, int status){ }
int init_ptrace_proxy(int idle_pid, int startup, int stop)
{
printk(KERN_ERR "debug requested when CONFIG_PT_PROXY is off\n");
printk(UM_KERN_ERR "debug requested when CONFIG_PT_PROXY is off\n");
kill_child_dead(idle_pid);
exit(1);
}
void signal_usr1(int sig)
{
printk(KERN_ERR "debug requested when CONFIG_PT_PROXY is off\n");
printk(UM_KERN_ERR "debug requested when CONFIG_PT_PROXY is off\n");
}
int attach_debugger(int idle_pid, int pid, int stop)
{
printk(KERN_ERR "attach_debugger called when CONFIG_PT_PROXY "
printk(UM_KERN_ERR "attach_debugger called when CONFIG_PT_PROXY "
"is off\n");
return(-1);
}
......@@ -265,3 +265,14 @@ void debugger_parent_signal(int status, int pid)
}
#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:
*/
......@@ -3,6 +3,7 @@
* Lars Brinkhoff.
* Licensed under the GPL
*/
#ifndef __DEBUG_H
#define __DEBUG_H
......@@ -11,6 +12,8 @@ extern void child_proxy(pid_t pid, int status);
extern void init_proxy (pid_t pid, int waiting, int status);
extern int start_debugger(char *prog, int startup, int stop, int *debugger_fd);
extern void fake_child_exit(void);
extern int gdb_config(char *str);
extern int gdb_remove(char *unused);
#endif
......
......@@ -24,30 +24,11 @@
#include "init.h"
#include "tt.h"
extern void start_kernel(void);
static int start_kernel_proc(void *unused)
{
int pid;
block_signals();
pid = os_getpid();
cpu_tasks[0].pid = pid;
cpu_tasks[0].task = current;
#ifdef CONFIG_SMP
cpu_online_map = 1;
#endif
if(debug) os_stop_process(pid);
start_kernel();
return(0);
}
void *switch_to_tt(void *prev, void *next, void *last)
{
struct task_struct *from, *to;
unsigned long flags;
int vtalrm, alrm, prof, err, cpu;
int err, vtalrm, alrm, prof, cpu;
char c;
/* jailing and SMP are incompatible, so this doesn't need to be
* made per-cpu
......@@ -60,7 +41,7 @@ void *switch_to_tt(void *prev, void *next, void *last)
to->thread.prev_sched = from;
cpu = from->thread_info->cpu;
if(cpu == 0)
if(cpu == 0)
forward_interrupts(to->thread.mode.tt.extern_pid);
#ifdef CONFIG_SMP
forward_ipi(cpu_data[cpu].ipi_pipe[0], to->thread.mode.tt.extern_pid);
......@@ -130,18 +111,6 @@ void exit_thread_tt(void)
close(current->thread.mode.tt.switch_pipe[1]);
}
void reboot_tt(void)
{
current->thread.request.op = OP_REBOOT;
os_usr1_process(os_getpid());
}
void halt_tt(void)
{
current->thread.request.op = OP_HALT;
os_usr1_process(os_getpid());
}
extern void schedule_tail(struct task_struct *prev);
static void new_thread_handler(int sig)
......@@ -276,6 +245,32 @@ int copy_thread_tt(int nr, unsigned long clone_flags, unsigned long sp,
return(0);
}
void reboot_tt(void)
{
current->thread.request.op = OP_REBOOT;
os_usr1_process(os_getpid());
}
void halt_tt(void)
{
current->thread.request.op = OP_HALT;
os_usr1_process(os_getpid());
}
void kill_off_processes_tt(void)
{
struct task_struct *p;
int me;
me = os_getpid();
for_each_process(p){
if(p->thread.mode.tt.extern_pid != me)
os_kill_process(p->thread.mode.tt.extern_pid, 0);
}
if(init_task.thread.mode.tt.extern_pid != me)
os_kill_process(init_task.thread.mode.tt.extern_pid, 0);
}
void initial_thread_cb_tt(void (*proc)(void *), void *arg)
{
if(os_getpid() == tracing_pid){
......@@ -395,7 +390,6 @@ static void mprotect_kernel_mem(int w)
mprotect_kernel_vm(w);
}
/* No SMP problems since jailing and SMP are incompatible */
void unprotect_kernel_mem(void)
{
mprotect_kernel_mem(1);
......@@ -406,18 +400,23 @@ void protect_kernel_mem(void)
mprotect_kernel_mem(0);
}
void kill_off_processes_tt(void)
extern void start_kernel(void);
static int start_kernel_proc(void *unused)
{
struct task_struct *p;
int me;
int pid;
me = os_getpid();
for_each_process(p){
if(p->thread.mode.tt.extern_pid != me)
os_kill_process(p->thread.mode.tt.extern_pid, 0);
}
if(init_task.thread.mode.tt.extern_pid != me)
os_kill_process(init_task.thread.mode.tt.extern_pid, 0);
block_signals();
pid = os_getpid();
cpu_tasks[0].pid = pid;
cpu_tasks[0].task = current;
#ifdef CONFIG_SMP
cpu_online_map = 1;
#endif
if(debug) os_stop_process(pid);
start_kernel();
return(0);
}
void set_tracing(void *task, int tracing)
......@@ -435,7 +434,8 @@ int set_user_mode(void *t)
struct task_struct *task;
task = t ? t : current;
if(task->thread.mode.tt.tracing) return(1);
if(task->thread.mode.tt.tracing)
return(1);
task->thread.request.op = OP_TRACE_ON;
os_usr1_process(os_getpid());
return(0);
......@@ -451,22 +451,22 @@ void set_init_pid(int pid)
err);
}
void clear_singlestep(void *t)
{
struct task_struct *task = (struct task_struct *) t;
task->ptrace &= ~PT_DTRACE;
}
int singlestepping(void *t)
{
struct task_struct *task = (struct task_struct *) t;
struct task_struct *task = t;
if(task->thread.mode.tt.singlestep_syscall)
return(0);
return(task->ptrace & PT_DTRACE);
}
void clear_singlestep(void *t)
{
struct task_struct *task = t;
task->ptrace &= ~PT_DTRACE;
}
int start_uml_tt(void)
{
void *sp;
......
......@@ -13,4 +13,3 @@ $(USER_OBJS) : %.o: %.c
$(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
clean:
rm -f *.o core child ptproxy
......@@ -84,7 +84,8 @@ static void fix_range(struct mm_struct *mm, unsigned long start_addr,
atomic_t vmchange_seq = ATOMIC_INIT(1);
void flush_kernel_range(unsigned long start, unsigned long end, int update_seq)
static void flush_kernel_vm_range(unsigned long start, unsigned long end,
int update_seq)
{
struct mm_struct *mm;
pgd_t *pgd;
......@@ -133,7 +134,7 @@ void flush_kernel_range(unsigned long start, unsigned long end, int update_seq)
void flush_tlb_kernel_range(unsigned long start, unsigned long end)
{
flush_kernel_range(start, end, 1);
flush_kernel_vm_range(start, end, 1);
}
static void protect_vm_page(unsigned long addr, int w, int must_succeed)
......@@ -189,7 +190,7 @@ void flush_tlb_range_tt(struct vm_area_struct *vma, unsigned long start,
* either process memory or kernel vm
*/
if((start >= start_vm) && (start < end_vm))
flush_kernel_range(start, end, 1);
flush_kernel_vm_range(start, end, 1);
else fix_range(vma->vm_mm, start, end, 0);
}
......@@ -204,13 +205,13 @@ void flush_tlb_mm_tt(struct mm_struct *mm)
seq = atomic_read(&vmchange_seq);
if(current->thread.mode.tt.vm_seq == seq) return;
current->thread.mode.tt.vm_seq = seq;
flush_kernel_range(start_vm, end_vm, 0);
flush_kernel_vm_range(start_vm, end_vm, 0);
}
void force_flush_all_tt(void)
{
fix_range(current->mm, 0, STACK_TOP, 1);
flush_kernel_range(start_vm, end_vm, 0);
flush_kernel_vm_range(start_vm, end_vm, 0);
}
/*
......
......@@ -372,13 +372,14 @@ int tracer(int (*init_proc)(void *), void *sp)
if(!tracing && (debugger_pid != -1) && (sig != 0) &&
(sig != SIGALRM) && (sig != SIGVTALRM) &&
(sig != SIGSEGV) && (sig != SIGTRAP) &&
(sig != SIGUSR2) && (sig != SIGIO)){
(sig != SIGUSR2) && (sig != SIGIO) &&
(sig != SIGFPE)){
child_signal(pid, status);
continue;
}
if(tracing){
if(singlestepping(task))
if(singlestepping_tt(task))
cont_type = PTRACE_SINGLESTEP;
else cont_type = PTRACE_SYSCALL;
}
......
......@@ -135,13 +135,13 @@ int main(int argc, char **argv, char **envp)
}
#define CAN_KMALLOC() \
(kmalloc_ok && CHOOSE_MODE((getpid() != tracing_pid), 1))
(kmalloc_ok && CHOOSE_MODE((getpid() != tracing_pid), 1))
extern void *__real_malloc(int);
void *__wrap_malloc(int size)
{
if(CAN_KMALLOC()) return(um_kmalloc(size));
if(CAN_KMALLOC()) return(um_kmalloc(size));
else return(__real_malloc(size));
}
......@@ -158,7 +158,7 @@ extern void __real_free(void *);
void __wrap_free(void *ptr)
{
if(CAN_KMALLOC()) kfree(ptr);
if(CAN_KMALLOC()) kfree(ptr);
else __real_free(ptr);
}
......
......@@ -24,8 +24,8 @@ struct mm_struct;
#ifdef CONFIG_MODE_TT
struct proc_tt_mode {
int extern_pid;
int tracing;
int extern_pid;
int tracing;
int switch_pipe[2];
int singlestep_syscall;
int vm_seq;
......@@ -40,7 +40,6 @@ struct proc_skas_mode {
#endif
struct thread_struct {
int tracing;
int forking;
unsigned long kernel_stack;
int nsyscalls;
......
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