Commit 3de7a7fa authored by Jeff Dike's avatar Jeff Dike

Merge jdike.wstearns.org:/home/jdike/linux/linus-2.5

into jdike.wstearns.org:/home/jdike/linux/fixes-2.5
parents 6a3354a9 e5102574
...@@ -99,7 +99,8 @@ static int port_accept(struct port_list *port) ...@@ -99,7 +99,8 @@ static int port_accept(struct port_list *port)
} }
list_add(&conn->list, &port->pending); list_add(&conn->list, &port->pending);
return(1); ret = 1;
goto out;
out_free: out_free:
kfree(conn); kfree(conn);
...@@ -274,8 +275,6 @@ void port_kern_free(void *d) ...@@ -274,8 +275,6 @@ void port_kern_free(void *d)
{ {
struct port_dev *dev = d; struct port_dev *dev = d;
if(dev->helper_pid != -1) os_kill_process(dev->helper_pid, 0);
if(dev->telnetd_pid != -1) os_kill_process(dev->telnetd_pid, 0);
kfree(dev); kfree(dev);
} }
......
...@@ -15,12 +15,12 @@ struct frame_common { ...@@ -15,12 +15,12 @@ struct frame_common {
int sr_index; int sr_index;
int sr_relative; int sr_relative;
int sp_index; int sp_index;
struct arch_frame_data arch;
}; };
struct sc_frame { struct sc_frame {
struct frame_common common; struct frame_common common;
int sc_index; int sc_index;
struct arch_frame_data arch;
}; };
extern struct sc_frame signal_frame_sc; extern struct sc_frame signal_frame_sc;
...@@ -31,6 +31,8 @@ struct si_frame { ...@@ -31,6 +31,8 @@ struct si_frame {
struct frame_common common; struct frame_common common;
int sip_index; int sip_index;
int si_index; int si_index;
int ucp_index;
int uc_index;
}; };
extern struct si_frame signal_frame_si; extern struct si_frame signal_frame_si;
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
enum { IRQ_READ, IRQ_WRITE }; enum { IRQ_READ, IRQ_WRITE };
extern void sigio_handler(int sig, struct uml_pt_regs *regs); extern void sigio_handler(int sig, union uml_pt_regs *regs);
extern int activate_fd(int irq, int fd, int type, void *dev_id); extern int activate_fd(int irq, int fd, int type, void *dev_id);
extern void free_irq_by_irq_and_dev(int irq, void *dev_id); extern void free_irq_by_irq_and_dev(int irq, void *dev_id);
extern void free_irq_by_fd(int fd); extern void free_irq_by_fd(int fd);
......
...@@ -47,7 +47,7 @@ extern void free_stack(unsigned long stack, int order); ...@@ -47,7 +47,7 @@ extern void free_stack(unsigned long stack, int order);
extern void add_input_request(int op, void (*proc)(int), void *arg); extern void add_input_request(int op, void (*proc)(int), void *arg);
extern int sys_execve(char *file, char **argv, char **env); extern int sys_execve(char *file, char **argv, char **env);
extern char *current_cmd(void); extern char *current_cmd(void);
extern void timer_handler(int sig, struct uml_pt_regs *regs); extern void timer_handler(int sig, union uml_pt_regs *regs);
extern int set_signals(int enable); extern int set_signals(int enable);
extern void force_sigbus(void); extern void force_sigbus(void);
extern int pid_to_processor_id(int pid); extern int pid_to_processor_id(int pid);
...@@ -64,7 +64,7 @@ extern void *syscall_sp(void *t); ...@@ -64,7 +64,7 @@ extern void *syscall_sp(void *t);
extern void syscall_trace(void); extern void syscall_trace(void);
extern int hz(void); extern int hz(void);
extern void idle_timer(void); extern void idle_timer(void);
extern unsigned int do_IRQ(int irq, struct uml_pt_regs *regs); extern unsigned int do_IRQ(int irq, union uml_pt_regs *regs);
extern int external_pid(void *t); extern int external_pid(void *t);
extern int pid_to_processor_id(int pid); extern int pid_to_processor_id(int pid);
extern void boot_timer_handler(int sig); extern void boot_timer_handler(int sig);
...@@ -77,10 +77,10 @@ extern int init_ptrace_proxy(int idle_pid, int startup, int stop); ...@@ -77,10 +77,10 @@ extern int init_ptrace_proxy(int idle_pid, int startup, int stop);
extern int init_parent_proxy(int pid); extern int init_parent_proxy(int pid);
extern int singlestepping(void *t); extern int singlestepping(void *t);
extern void check_stack_overflow(void *ptr); extern void check_stack_overflow(void *ptr);
extern void relay_signal(int sig, struct uml_pt_regs *regs); extern void relay_signal(int sig, union uml_pt_regs *regs);
extern void not_implemented(void); extern void not_implemented(void);
extern int user_context(unsigned long sp); extern int user_context(unsigned long sp);
extern void timer_irq(struct uml_pt_regs *regs); extern void timer_irq(union uml_pt_regs *regs);
extern void unprotect_stack(unsigned long stack); extern void unprotect_stack(unsigned long stack);
extern void do_uml_exitcalls(void); extern void do_uml_exitcalls(void);
extern int attach_debugger(int idle_pid, int pid, int stop); extern int attach_debugger(int idle_pid, int pid, int stop);
...@@ -101,7 +101,7 @@ extern void *get_init_task(void); ...@@ -101,7 +101,7 @@ extern void *get_init_task(void);
extern int clear_user_proc(void *buf, int size); extern int clear_user_proc(void *buf, int size);
extern int copy_to_user_proc(void *to, void *from, int size); extern int copy_to_user_proc(void *to, void *from, int size);
extern int copy_from_user_proc(void *to, void *from, int size); extern int copy_from_user_proc(void *to, void *from, int size);
extern void bus_handler(int sig, struct uml_pt_regs *regs); extern void bus_handler(int sig, union uml_pt_regs *regs);
extern long execute_syscall(void *r); extern long execute_syscall(void *r);
extern int smp_sigio_handler(void); extern int smp_sigio_handler(void);
extern void *get_current(void); extern void *get_current(void);
......
...@@ -7,7 +7,8 @@ ...@@ -7,7 +7,8 @@
#define __FRAME_I386_H #define __FRAME_I386_H
struct arch_frame_data_raw { struct arch_frame_data_raw {
unsigned long sc_end; unsigned long fp_start;
unsigned long sr;
}; };
struct arch_frame_data { struct arch_frame_data {
......
...@@ -16,6 +16,15 @@ static inline void *sp_to_sc(unsigned long sp) ...@@ -16,6 +16,15 @@ static inline void *sp_to_sc(unsigned long sp)
return((void *) sp); return((void *) sp);
} }
static inline void *sp_to_uc(unsigned long sp)
{
unsigned long uc;
uc = sp + signal_frame_si.uc_index -
signal_frame_si.common.sp_index - 4;
return((void *) uc);
}
static inline void *sp_to_rt_sc(unsigned long sp) static inline void *sp_to_rt_sc(unsigned long sp)
{ {
unsigned long sc; unsigned long sc;
...@@ -42,7 +51,7 @@ static inline void *sp_to_rt_mask(unsigned long sp) ...@@ -42,7 +51,7 @@ static inline void *sp_to_rt_mask(unsigned long sp)
mask = sp - signal_frame_si.common.sp_index + mask = sp - signal_frame_si.common.sp_index +
signal_frame_si.common.len + signal_frame_si.common.len +
sc_size(&signal_frame_sc.arch) - 4; sc_size(&signal_frame_si.common.arch) - 4;
return((void *) mask); return((void *) mask);
} }
......
...@@ -18,26 +18,35 @@ ...@@ -18,26 +18,35 @@
* setup_arch_frame uses that data to figure out what * setup_arch_frame uses that data to figure out what
* arch_frame_data.fpstate_size should be. It really has no idea, since it's * arch_frame_data.fpstate_size should be. It really has no idea, since it's
* not allowed to do sizeof(struct fpstate) but it's safe to consider that it's * not allowed to do sizeof(struct fpstate) but it's safe to consider that it's
* everything from the end of the sgcontext up to the top of the stack. So, * everything from the end of the sigcontext up to the top of the stack. So,
* it masks off the page number to get the offset within the page and subtracts * it masks off the page number to get the offset within the page and subtracts
* that from the page size, and that's how big the fpstate struct will be * that from the page size, and that's how big the fpstate struct will be
* considered to be. * considered to be.
*/ */
static inline void setup_arch_frame_raw(struct arch_frame_data_raw *data, static inline void setup_arch_frame_raw(struct arch_frame_data_raw *data,
struct sigcontext *sc) void *end, unsigned long srp)
{ {
data->sc_end = (unsigned long) sc; unsigned long sr = *((unsigned long *) srp);
data->sc_end += sizeof(*sc);
data->fp_start = (unsigned long) end;
if((sr & PAGE_MASK) == ((unsigned long) end & PAGE_MASK))
data->sr = sr;
else data->sr = 0;
} }
static inline void setup_arch_frame(struct arch_frame_data_raw *in, static inline void setup_arch_frame(struct arch_frame_data_raw *in,
struct arch_frame_data *out) struct arch_frame_data *out)
{ {
unsigned long fpstate_start = in->sc_end; unsigned long fpstate_start = in->fp_start;
if(in->sr == 0){
fpstate_start &= ~PAGE_MASK; fpstate_start &= ~PAGE_MASK;
out->fpstate_size = PAGE_SIZE - fpstate_start; out->fpstate_size = PAGE_SIZE - fpstate_start;
}
else {
out->fpstate_size = in->sr - fpstate_start;
}
} }
/* This figures out where on the stack the SA_RESTORER function address /* This figures out where on the stack the SA_RESTORER function address
......
...@@ -7,72 +7,101 @@ ...@@ -7,72 +7,101 @@
#define __SYSDEP_I386_PTRACE_H #define __SYSDEP_I386_PTRACE_H
#include "uml-config.h" #include "uml-config.h"
#ifdef CONFIG_MODE_TT
#include "ptrace-tt.h" #include "ptrace-tt.h"
#endif
#ifdef CONFIG_MODE_SKAS
#include "ptrace-skas.h" #include "ptrace-skas.h"
#endif
#include "choose-mode.h" #include "choose-mode.h"
struct uml_pt_regs { union uml_pt_regs {
unsigned long args[6];
long syscall;
int is_user;
union {
#ifdef CONFIG_MODE_TT #ifdef CONFIG_MODE_TT
void *tt; struct tt_regs {
long syscall;
void *sc;
} tt;
#endif #endif
#ifdef CONFIG_MODE_SKAS #ifdef CONFIG_MODE_SKAS
struct { struct skas_regs {
unsigned long regs[HOST_FRAME_SIZE]; unsigned long regs[HOST_FRAME_SIZE];
unsigned long fp[HOST_FP_SIZE]; unsigned long fp[HOST_FP_SIZE];
unsigned long xfp[HOST_XFP_SIZE]; unsigned long xfp[HOST_XFP_SIZE];
unsigned long fault_addr; unsigned long fault_addr;
unsigned long fault_type; unsigned long fault_type;
unsigned long trap_type; unsigned long trap_type;
long syscall;
int is_user;
} skas; } skas;
#endif #endif
} mode;
}; };
#define EMPTY_UML_PT_REGS { \ #define EMPTY_UML_PT_REGS { }
syscall : -1, \
args : { [0 ... 5] = 0 }, \
is_user : 0 }
extern int mode_tt; extern int mode_tt;
#define UPT_SC(r) ((r)->tt.sc)
#define UPT_IP(r) \ #define UPT_IP(r) \
CHOOSE_MODE(SC_IP((r)->mode.tt), REGS_IP((r)->mode.skas.regs)) CHOOSE_MODE(SC_IP(UPT_SC(r)), REGS_IP((r)->skas.regs))
#define UPT_SP(r) \ #define UPT_SP(r) \
CHOOSE_MODE(SC_SP((r)->mode.tt), REGS_SP((r)->mode.skas.regs)) CHOOSE_MODE(SC_SP(UPT_SC(r)), REGS_SP((r)->skas.regs))
#define UPT_EFLAGS(r) \ #define UPT_EFLAGS(r) \
CHOOSE_MODE(SC_EFLAGS((r)->mode.tt), REGS_EFLAGS((r)->mode.skas.regs)) CHOOSE_MODE(SC_EFLAGS(UPT_SC(r)), REGS_EFLAGS((r)->skas.regs))
#define UPT_EAX(r) \ #define UPT_EAX(r) \
CHOOSE_MODE(SC_EAX((r)->mode.tt), REGS_EAX((r)->mode.skas.regs)) CHOOSE_MODE(SC_EAX(UPT_SC(r)), REGS_EAX((r)->skas.regs))
#define UPT_EBX(r) \ #define UPT_EBX(r) \
CHOOSE_MODE(SC_EBX((r)->mode.tt), REGS_EBX((r)->mode.skas.regs)) CHOOSE_MODE(SC_EBX(UPT_SC(r)), REGS_EBX((r)->skas.regs))
#define UPT_ECX(r) \ #define UPT_ECX(r) \
CHOOSE_MODE(SC_ECX((r)->mode.tt), REGS_ECX((r)->mode.skas.regs)) CHOOSE_MODE(SC_ECX(UPT_SC(r)), REGS_ECX((r)->skas.regs))
#define UPT_EDX(r) \ #define UPT_EDX(r) \
CHOOSE_MODE(SC_EDX((r)->mode.tt), REGS_EDX((r)->mode.skas.regs)) CHOOSE_MODE(SC_EDX(UPT_SC(r)), REGS_EDX((r)->skas.regs))
#define UPT_ESI(r) \ #define UPT_ESI(r) \
CHOOSE_MODE(SC_ESI((r)->mode.tt), REGS_ESI((r)->mode.skas.regs)) CHOOSE_MODE(SC_ESI(UPT_SC(r)), REGS_ESI((r)->skas.regs))
#define UPT_EDI(r) \ #define UPT_EDI(r) \
CHOOSE_MODE(SC_EDI((r)->mode.tt), REGS_EDI((r)->mode.skas.regs)) CHOOSE_MODE(SC_EDI(UPT_SC(r)), REGS_EDI((r)->skas.regs))
#define UPT_EBP(r) \ #define UPT_EBP(r) \
CHOOSE_MODE(SC_EBP((r)->mode.tt), REGS_EBP((r)->mode.skas.regs)) CHOOSE_MODE(SC_EBP(UPT_SC(r)), REGS_EBP((r)->skas.regs))
#define UPT_ORIG_EAX(r) ((r)->syscall) #define UPT_ORIG_EAX(r) \
CHOOSE_MODE((r)->tt.syscall, (r)->skas.syscall)
#define UPT_CS(r) \ #define UPT_CS(r) \
CHOOSE_MODE(SC_CS((r)->mode.tt), REGS_CS((r)->mode.skas.regs)) CHOOSE_MODE(SC_CS(UPT_SC(r)), REGS_CS((r)->skas.regs))
#define UPT_SS(r) \ #define UPT_SS(r) \
CHOOSE_MODE(SC_SS((r)->mode.tt), REGS_SS((r)->mode.skas.regs)) CHOOSE_MODE(SC_SS(UPT_SC(r)), REGS_SS((r)->skas.regs))
#define UPT_DS(r) \ #define UPT_DS(r) \
CHOOSE_MODE(SC_DS((r)->mode.tt), REGS_DS((r)->mode.skas.regs)) CHOOSE_MODE(SC_DS(UPT_SC(r)), REGS_DS((r)->skas.regs))
#define UPT_ES(r) \ #define UPT_ES(r) \
CHOOSE_MODE(SC_ES((r)->mode.tt), REGS_ES((r)->mode.skas.regs)) CHOOSE_MODE(SC_ES(UPT_SC(r)), REGS_ES((r)->skas.regs))
#define UPT_FS(r) \ #define UPT_FS(r) \
CHOOSE_MODE(SC_FS((r)->mode.tt), REGS_FS((r)->mode.skas.regs)) CHOOSE_MODE(SC_FS(UPT_SC(r)), REGS_FS((r)->skas.regs))
#define UPT_GS(r) \ #define UPT_GS(r) \
CHOOSE_MODE(SC_GS((r)->mode.tt), REGS_GS((r)->mode.skas.regs)) CHOOSE_MODE(SC_GS(UPT_SC(r)), REGS_GS((r)->skas.regs))
#define UPT_SC(r) ((r)->mode.tt)
#define UPT_SYSCALL_ARG1(r) UPT_EBX(r)
#define UPT_SYSCALL_ARG2(r) UPT_ECX(r)
#define UPT_SYSCALL_ARG3(r) UPT_EDX(r)
#define UPT_SYSCALL_ARG4(r) UPT_ESI(r)
#define UPT_SYSCALL_ARG5(r) UPT_EDI(r)
#define UPT_SYSCALL_ARG6(r) UPT_EBP(r)
extern int user_context(unsigned long sp);
#define UPT_IS_USER(r) \
CHOOSE_MODE(user_context(UPT_SP(r)), (r)->skas.is_user)
struct syscall_args {
unsigned long args[6];
};
#define SYSCALL_ARGS(r) ((struct syscall_args) \
{ .args = { UPT_SYSCALL_ARG1(r), \
UPT_SYSCALL_ARG2(r), \
UPT_SYSCALL_ARG3(r), \
UPT_SYSCALL_ARG4(r), \
UPT_SYSCALL_ARG5(r), \
UPT_SYSCALL_ARG6(r) } } )
#define UPT_REG(regs, reg) \ #define UPT_REG(regs, reg) \
({ unsigned long val; \ ({ unsigned long val; \
...@@ -129,28 +158,26 @@ extern int mode_tt; ...@@ -129,28 +158,26 @@ extern int mode_tt;
} while (0) } while (0)
#define UPT_SET_SYSCALL_RETURN(r, res) \ #define UPT_SET_SYSCALL_RETURN(r, res) \
CHOOSE_MODE(SC_SET_SYSCALL_RETURN((r)->mode.tt, (res)), \ CHOOSE_MODE(SC_SET_SYSCALL_RETURN(UPT_SC(r), (res)), \
REGS_SET_SYSCALL_RETURN((r)->mode.skas.regs, (res))) REGS_SET_SYSCALL_RETURN((r)->skas.regs, (res)))
#define UPT_RESTART_SYSCALL(r) \ #define UPT_RESTART_SYSCALL(r) \
CHOOSE_MODE(SC_RESTART_SYSCALL((r)->mode.tt), \ CHOOSE_MODE(SC_RESTART_SYSCALL(UPT_SC(r)), \
REGS_RESTART_SYSCALL((r)->mode.skas.regs)) REGS_RESTART_SYSCALL((r)->skas.regs))
#define UPT_ORIG_SYSCALL(r) UPT_EAX(r) #define UPT_ORIG_SYSCALL(r) UPT_EAX(r)
#define UPT_SYSCALL_NR(r) ((r)->syscall) #define UPT_SYSCALL_NR(r) UPT_ORIG_EAX(r)
#define UPT_SYSCALL_RET(r) UPT_EAX(r) #define UPT_SYSCALL_RET(r) UPT_EAX(r)
#define UPT_SEGV_IS_FIXABLE(r) \ #define UPT_SEGV_IS_FIXABLE(r) \
CHOOSE_MODE(SC_SEGV_IS_FIXABLE(r->mode.tt), \ CHOOSE_MODE(SC_SEGV_IS_FIXABLE(UPT_SC(r)), \
REGS_SEGV_IS_FIXABLE(&r->mode.skas)) REGS_SEGV_IS_FIXABLE(&r->skas))
#define UPT_FAULT_ADDR(r) \ #define UPT_FAULT_ADDR(r) \
CHOOSE_MODE(SC_FAULT_ADDR(r->mode.tt), \ CHOOSE_MODE(SC_FAULT_ADDR(UPT_SC(r)), REGS_FAULT_ADDR(&r->skas))
REGS_FAULT_ADDR(&r->mode.skas))
#define UPT_FAULT_WRITE(r) \ #define UPT_FAULT_WRITE(r) \
CHOOSE_MODE(SC_FAULT_WRITE(r->mode.tt), \ CHOOSE_MODE(SC_FAULT_WRITE(UPT_SC(r)), REGS_FAULT_WRITE(&r->skas))
REGS_FAULT_WRITE(&r->mode.skas))
#endif #endif
......
...@@ -33,34 +33,6 @@ ...@@ -33,34 +33,6 @@
#define SC_SEGV_IS_FIXABLE(sc) (SEGV_IS_FIXABLE(SC_TRAPNO(sc))) #define SC_SEGV_IS_FIXABLE(sc) (SEGV_IS_FIXABLE(SC_TRAPNO(sc)))
#ifdef CONFIG_MODE_TT
/* XXX struct sigcontext needs declaring by now */
static inline void sc_to_regs(struct uml_pt_regs *regs, struct sigcontext *sc,
unsigned long syscall)
{
regs->syscall = syscall;
regs->args[0] = SC_EBX(sc);
regs->args[1] = SC_ECX(sc);
regs->args[2] = SC_EDX(sc);
regs->args[3] = SC_ESI(sc);
regs->args[4] = SC_EDI(sc);
regs->args[5] = SC_EBP(sc);
}
#endif
#ifdef CONFIG_MODE_SKAS
static inline void host_to_regs(struct uml_pt_regs *regs)
{
regs->syscall = UPT_ORIG_EAX(regs);
regs->args[0] = UPT_EBX(regs);
regs->args[1] = UPT_ECX(regs);
regs->args[2] = UPT_EDX(regs);
regs->args[3] = UPT_ESI(regs);
regs->args[4] = UPT_EDI(regs);
regs->args[5] = UPT_EBP(regs);
}
#endif
extern unsigned long *sc_sigmask(void *sc_ptr); extern unsigned long *sc_sigmask(void *sc_ptr);
extern int sc_get_fpregs(unsigned long buf, void *sc_ptr); extern int sc_get_fpregs(unsigned long buf, void *sc_ptr);
......
...@@ -4,10 +4,12 @@ ...@@ -4,10 +4,12 @@
*/ */
#include "asm/unistd.h" #include "asm/unistd.h"
#include "sysdep/ptrace.h"
typedef long syscall_handler_t(struct pt_regs); typedef long syscall_handler_t(struct pt_regs);
#define EXECUTE_SYSCALL(syscall, regs) (*sys_call_table[syscall])(*regs); #define EXECUTE_SYSCALL(syscall, regs) \
((long (*)(struct syscall_args)) (*sys_call_table[syscall]))(SYSCALL_ARGS(&regs->regs))
extern syscall_handler_t sys_modify_ldt; extern syscall_handler_t sys_modify_ldt;
extern syscall_handler_t old_mmap_i386; extern syscall_handler_t old_mmap_i386;
......
/*
* Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
* Licensed under the GPL
*/
#ifndef __UML_UACCESS_H__
#define __UML_UACCESS_H__
extern int __do_copy_to_user(void *to, const void *from, int n,
void **fault_addr, void **fault_catcher);
extern unsigned long __do_user_copy(void *to, const void *from, int n,
void **fault_addr, void **fault_catcher,
void (*op)(void *to, const void *from,
int n), int *faulted_out);
void __do_copy(void *to, const void *from, int n);
#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:
*/
...@@ -24,7 +24,7 @@ struct cpu_task { ...@@ -24,7 +24,7 @@ struct cpu_task {
extern struct cpu_task cpu_tasks[]; extern struct cpu_task cpu_tasks[];
struct signal_info { struct signal_info {
void (*handler)(int, struct uml_pt_regs *); void (*handler)(int, union uml_pt_regs *);
int is_irq; int is_irq;
}; };
...@@ -87,7 +87,7 @@ extern void check_sigio(void); ...@@ -87,7 +87,7 @@ extern void check_sigio(void);
extern int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr); extern int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr);
extern void write_sigio_workaround(void); extern void write_sigio_workaround(void);
extern void arch_check_bugs(void); extern void arch_check_bugs(void);
extern int arch_handle_signal(int sig, struct uml_pt_regs *regs); extern int arch_handle_signal(int sig, union uml_pt_regs *regs);
extern int arch_fixup(unsigned long address, void *sc_ptr); extern int arch_fixup(unsigned long address, void *sc_ptr);
extern void forward_pending_sigio(int target); extern void forward_pending_sigio(int target);
extern int can_do_skas(void); extern int can_do_skas(void);
......
...@@ -10,8 +10,8 @@ obj-y = checksum.o config.o exec_kern.o exitcode.o frame_kern.o frame.o \ ...@@ -10,8 +10,8 @@ obj-y = checksum.o config.o exec_kern.o exitcode.o frame_kern.o frame.o \
process.o process_kern.o ptrace.o reboot.o resource.o sigio_user.o \ process.o process_kern.o ptrace.o reboot.o resource.o sigio_user.o \
sigio_kern.o signal_kern.o signal_user.o smp.o syscall_kern.o \ sigio_kern.o signal_kern.o signal_user.o smp.o syscall_kern.o \
syscall_user.o sysrq.o sys_call_table.o tempfile.o time.o \ syscall_user.o sysrq.o sys_call_table.o tempfile.o time.o \
time_kern.o tlb.o trap_kern.o trap_user.o um_arch.o \ time_kern.o tlb.o trap_kern.o trap_user.o uaccess_user.o um_arch.o \
umid.o user_util.o umid.o user_syms.o user_util.o
obj-$(CONFIG_BLK_DEV_INITRD) += initrd_kern.o initrd_user.o obj-$(CONFIG_BLK_DEV_INITRD) += initrd_kern.o initrd_user.o
obj-$(CONFIG_GPROF) += gprof_syms.o obj-$(CONFIG_GPROF) += gprof_syms.o
...@@ -23,9 +23,6 @@ obj-$(CONFIG_MODE_SKAS) += skas/ ...@@ -23,9 +23,6 @@ obj-$(CONFIG_MODE_SKAS) += skas/
user-objs-$(CONFIG_TTY_LOG) += tty_log.o user-objs-$(CONFIG_TTY_LOG) += tty_log.o
# user_syms.o not included here because Rules.make has its own ideas about
# building anything in export-objs
USER_OBJS := $(filter %_user.o,$(obj-y)) $(user-objs-y) config.o helper.o \ USER_OBJS := $(filter %_user.o,$(obj-y)) $(user-objs-y) config.o helper.o \
process.o tempfile.o time.o tty_log.o umid.o user_util.o user_syms.o process.o tempfile.o time.o tty_log.o umid.o user_util.o user_syms.o
USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file)) USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
...@@ -47,7 +44,7 @@ CFLAGS_user_syms.o = -D__AUTOCONF_INCLUDED__ $(DMODULES-y) $(DMODVERSIONS-y) \ ...@@ -47,7 +44,7 @@ CFLAGS_user_syms.o = -D__AUTOCONF_INCLUDED__ $(DMODULES-y) $(DMODVERSIONS-y) \
CFLAGS_frame.o := $(patsubst -fomit-frame-pointer,,$(USER_CFLAGS)) CFLAGS_frame.o := $(patsubst -fomit-frame-pointer,,$(USER_CFLAGS))
$(USER_OBJS) : %.o: %.c $(USER_OBJS) : %.o: %.c
$(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $< $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
$(obj)/unmap.o: $(src)/unmap.c $(obj)/unmap.o: $(src)/unmap.c
$(CC) $(UNMAP_CFLAGS) -c -o $@ $< $(CC) $(UNMAP_CFLAGS) -c -o $@ $<
......
...@@ -110,6 +110,7 @@ struct common_raw { ...@@ -110,6 +110,7 @@ struct common_raw {
unsigned long sig; unsigned long sig;
unsigned long sr; unsigned long sr;
unsigned long sp; unsigned long sp;
struct arch_frame_data_raw arch;
}; };
#define SA_RESTORER (0x04000000) #define SA_RESTORER (0x04000000)
...@@ -173,7 +174,6 @@ struct sc_frame_raw { ...@@ -173,7 +174,6 @@ struct sc_frame_raw {
struct common_raw common; struct common_raw common;
unsigned long sc; unsigned long sc;
int restorer; int restorer;
struct arch_frame_data_raw arch;
}; };
/* Changed only during early boot */ /* Changed only during early boot */
...@@ -185,7 +185,8 @@ static void sc_handler(int sig, struct sigcontext sc) ...@@ -185,7 +185,8 @@ static void sc_handler(int sig, struct sigcontext sc)
raw_sc->common.sr = frame_restorer(); raw_sc->common.sr = frame_restorer();
raw_sc->common.sp = frame_sp(); raw_sc->common.sp = frame_sp();
raw_sc->sc = (unsigned long) &sc; raw_sc->sc = (unsigned long) &sc;
setup_arch_frame_raw(&raw_sc->arch, &sc); setup_arch_frame_raw(&raw_sc->common.arch, &sc + 1, raw_sc->common.sr);
os_stop_process(os_getpid()); os_stop_process(os_getpid());
kill(getpid(), SIGKILL); kill(getpid(), SIGKILL);
} }
...@@ -205,18 +206,25 @@ struct si_frame_raw { ...@@ -205,18 +206,25 @@ struct si_frame_raw {
struct common_raw common; struct common_raw common;
unsigned long sip; unsigned long sip;
unsigned long si; unsigned long si;
unsigned long ucp;
unsigned long uc;
}; };
/* Changed only during early boot */ /* Changed only during early boot */
static struct si_frame_raw *raw_si = NULL; static struct si_frame_raw *raw_si = NULL;
static void si_handler(int sig, siginfo_t *si) static void si_handler(int sig, siginfo_t *si, struct ucontext *ucontext)
{ {
raw_si->common.sig = (unsigned long) &sig; raw_si->common.sig = (unsigned long) &sig;
raw_si->common.sr = frame_restorer(); raw_si->common.sr = frame_restorer();
raw_si->common.sp = frame_sp(); raw_si->common.sp = frame_sp();
raw_si->sip = (unsigned long) &si; raw_si->sip = (unsigned long) &si;
raw_si->si = (unsigned long) si; raw_si->si = (unsigned long) si;
raw_si->ucp = (unsigned long) &ucontext;
raw_si->uc = (unsigned long) ucontext;
setup_arch_frame_raw(&raw_si->common.arch,
ucontext->uc_mcontext.fpregs, raw_si->common.sr);
os_stop_process(os_getpid()); os_stop_process(os_getpid());
kill(getpid(), SIGKILL); kill(getpid(), SIGKILL);
} }
...@@ -292,7 +300,7 @@ void capture_signal_stack(void) ...@@ -292,7 +300,7 @@ void capture_signal_stack(void)
&signal_frame_sc.common); &signal_frame_sc.common);
signal_frame_sc.sc_index = raw_sc.sc - base; signal_frame_sc.sc_index = raw_sc.sc - base;
setup_arch_frame(&raw_sc.arch, &signal_frame_sc.arch); setup_arch_frame(&raw_sc.common.arch, &signal_frame_sc.common.arch);
/* Ditto for the sigcontext, sigrestorer layout */ /* Ditto for the sigcontext, sigrestorer layout */
raw_sc.restorer = 1; raw_sc.restorer = 1;
...@@ -300,6 +308,7 @@ void capture_signal_stack(void) ...@@ -300,6 +308,7 @@ void capture_signal_stack(void)
(void *) top, sigstack, PAGE_SIZE, (void *) top, sigstack, PAGE_SIZE,
&signal_frame_sc_sr.common); &signal_frame_sc_sr.common);
signal_frame_sc_sr.sc_index = raw_sc.sc - base; signal_frame_sc_sr.sc_index = raw_sc.sc - base;
setup_arch_frame(&raw_sc.common.arch, &signal_frame_sc_sr.common.arch);
/* And the siginfo layout */ /* And the siginfo layout */
...@@ -308,6 +317,9 @@ void capture_signal_stack(void) ...@@ -308,6 +317,9 @@ void capture_signal_stack(void)
&signal_frame_si.common); &signal_frame_si.common);
signal_frame_si.sip_index = raw_si.sip - base; signal_frame_si.sip_index = raw_si.sip - base;
signal_frame_si.si_index = raw_si.si - base; signal_frame_si.si_index = raw_si.si - base;
signal_frame_si.ucp_index = raw_si.ucp - base;
signal_frame_si.uc_index = raw_si.uc - base;
setup_arch_frame(&raw_si.common.arch, &signal_frame_si.common.arch);
if((munmap(stack, PAGE_SIZE) < 0) || if((munmap(stack, PAGE_SIZE) < 0) ||
(munmap(sigstack, PAGE_SIZE) < 0)){ (munmap(sigstack, PAGE_SIZE) < 0)){
......
...@@ -6,6 +6,8 @@ ...@@ -6,6 +6,8 @@
#include "asm/ptrace.h" #include "asm/ptrace.h"
#include "asm/uaccess.h" #include "asm/uaccess.h"
#include "asm/signal.h" #include "asm/signal.h"
#include "asm/uaccess.h"
#include "asm/ucontext.h"
#include "frame_kern.h" #include "frame_kern.h"
#include "sigcontext.h" #include "sigcontext.h"
#include "sysdep/ptrace.h" #include "sysdep/ptrace.h"
...@@ -27,48 +29,62 @@ static int copy_restorer(void (*restorer)(void), unsigned long start, ...@@ -27,48 +29,62 @@ static int copy_restorer(void (*restorer)(void), unsigned long start,
sizeof(restorer))); sizeof(restorer)));
} }
static int copy_sc_to_user(void *to, struct pt_regs *from) static int copy_sc_to_user(void *to, void *fp, struct pt_regs *from,
struct arch_frame_data *arch)
{ {
return(CHOOSE_MODE(copy_sc_to_user_tt(to, from->regs.mode.tt, return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs),
&signal_frame_sc_sr.arch), arch),
copy_sc_to_user_skas(to, &from->regs, copy_sc_to_user_skas(to, fp, &from->regs,
current->thread.cr2, current->thread.cr2,
current->thread.err))); current->thread.err)));
} }
static int copy_ucontext_to_user(struct ucontext *uc, void *fp, sigset_t *set,
unsigned long sp)
{
int err = 0;
err |= put_user(current->sas_ss_sp, &uc->uc_stack.ss_sp);
err |= put_user(sas_ss_flags(sp), &uc->uc_stack.ss_flags);
err |= put_user(current->sas_ss_size, &uc->uc_stack.ss_size);
err |= copy_sc_to_user(&uc->uc_mcontext, fp, &current->thread.regs,
&signal_frame_si.common.arch);
err |= copy_to_user(&uc->uc_sigmask, set, sizeof(*set));
return(err);
}
int setup_signal_stack_si(unsigned long stack_top, int sig, int setup_signal_stack_si(unsigned long stack_top, int sig,
unsigned long handler, void (*restorer)(void), unsigned long handler, void (*restorer)(void),
struct pt_regs *regs, siginfo_t *info, struct pt_regs *regs, siginfo_t *info,
sigset_t *mask) sigset_t *mask)
{ {
unsigned long start, sc, sigs; unsigned long start;
void *sip; void *sip, *ucp, *fp;
int sig_size = _NSIG_WORDS * sizeof(unsigned long);
start = stack_top - signal_frame_si.common.len - start = stack_top - signal_frame_si.common.len;
sc_size(&signal_frame_sc.arch) - sig_size;
sip = (void *) (start + signal_frame_si.si_index); sip = (void *) (start + signal_frame_si.si_index);
sc = start + signal_frame_si.common.len; ucp = (void *) (start + signal_frame_si.uc_index);
sigs = sc + sc_size(&signal_frame_sc.arch); fp = (void *) (((unsigned long) ucp) + sizeof(struct ucontext));
if(restorer == NULL) if(restorer == NULL)
panic("setup_signal_stack_si - no restorer"); panic("setup_signal_stack_si - no restorer");
if(copy_sc_to_user((void *) sc, regs) || if(copy_to_user((void *) start, signal_frame_si.common.data,
copy_to_user((void *) start, signal_frame_si.common.data,
signal_frame_si.common.len) || signal_frame_si.common.len) ||
copy_to_user((void *) (start + signal_frame_si.common.sig_index), copy_to_user((void *) (start + signal_frame_si.common.sig_index),
&sig, sizeof(sig)) || &sig, sizeof(sig)) ||
copy_siginfo_to_user(sip, info) || copy_siginfo_to_user(sip, info) ||
copy_to_user((void *) (start + signal_frame_si.sip_index), &sip, copy_to_user((void *) (start + signal_frame_si.sip_index), &sip,
sizeof(sip)) || sizeof(sip)) ||
copy_to_user((void *) sigs, mask, sig_size) || copy_ucontext_to_user(ucp, fp, mask, PT_REGS_SP(regs)) ||
copy_to_user((void *) (start + signal_frame_si.ucp_index), &ucp,
sizeof(ucp)) ||
copy_restorer(restorer, start, signal_frame_si.common.sr_index, copy_restorer(restorer, start, signal_frame_si.common.sr_index,
signal_frame_si.common.sr_relative)) signal_frame_si.common.sr_relative))
return(1); return(1);
PT_REGS_IP(regs) = handler; PT_REGS_IP(regs) = handler;
PT_REGS_SP(regs) = start + signal_frame_sc.common.sp_index; PT_REGS_SP(regs) = start + signal_frame_si.common.sp_index;
return(0); return(0);
} }
...@@ -96,7 +112,8 @@ int setup_signal_stack_sc(unsigned long stack_top, int sig, ...@@ -96,7 +112,8 @@ int setup_signal_stack_sc(unsigned long stack_top, int sig,
if(copy_to_user((void *) start, frame->data, frame->len) || if(copy_to_user((void *) start, frame->data, frame->len) ||
copy_to_user((void *) (start + frame->sig_index), &sig, copy_to_user((void *) (start + frame->sig_index), &sig,
sizeof(sig)) || sizeof(sig)) ||
copy_sc_to_user(user_sc, regs) || copy_sc_to_user(user_sc, NULL, regs,
&signal_frame_sc.common.arch) ||
copy_to_user(sc_sigmask(user_sc), mask, sizeof(mask->sig[0])) || copy_to_user(sc_sigmask(user_sc), mask, sizeof(mask->sig[0])) ||
copy_to_user((void *) sigs, &mask->sig[1], sig_size) || copy_to_user((void *) sigs, &mask->sig[1], sig_size) ||
copy_restorer(restorer, start, frame->sr_index, frame->sr_relative)) copy_restorer(restorer, start, frame->sr_index, frame->sr_relative))
......
...@@ -271,7 +271,7 @@ void enable_irq(unsigned int irq) ...@@ -271,7 +271,7 @@ void enable_irq(unsigned int irq)
* SMP cross-CPU interrupts have their own specific * SMP cross-CPU interrupts have their own specific
* handlers). * handlers).
*/ */
unsigned int do_IRQ(int irq, struct uml_pt_regs *regs) unsigned int do_IRQ(int irq, union uml_pt_regs *regs)
{ {
/* /*
* 0 return value means that this irq is already being * 0 return value means that this irq is already being
......
...@@ -42,7 +42,7 @@ static int pollfds_size = 0; ...@@ -42,7 +42,7 @@ static int pollfds_size = 0;
extern int io_count, intr_count; extern int io_count, intr_count;
void sigio_handler(int sig, struct uml_pt_regs *regs) void sigio_handler(int sig, union uml_pt_regs *regs)
{ {
struct irq_fd *irq_fd, *next; struct irq_fd *irq_fd, *next;
int i, n; int i, n;
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include "init.h" #include "init.h"
#include "os.h" #include "os.h"
#include "mode_kern.h" #include "mode_kern.h"
#include "uml_uaccess.h"
/* Changed during early boot */ /* Changed during early boot */
pgd_t swapper_pg_dir[1024]; pgd_t swapper_pg_dir[1024];
...@@ -414,8 +415,28 @@ __uml_setup("mem=", uml_mem_setup, ...@@ -414,8 +415,28 @@ __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)
{ {
return(CHOOSE_MODE_PROC(arch_validate_tt, arch_validate_skas, page, unsigned long addr, zero = 0;
mask, order)); int i;
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);
......
...@@ -169,8 +169,12 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, ...@@ -169,8 +169,12 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
void initial_thread_cb(void (*proc)(void *), void *arg) void initial_thread_cb(void (*proc)(void *), void *arg)
{ {
int save_kmalloc_ok = kmalloc_ok;
kmalloc_ok = 0;
CHOOSE_MODE_PROC(initial_thread_cb_tt, initial_thread_cb_skas, proc, CHOOSE_MODE_PROC(initial_thread_cb_tt, initial_thread_cb_skas, proc,
arg); arg);
kmalloc_ok = save_kmalloc_ok;
} }
unsigned long stack_sp(unsigned long page) unsigned long stack_sp(unsigned long page)
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "asm/uaccess.h" #include "asm/uaccess.h"
#include "asm/unistd.h" #include "asm/unistd.h"
#include "user_util.h" #include "user_util.h"
#include "asm/ucontext.h"
#include "kern_util.h" #include "kern_util.h"
#include "signal_kern.h" #include "signal_kern.h"
#include "signal_user.h" #include "signal_user.h"
...@@ -237,20 +238,20 @@ int sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize) ...@@ -237,20 +238,20 @@ int sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize)
} }
} }
static int copy_sc_from_user(struct pt_regs *to, void *from) static int copy_sc_from_user(struct pt_regs *to, void *from,
struct arch_frame_data *arch)
{ {
int ret; int ret;
ret = CHOOSE_MODE(copy_sc_from_user_tt(to->regs.mode.tt, from, ret = CHOOSE_MODE(copy_sc_from_user_tt(UPT_SC(&to->regs), from, arch),
&signal_frame_sc.arch),
copy_sc_from_user_skas(&to->regs, from)); copy_sc_from_user_skas(&to->regs, from));
return(ret); return(ret);
} }
int sys_sigreturn(struct pt_regs regs) int sys_sigreturn(struct pt_regs regs)
{ {
void *sc = sp_to_sc(PT_REGS_SP(&regs)); void *sc = sp_to_sc(PT_REGS_SP(&current->thread.regs));
void *mask = sp_to_mask(PT_REGS_SP(&regs)); void *mask = sp_to_mask(PT_REGS_SP(&current->thread.regs));
int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long); int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long);
spin_lock_irq(&current->sig->siglock); spin_lock_irq(&current->sig->siglock);
...@@ -260,22 +261,25 @@ int sys_sigreturn(struct pt_regs regs) ...@@ -260,22 +261,25 @@ int sys_sigreturn(struct pt_regs regs)
sigdelsetmask(&current->blocked, ~_BLOCKABLE); sigdelsetmask(&current->blocked, ~_BLOCKABLE);
recalc_sigpending(); recalc_sigpending();
spin_unlock_irq(&current->sig->siglock); spin_unlock_irq(&current->sig->siglock);
copy_sc_from_user(&current->thread.regs, sc); copy_sc_from_user(&current->thread.regs, sc,
&signal_frame_sc.common.arch);
return(PT_REGS_SYSCALL_RET(&current->thread.regs)); return(PT_REGS_SYSCALL_RET(&current->thread.regs));
} }
int sys_rt_sigreturn(struct pt_regs regs) int sys_rt_sigreturn(struct pt_regs regs)
{ {
void *sc = sp_to_rt_sc(PT_REGS_SP(&regs)); struct ucontext *uc = sp_to_uc(PT_REGS_SP(&current->thread.regs));
void *mask = sp_to_rt_mask(PT_REGS_SP(&regs)); void *fp;
int sig_size = _NSIG_WORDS * sizeof(unsigned long); int sig_size = _NSIG_WORDS * sizeof(unsigned long);
spin_lock_irq(&current->sig->siglock); spin_lock_irq(&current->sig->siglock);
copy_from_user(&current->blocked, mask, sig_size); copy_from_user(&current->blocked, &uc->uc_sigmask, sig_size);
sigdelsetmask(&current->blocked, ~_BLOCKABLE); sigdelsetmask(&current->blocked, ~_BLOCKABLE);
recalc_sigpending(); recalc_sigpending();
spin_unlock_irq(&current->sig->siglock); spin_unlock_irq(&current->sig->siglock);
copy_sc_from_user(&current->thread.regs, sc); fp = (void *) (((unsigned long) uc) + sizeof(struct ucontext));
copy_sc_from_user(&current->thread.regs, &uc->uc_mcontext,
&signal_frame_si.common.arch);
return(PT_REGS_SYSCALL_RET(&current->thread.regs)); return(PT_REGS_SYSCALL_RET(&current->thread.regs));
} }
......
...@@ -12,10 +12,11 @@ extern unsigned long exec_fpx_regs[]; ...@@ -12,10 +12,11 @@ extern unsigned long exec_fpx_regs[];
extern int have_fpx_regs; extern int have_fpx_regs;
extern void user_time_init_skas(void); extern void user_time_init_skas(void);
extern int copy_sc_from_user_skas(struct uml_pt_regs *regs, void *from_ptr); extern int copy_sc_from_user_skas(union uml_pt_regs *regs, void *from_ptr);
extern int copy_sc_to_user_skas(void *to_ptr, struct uml_pt_regs *regs, extern int copy_sc_to_user_skas(void *to_ptr, void *fp,
union uml_pt_regs *regs,
unsigned long fault_addr, int fault_type); unsigned long fault_addr, int fault_type);
extern void sig_handler_common_skas(int sig, struct sigcontext *sc); extern void sig_handler_common_skas(int sig, void *sc_ptr);
extern void halt_skas(void); extern void halt_skas(void);
extern void reboot_skas(void); extern void reboot_skas(void);
extern void kill_off_processes_skas(void); extern void kill_off_processes_skas(void);
......
...@@ -32,11 +32,10 @@ extern void before_mem_skas(unsigned long unused); ...@@ -32,11 +32,10 @@ extern void before_mem_skas(unsigned long unused);
extern unsigned long set_task_sizes_skas(int arg, unsigned long *host_size_out, extern unsigned long set_task_sizes_skas(int arg, unsigned long *host_size_out,
unsigned long *task_size_out); unsigned long *task_size_out);
extern int start_uml_skas(void); extern int start_uml_skas(void);
extern struct page *arch_validate_skas(struct page *page, int mask, int order);
extern int external_pid_skas(struct task_struct *task); extern int external_pid_skas(struct task_struct *task);
extern int thread_pid_skas(struct task_struct *task); extern int thread_pid_skas(struct task_struct *task);
#define kmem_end_skas (host_task_size) #define kmem_end_skas (host_task_size - 1024 * 1024)
#endif #endif
......
...@@ -17,21 +17,21 @@ extern void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr, ...@@ -17,21 +17,21 @@ extern void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr,
extern int start_idle_thread(void *stack, void *switch_buf_ptr, extern int start_idle_thread(void *stack, void *switch_buf_ptr,
void **fork_buf_ptr); void **fork_buf_ptr);
extern int user_thread(unsigned long stack, int flags); extern int user_thread(unsigned long stack, int flags);
extern void userspace(struct uml_pt_regs *regs); extern void userspace(union uml_pt_regs *regs);
extern void new_thread_proc(void *stack, void (*handler)(int sig)); extern void new_thread_proc(void *stack, void (*handler)(int sig));
extern void remove_sigstack(void); extern void remove_sigstack(void);
extern void new_thread_handler(int sig); extern void new_thread_handler(int sig);
extern void handle_syscall(struct uml_pt_regs *regs); extern void handle_syscall(union uml_pt_regs *regs);
extern void map(int fd, unsigned long virt, unsigned long phys, extern void map(int fd, unsigned long virt, unsigned long phys,
unsigned long len, int r, int w, int x); unsigned long len, int r, int w, int x);
extern int unmap(int fd, void *addr, int len); extern int unmap(int fd, void *addr, int len);
extern int protect(int fd, unsigned long addr, unsigned long len, extern int protect(int fd, unsigned long addr, unsigned long len,
int r, int w, int x, int must_succeed); int r, int w, int x, int must_succeed);
extern void user_signal(int sig, struct uml_pt_regs *regs); extern void user_signal(int sig, union uml_pt_regs *regs);
extern int singlestepping_skas(void); extern int singlestepping_skas(void);
extern int new_mm(int from); extern int new_mm(int from);
extern void save_registers(struct uml_pt_regs *regs); extern void save_registers(union uml_pt_regs *regs);
extern void restore_registers(struct uml_pt_regs *regs); extern void restore_registers(union uml_pt_regs *regs);
extern void start_userspace(void); extern void start_userspace(void);
extern void init_registers(int pid); extern void init_registers(int pid);
......
...@@ -18,11 +18,6 @@ unsigned long set_task_sizes_skas(int arg, unsigned long *host_size_out, ...@@ -18,11 +18,6 @@ unsigned long set_task_sizes_skas(int arg, unsigned long *host_size_out,
return(((unsigned long) set_task_sizes_skas) & ~0xffffff); return(((unsigned long) set_task_sizes_skas) & ~0xffffff);
} }
struct page *arch_validate_skas(struct page *page, int mask, int order)
{
return(page);
}
/* /*
* Overrides for Emacs so that we follow Linus's tabbing style. * Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically * Emacs will notice this stuff at the end of the file and automatically
......
...@@ -20,10 +20,10 @@ ...@@ -20,10 +20,10 @@
#include "user_util.h" #include "user_util.h"
#include "kern_util.h" #include "kern_util.h"
#include "skas.h" #include "skas.h"
#include "skas_ptrace.h"
#include "sysdep/sigcontext.h" #include "sysdep/sigcontext.h"
#include "os.h" #include "os.h"
#include "proc_mm.h" #include "proc_mm.h"
#include "skas_ptrace.h"
unsigned long exec_regs[FRAME_SIZE]; unsigned long exec_regs[FRAME_SIZE];
unsigned long exec_fp_regs[HOST_FP_SIZE]; unsigned long exec_fp_regs[HOST_FP_SIZE];
...@@ -42,11 +42,11 @@ static void handle_segv(int pid) ...@@ -42,11 +42,11 @@ static void handle_segv(int pid)
segv(fault.addr, 0, FAULT_WRITE(fault.is_write), 1, NULL); segv(fault.addr, 0, FAULT_WRITE(fault.is_write), 1, NULL);
} }
static void handle_trap(int pid, struct uml_pt_regs *regs) static void handle_trap(int pid, union uml_pt_regs *regs)
{ {
int err, syscall_nr, status; int err, syscall_nr, status;
syscall_nr = PT_SYSCALL_NR(regs->mode.skas.regs); syscall_nr = PT_SYSCALL_NR(regs->skas.regs);
if(syscall_nr < 1){ if(syscall_nr < 1){
relay_signal(SIGTRAP, regs); relay_signal(SIGTRAP, regs);
return; return;
...@@ -115,7 +115,7 @@ void start_userspace(void) ...@@ -115,7 +115,7 @@ void start_userspace(void)
userspace_pid = pid; userspace_pid = pid;
} }
void userspace(struct uml_pt_regs *regs) void userspace(union uml_pt_regs *regs)
{ {
int err, status, op; int err, status, op;
...@@ -131,7 +131,7 @@ void userspace(struct uml_pt_regs *regs) ...@@ -131,7 +131,7 @@ void userspace(struct uml_pt_regs *regs)
panic("userspace - waitpid failed, errno = %d\n", panic("userspace - waitpid failed, errno = %d\n",
errno); errno);
regs->is_user = 1; regs->skas.is_user = 1;
save_registers(regs); save_registers(regs);
if(WIFSTOPPED(status)){ if(WIFSTOPPED(status)){
...@@ -191,28 +191,28 @@ void thread_wait(void *sw, void *fb) ...@@ -191,28 +191,28 @@ void thread_wait(void *sw, void *fb)
longjmp(*fork_buf, 1); longjmp(*fork_buf, 1);
} }
static int move_registers(int int_op, int fp_op, struct uml_pt_regs *regs, static int move_registers(int int_op, int fp_op, union uml_pt_regs *regs,
unsigned long *fp_regs) unsigned long *fp_regs)
{ {
if(ptrace(int_op, userspace_pid, 0, regs->mode.skas.regs) < 0) if(ptrace(int_op, userspace_pid, 0, regs->skas.regs) < 0)
return(-errno); return(-errno);
if(ptrace(fp_op, userspace_pid, 0, fp_regs) < 0) if(ptrace(fp_op, userspace_pid, 0, fp_regs) < 0)
return(-errno); return(-errno);
return(0); return(0);
} }
void save_registers(struct uml_pt_regs *regs) void save_registers(union uml_pt_regs *regs)
{ {
unsigned long *fp_regs; unsigned long *fp_regs;
int err, fp_op; int err, fp_op;
if(have_fpx_regs){ if(have_fpx_regs){
fp_op = PTRACE_GETFPXREGS; fp_op = PTRACE_GETFPXREGS;
fp_regs = regs->mode.skas.xfp; fp_regs = regs->skas.xfp;
} }
else { else {
fp_op = PTRACE_GETFPREGS; fp_op = PTRACE_GETFPREGS;
fp_regs = regs->mode.skas.fp; fp_regs = regs->skas.fp;
} }
err = move_registers(PTRACE_GETREGS, fp_op, regs, fp_regs); err = move_registers(PTRACE_GETREGS, fp_op, regs, fp_regs);
...@@ -221,18 +221,18 @@ void save_registers(struct uml_pt_regs *regs) ...@@ -221,18 +221,18 @@ void save_registers(struct uml_pt_regs *regs)
err); err);
} }
void restore_registers(struct uml_pt_regs *regs) void restore_registers(union uml_pt_regs *regs)
{ {
unsigned long *fp_regs; unsigned long *fp_regs;
int err, fp_op; int err, fp_op;
if(have_fpx_regs){ if(have_fpx_regs){
fp_op = PTRACE_SETFPXREGS; fp_op = PTRACE_SETFPXREGS;
fp_regs = regs->mode.skas.xfp; fp_regs = regs->skas.xfp;
} }
else { else {
fp_op = PTRACE_SETFPREGS; fp_op = PTRACE_SETFPREGS;
fp_regs = regs->mode.skas.fp; fp_regs = regs->skas.fp;
} }
err = move_registers(PTRACE_SETREGS, fp_op, regs, fp_regs); err = move_registers(PTRACE_SETREGS, fp_op, regs, fp_regs);
...@@ -272,10 +272,14 @@ int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr) ...@@ -272,10 +272,14 @@ int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr)
(*cb_proc)(cb_arg); (*cb_proc)(cb_arg);
longjmp(*cb_back, 1); longjmp(*cb_back, 1);
} }
else if(n == 3) else if(n == 3){
kmalloc_ok = 0;
return(0); return(0);
else if(n == 4) }
else if(n == 4){
kmalloc_ok = 0;
return(1); return(1);
}
longjmp(**switch_buf, 1); longjmp(**switch_buf, 1);
} }
...@@ -296,8 +300,11 @@ void initial_thread_cb_skas(void (*proc)(void *), void *arg) ...@@ -296,8 +300,11 @@ void initial_thread_cb_skas(void (*proc)(void *), void *arg)
cb_proc = proc; cb_proc = proc;
cb_arg = arg; cb_arg = arg;
cb_back = &here; cb_back = &here;
block_signals();
if(setjmp(here) == 0) if(setjmp(here) == 0)
longjmp(initial_jmpbuf, 2); longjmp(initial_jmpbuf, 2);
unblock_signals();
cb_proc = NULL; cb_proc = NULL;
cb_arg = NULL; cb_arg = NULL;
......
...@@ -68,8 +68,7 @@ void new_thread_handler(int sig) ...@@ -68,8 +68,7 @@ void new_thread_handler(int sig)
n = run_kernel_thread(fn, arg, &current->thread.exec_buf); n = run_kernel_thread(fn, arg, &current->thread.exec_buf);
if(n == 1) if(n == 1)
userspace(&current->thread.regs.regs); userspace(&current->thread.regs.regs);
else if(n == 2) else do_exit(0);
do_exit(0);
} }
void new_thread_proc(void *stack, void (*handler)(int sig)) void new_thread_proc(void *stack, void (*handler)(int sig))
...@@ -109,21 +108,21 @@ int copy_thread_skas(int nr, unsigned long clone_flags, unsigned long sp, ...@@ -109,21 +108,21 @@ int copy_thread_skas(int nr, unsigned long clone_flags, unsigned long sp,
void (*handler)(int); void (*handler)(int);
if(current->thread.forking){ if(current->thread.forking){
memcpy(&p->thread.regs.regs.mode.skas, memcpy(&p->thread.regs.regs.skas,
&current->thread.regs.regs.mode.skas, &current->thread.regs.regs.skas,
sizeof(p->thread.regs.regs.mode.skas)); sizeof(p->thread.regs.regs.skas));
REGS_SET_SYSCALL_RETURN(p->thread.regs.regs.mode.skas.regs, 0); REGS_SET_SYSCALL_RETURN(p->thread.regs.regs.skas.regs, 0);
if(sp != 0) REGS_SP(p->thread.regs.regs.mode.skas.regs) = sp; if(sp != 0) REGS_SP(p->thread.regs.regs.skas.regs) = sp;
handler = fork_handler; handler = fork_handler;
} }
else { else {
memcpy(p->thread.regs.regs.mode.skas.regs, exec_regs, memcpy(p->thread.regs.regs.skas.regs, exec_regs,
sizeof(p->thread.regs.regs.mode.skas.regs)); sizeof(p->thread.regs.regs.skas.regs));
memcpy(p->thread.regs.regs.mode.skas.fp, exec_fp_regs, memcpy(p->thread.regs.regs.skas.fp, exec_fp_regs,
sizeof(p->thread.regs.regs.mode.skas.fp)); sizeof(p->thread.regs.regs.skas.fp));
memcpy(p->thread.regs.regs.mode.skas.xfp, exec_fpx_regs, memcpy(p->thread.regs.regs.skas.xfp, exec_fpx_regs,
sizeof(p->thread.regs.regs.mode.skas.xfp)); sizeof(p->thread.regs.regs.skas.xfp));
p->thread.request.u.thread = current->thread.request.u.thread; p->thread.request.u.thread = current->thread.request.u.thread;
handler = new_thread_handler; handler = new_thread_handler;
} }
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
extern int userspace_pid; extern int userspace_pid;
int copy_sc_from_user_skas(struct uml_pt_regs *regs, void *from_ptr) int copy_sc_from_user_skas(union uml_pt_regs *regs, void *from_ptr)
{ {
struct sigcontext sc, *from = from_ptr; struct sigcontext sc, *from = from_ptr;
unsigned long fpregs[FP_FRAME_SIZE]; unsigned long fpregs[FP_FRAME_SIZE];
...@@ -26,26 +26,26 @@ int copy_sc_from_user_skas(struct uml_pt_regs *regs, void *from_ptr) ...@@ -26,26 +26,26 @@ int copy_sc_from_user_skas(struct uml_pt_regs *regs, void *from_ptr)
if(err) if(err)
return(err); return(err);
regs->mode.skas.regs[GS] = sc.gs; regs->skas.regs[GS] = sc.gs;
regs->mode.skas.regs[FS] = sc.fs; regs->skas.regs[FS] = sc.fs;
regs->mode.skas.regs[ES] = sc.es; regs->skas.regs[ES] = sc.es;
regs->mode.skas.regs[DS] = sc.ds; regs->skas.regs[DS] = sc.ds;
regs->mode.skas.regs[EDI] = sc.edi; regs->skas.regs[EDI] = sc.edi;
regs->mode.skas.regs[ESI] = sc.esi; regs->skas.regs[ESI] = sc.esi;
regs->mode.skas.regs[EBP] = sc.ebp; regs->skas.regs[EBP] = sc.ebp;
regs->mode.skas.regs[UESP] = sc.esp; regs->skas.regs[UESP] = sc.esp;
regs->mode.skas.regs[EBX] = sc.ebx; regs->skas.regs[EBX] = sc.ebx;
regs->mode.skas.regs[EDX] = sc.edx; regs->skas.regs[EDX] = sc.edx;
regs->mode.skas.regs[ECX] = sc.ecx; regs->skas.regs[ECX] = sc.ecx;
regs->mode.skas.regs[EAX] = sc.eax; regs->skas.regs[EAX] = sc.eax;
regs->mode.skas.regs[EIP] = sc.eip; regs->skas.regs[EIP] = sc.eip;
regs->mode.skas.regs[CS] = sc.cs; regs->skas.regs[CS] = sc.cs;
regs->mode.skas.regs[EFL] = sc.eflags; regs->skas.regs[EFL] = sc.eflags;
regs->mode.skas.regs[UESP] = sc.esp_at_signal; regs->skas.regs[UESP] = sc.esp_at_signal;
regs->mode.skas.regs[SS] = sc.ss; regs->skas.regs[SS] = sc.ss;
regs->mode.skas.fault_addr = sc.cr2; regs->skas.fault_addr = sc.cr2;
regs->mode.skas.fault_type = FAULT_WRITE(sc.err); regs->skas.fault_type = FAULT_WRITE(sc.err);
regs->mode.skas.trap_type = sc.trapno; regs->skas.trap_type = sc.trapno;
err = ptrace(PTRACE_SETFPREGS, userspace_pid, 0, fpregs); err = ptrace(PTRACE_SETFPREGS, userspace_pid, 0, fpregs);
if(err < 0){ if(err < 0){
...@@ -57,7 +57,7 @@ int copy_sc_from_user_skas(struct uml_pt_regs *regs, void *from_ptr) ...@@ -57,7 +57,7 @@ int copy_sc_from_user_skas(struct uml_pt_regs *regs, void *from_ptr)
return(0); return(0);
} }
int copy_sc_to_user_skas(void *to_ptr, struct uml_pt_regs *regs, int copy_sc_to_user_skas(void *to_ptr, void *fp, union uml_pt_regs *regs,
unsigned long fault_addr, int fault_type) unsigned long fault_addr, int fault_type)
{ {
struct sigcontext sc, *to = to_ptr; struct sigcontext sc, *to = to_ptr;
...@@ -65,26 +65,26 @@ int copy_sc_to_user_skas(void *to_ptr, struct uml_pt_regs *regs, ...@@ -65,26 +65,26 @@ int copy_sc_to_user_skas(void *to_ptr, struct uml_pt_regs *regs,
unsigned long fpregs[FP_FRAME_SIZE]; unsigned long fpregs[FP_FRAME_SIZE];
int err; int err;
sc.gs = regs->mode.skas.regs[GS]; sc.gs = regs->skas.regs[GS];
sc.fs = regs->mode.skas.regs[FS]; sc.fs = regs->skas.regs[FS];
sc.es = regs->mode.skas.regs[ES]; sc.es = regs->skas.regs[ES];
sc.ds = regs->mode.skas.regs[DS]; sc.ds = regs->skas.regs[DS];
sc.edi = regs->mode.skas.regs[EDI]; sc.edi = regs->skas.regs[EDI];
sc.esi = regs->mode.skas.regs[ESI]; sc.esi = regs->skas.regs[ESI];
sc.ebp = regs->mode.skas.regs[EBP]; sc.ebp = regs->skas.regs[EBP];
sc.esp = regs->mode.skas.regs[UESP]; sc.esp = regs->skas.regs[UESP];
sc.ebx = regs->mode.skas.regs[EBX]; sc.ebx = regs->skas.regs[EBX];
sc.edx = regs->mode.skas.regs[EDX]; sc.edx = regs->skas.regs[EDX];
sc.ecx = regs->mode.skas.regs[ECX]; sc.ecx = regs->skas.regs[ECX];
sc.eax = regs->mode.skas.regs[EAX]; sc.eax = regs->skas.regs[EAX];
sc.eip = regs->mode.skas.regs[EIP]; sc.eip = regs->skas.regs[EIP];
sc.cs = regs->mode.skas.regs[CS]; sc.cs = regs->skas.regs[CS];
sc.eflags = regs->mode.skas.regs[EFL]; sc.eflags = regs->skas.regs[EFL];
sc.esp_at_signal = regs->mode.skas.regs[UESP]; sc.esp_at_signal = regs->skas.regs[UESP];
sc.ss = regs->mode.skas.regs[SS]; sc.ss = regs->skas.regs[SS];
sc.cr2 = fault_addr; sc.cr2 = fault_addr;
sc.err = TO_SC_ERR(fault_type); sc.err = TO_SC_ERR(fault_type);
sc.trapno = regs->mode.skas.trap_type; sc.trapno = regs->skas.trap_type;
err = ptrace(PTRACE_GETFPREGS, userspace_pid, 0, fpregs); err = ptrace(PTRACE_GETFPREGS, userspace_pid, 0, fpregs);
if(err < 0){ if(err < 0){
...@@ -92,7 +92,8 @@ int copy_sc_to_user_skas(void *to_ptr, struct uml_pt_regs *regs, ...@@ -92,7 +92,8 @@ int copy_sc_to_user_skas(void *to_ptr, struct uml_pt_regs *regs,
"errno = %d\n", errno); "errno = %d\n", errno);
return(1); return(1);
} }
to_fp = (struct _fpstate *)((unsigned long) to + sizeof(*to)); to_fp = (struct _fpstate *)
(fp ? (unsigned long) fp : ((unsigned long) to + sizeof(*to)));
sc.fpstate = to_fp; sc.fpstate = to_fp;
if(err) if(err)
......
...@@ -21,7 +21,7 @@ long execute_syscall_skas(void *r) ...@@ -21,7 +21,7 @@ long execute_syscall_skas(void *r)
current->thread.nsyscalls++; current->thread.nsyscalls++;
nsyscalls++; nsyscalls++;
syscall = regs->regs.syscall; syscall = UPT_SYSCALL_NR(&regs->regs);
if((syscall >= NR_syscalls) || (syscall < 0)) if((syscall >= NR_syscalls) || (syscall < 0))
res = -ENOSYS; res = -ENOSYS;
......
...@@ -15,18 +15,17 @@ ...@@ -15,18 +15,17 @@
#define ERESTARTNOINTR 513 #define ERESTARTNOINTR 513
#define ERESTARTNOHAND 514 #define ERESTARTNOHAND 514
void handle_syscall(struct uml_pt_regs *regs) void handle_syscall(union uml_pt_regs *regs)
{ {
long result; long result;
int index; int index;
host_to_regs(regs);
index = record_syscall_start(UPT_SYSCALL_NR(regs)); index = record_syscall_start(UPT_SYSCALL_NR(regs));
syscall_trace(); syscall_trace();
result = execute_syscall(regs); result = execute_syscall(regs);
REGS_SET_SYSCALL_RETURN(regs->mode.skas.regs, result); REGS_SET_SYSCALL_RETURN(regs->skas.regs, result);
if((result == -ERESTARTNOHAND) || (result == -ERESTARTSYS) || if((result == -ERESTARTNOHAND) || (result == -ERESTARTSYS) ||
(result == -ERESTARTNOINTR)) (result == -ERESTARTNOINTR))
do_signal(result); do_signal(result);
......
...@@ -134,9 +134,8 @@ void flush_tlb_range_skas(struct vm_area_struct *vma, unsigned long start, ...@@ -134,9 +134,8 @@ void flush_tlb_range_skas(struct vm_area_struct *vma, unsigned long start,
void flush_tlb_mm_skas(struct mm_struct *mm) void flush_tlb_mm_skas(struct mm_struct *mm)
{ {
if(mm == NULL)
flush_tlb_kernel_vm_skas(); flush_tlb_kernel_vm_skas();
else fix_range(mm, 0, host_task_size, 0); fix_range(mm, 0, host_task_size, 0);
} }
void force_flush_all_skas(void) void force_flush_all_skas(void)
......
...@@ -13,41 +13,40 @@ ...@@ -13,41 +13,40 @@
#include "task.h" #include "task.h"
#include "sigcontext.h" #include "sigcontext.h"
void sig_handler_common_skas(int sig, struct sigcontext *sc) void sig_handler_common_skas(int sig, void *sc_ptr)
{ {
struct uml_pt_regs save_regs, *r; struct sigcontext *sc = sc_ptr;
struct skas_regs *r;
struct signal_info *info; struct signal_info *info;
int save_errno = errno; int save_errno = errno;
r = (struct uml_pt_regs *) TASK_REGS(get_current()); r = &TASK_REGS(get_current())->skas;
save_regs = *r;
r->is_user = 0; r->is_user = 0;
r->mode.skas.fault_addr = SC_FAULT_ADDR(sc); r->fault_addr = SC_FAULT_ADDR(sc);
r->mode.skas.fault_type = SC_FAULT_TYPE(sc); r->fault_type = SC_FAULT_TYPE(sc);
r->mode.skas.trap_type = SC_TRAP_TYPE(sc); r->trap_type = SC_TRAP_TYPE(sc);
change_sig(SIGUSR1, 1); change_sig(SIGUSR1, 1);
info = &sig_info[sig]; info = &sig_info[sig];
if(!info->is_irq) unblock_signals(); if(!info->is_irq) unblock_signals();
(*info->handler)(sig, r); (*info->handler)(sig, (union uml_pt_regs *) r);
*r = save_regs;
errno = save_errno; errno = save_errno;
} }
extern int missed_ticks[]; extern int missed_ticks[];
void user_signal(int sig, struct uml_pt_regs *regs) void user_signal(int sig, union uml_pt_regs *regs)
{ {
struct signal_info *info; struct signal_info *info;
if(sig == SIGVTALRM) if(sig == SIGVTALRM)
missed_ticks[cpu()]++; missed_ticks[cpu()]++;
regs->is_user = 1; regs->skas.is_user = 1;
regs->mode.skas.fault_addr = 0; regs->skas.fault_addr = 0;
regs->mode.skas.fault_type = 0; regs->skas.fault_type = 0;
regs->mode.skas.trap_type = 0; regs->skas.trap_type = 0;
info = &sig_info[sig]; info = &sig_info[sig];
(*info->handler)(sig, regs); (*info->handler)(sig, regs);
......
...@@ -37,7 +37,7 @@ int timer_irq_inited = 0; ...@@ -37,7 +37,7 @@ int timer_irq_inited = 0;
*/ */
int __attribute__ ((__section__ (".unprotected"))) missed_ticks[NR_CPUS]; int __attribute__ ((__section__ (".unprotected"))) missed_ticks[NR_CPUS];
void timer_irq(struct uml_pt_regs *regs) void timer_irq(union uml_pt_regs *regs)
{ {
int cpu = current->thread_info->cpu, ticks = missed_ticks[cpu]; int cpu = current->thread_info->cpu, ticks = missed_ticks[cpu];
...@@ -50,7 +50,9 @@ void boot_timer_handler(int sig) ...@@ -50,7 +50,9 @@ void boot_timer_handler(int sig)
{ {
struct pt_regs regs; struct pt_regs regs;
regs.regs.is_user = 0; CHOOSE_MODE((void)
(UPT_SC(&regs.regs) = (struct sigcontext *) (&sig + 1)),
(void) (regs.regs.skas.is_user = 0));
do_timer(&regs); do_timer(&regs);
} }
...@@ -118,7 +120,7 @@ void __const_udelay(um_udelay_t usecs) ...@@ -118,7 +120,7 @@ void __const_udelay(um_udelay_t usecs)
for(i=0;i<n;i++) ; for(i=0;i<n;i++) ;
} }
void timer_handler(int sig, struct uml_pt_regs *regs) void timer_handler(int sig, union uml_pt_regs *regs)
{ {
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
update_process_times(user_context(UPT_SP(regs))); update_process_times(user_context(UPT_SP(regs)));
......
...@@ -164,14 +164,15 @@ void bad_segv(unsigned long address, unsigned long ip, int is_write) ...@@ -164,14 +164,15 @@ void bad_segv(unsigned long address, unsigned long ip, int is_write)
force_sig_info(SIGSEGV, &si, current); force_sig_info(SIGSEGV, &si, current);
} }
void relay_signal(int sig, struct uml_pt_regs *regs) void relay_signal(int sig, union uml_pt_regs *regs)
{ {
if(arch_handle_signal(sig, regs)) return; if(arch_handle_signal(sig, regs)) return;
if(!regs->is_user) panic("Kernel mode signal %d", sig); if(!UPT_IS_USER(regs))
panic("Kernel mode signal %d", sig);
force_sig(sig, current); force_sig(sig, current);
} }
void bus_handler(int sig, struct uml_pt_regs *regs) void bus_handler(int sig, union uml_pt_regs *regs)
{ {
if(current->thread.fault_catcher != NULL) if(current->thread.fault_catcher != NULL)
do_longjmp(current->thread.fault_catcher, 1); do_longjmp(current->thread.fault_catcher, 1);
......
...@@ -48,11 +48,11 @@ struct { ...@@ -48,11 +48,11 @@ struct {
int is_user; int is_user;
} segfault_record[1024]; } segfault_record[1024];
void segv_handler(int sig, struct uml_pt_regs *regs) void segv_handler(int sig, union uml_pt_regs *regs)
{ {
int index, max; int index, max;
if(regs->is_user && !UPT_SEGV_IS_FIXABLE(regs)){ if(UPT_IS_USER(regs) && !UPT_SEGV_IS_FIXABLE(regs)){
bad_segv(UPT_FAULT_ADDR(regs), UPT_IP(regs), bad_segv(UPT_FAULT_ADDR(regs), UPT_IP(regs),
UPT_FAULT_WRITE(regs)); UPT_FAULT_WRITE(regs));
return; return;
...@@ -65,35 +65,35 @@ void segv_handler(int sig, struct uml_pt_regs *regs) ...@@ -65,35 +65,35 @@ void segv_handler(int sig, struct uml_pt_regs *regs)
segfault_record[index].pid = os_getpid(); segfault_record[index].pid = os_getpid();
segfault_record[index].is_write = UPT_FAULT_WRITE(regs); segfault_record[index].is_write = UPT_FAULT_WRITE(regs);
segfault_record[index].sp = UPT_SP(regs); segfault_record[index].sp = UPT_SP(regs);
segfault_record[index].is_user = regs->is_user; segfault_record[index].is_user = UPT_IS_USER(regs);
segv(UPT_FAULT_ADDR(regs), UPT_IP(regs), UPT_FAULT_WRITE(regs), segv(UPT_FAULT_ADDR(regs), UPT_IP(regs), UPT_FAULT_WRITE(regs),
regs->is_user, regs); UPT_IS_USER(regs), regs);
} }
void usr2_handler(int sig, struct uml_pt_regs *regs) void usr2_handler(int sig, union uml_pt_regs *regs)
{ {
CHOOSE_MODE(syscall_handler_tt(sig, regs), (void) 0); CHOOSE_MODE(syscall_handler_tt(sig, regs), (void) 0);
} }
struct signal_info sig_info[] = { struct signal_info sig_info[] = {
[ SIGTRAP ] { handler : relay_signal, [ SIGTRAP ] { .handler = relay_signal,
is_irq : 0 }, .is_irq = 0 },
[ SIGFPE ] { handler : relay_signal, [ SIGFPE ] { .handler = relay_signal,
is_irq : 0 }, .is_irq = 0 },
[ SIGILL ] { handler : relay_signal, [ SIGILL ] { .handler = relay_signal,
is_irq : 0 }, .is_irq = 0 },
[ SIGBUS ] { handler : bus_handler, [ SIGBUS ] { .handler = bus_handler,
is_irq : 0 }, .is_irq = 0 },
[ SIGSEGV] { handler : segv_handler, [ SIGSEGV] { .handler = segv_handler,
is_irq : 0 }, .is_irq = 0 },
[ SIGIO ] { handler : sigio_handler, [ SIGIO ] { .handler = sigio_handler,
is_irq : 1 }, .is_irq = 1 },
[ SIGVTALRM ] { handler : timer_handler, [ SIGVTALRM ] { .handler = timer_handler,
is_irq : 1 }, .is_irq = 1 },
[ SIGALRM ] { handler : timer_handler, [ SIGALRM ] { .handler = timer_handler,
is_irq : 1 }, .is_irq = 1 },
[ SIGUSR2 ] { handler : usr2_handler, [ SIGUSR2 ] { .handler = usr2_handler,
is_irq : 0 }, .is_irq = 0 },
}; };
void sig_handler(int sig, struct sigcontext sc) void sig_handler(int sig, struct sigcontext sc)
......
...@@ -74,16 +74,16 @@ static void *xterm_data; ...@@ -74,16 +74,16 @@ static void *xterm_data;
static int xterm_fd; static int xterm_fd;
extern void *xterm_init(char *, int, struct chan_opts *); extern void *xterm_init(char *, int, struct chan_opts *);
extern int xterm_open(int, int, int, void *); extern int xterm_open(int, int, int, void *, char **);
extern void xterm_close(int, void *); extern void xterm_close(int, void *);
int open_gdb_chan(void) int open_gdb_chan(void)
{ {
char stack[UM_KERN_PAGE_SIZE]; char stack[UM_KERN_PAGE_SIZE], *dummy;
opts.tramp_stack = (unsigned long) stack; opts.tramp_stack = (unsigned long) stack;
xterm_data = xterm_init("", 0, &opts); xterm_data = xterm_init("", 0, &opts);
xterm_fd = xterm_open(1, 1, 1, xterm_data); xterm_fd = xterm_open(1, 1, 1, xterm_data, &dummy);
return(xterm_fd); return(xterm_fd);
} }
......
...@@ -13,9 +13,10 @@ extern int tracing_pid; ...@@ -13,9 +13,10 @@ extern int tracing_pid;
extern int tracer(int (*init_proc)(void *), void *sp); extern int tracer(int (*init_proc)(void *), void *sp);
extern void user_time_init_tt(void); extern void user_time_init_tt(void);
extern int copy_sc_from_user_tt(void *to_ptr, void *from_ptr, void *data); extern int copy_sc_from_user_tt(void *to_ptr, void *from_ptr, void *data);
extern int copy_sc_to_user_tt(void *to_ptr, void *from_ptr, void *data); extern int copy_sc_to_user_tt(void *to_ptr, void *fp, void *from_ptr,
extern void sig_handler_common_tt(int sig, struct sigcontext *sc); void *data);
extern void syscall_handler_tt(int sig, struct uml_pt_regs *regs); extern void sig_handler_common_tt(int sig, void *sc);
extern void syscall_handler_tt(int sig, union uml_pt_regs *regs);
extern void reboot_tt(void); extern void reboot_tt(void);
extern void halt_tt(void); extern void halt_tt(void);
extern int is_tracer_winch(int pid, int fd, void *data); extern int is_tracer_winch(int pid, int fd, void *data);
......
...@@ -33,7 +33,6 @@ extern void before_mem_tt(unsigned long brk_start); ...@@ -33,7 +33,6 @@ extern void before_mem_tt(unsigned long brk_start);
extern unsigned long set_task_sizes_tt(int arg, unsigned long *host_size_out, extern unsigned long set_task_sizes_tt(int arg, unsigned long *host_size_out,
unsigned long *task_size_out); unsigned long *task_size_out);
extern int start_uml_tt(void); extern int start_uml_tt(void);
extern struct page *arch_validate_tt(struct page *page, int mask, int order);
extern int external_pid_tt(struct task_struct *task); extern int external_pid_tt(struct task_struct *task);
extern int thread_pid_tt(struct task_struct *task); extern int thread_pid_tt(struct task_struct *task);
......
...@@ -26,10 +26,11 @@ extern void set_tracing(void *t, int tracing); ...@@ -26,10 +26,11 @@ extern void set_tracing(void *t, int tracing);
extern int is_tracing(void *task); extern int is_tracing(void *task);
extern int singlestepping_tt(void *t); extern int singlestepping_tt(void *t);
extern void clear_singlestep(void *t); extern void clear_singlestep(void *t);
extern void syscall_handler(int sig, struct uml_pt_regs *regs); extern void syscall_handler(int sig, union uml_pt_regs *regs);
extern void exit_kernel(int pid, void *task); extern void exit_kernel(int pid, void *task);
extern int do_syscall(void *task, int pid); extern int do_syscall(void *task, int pid);
extern int is_valid_pid(int pid); extern int is_valid_pid(int pid);
extern void remap_data(void *segment_start, void *segment_end, int w);
#endif #endif
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "asm/errno.h" #include "asm/errno.h"
#include "asm/current.h" #include "asm/current.h"
#include "asm/a.out.h" #include "asm/a.out.h"
#include "uml_uaccess.h"
#define ABOVE_KMEM (16 * 1024 * 1024) #define ABOVE_KMEM (16 * 1024 * 1024)
...@@ -51,9 +52,6 @@ static inline int copy_from_user_tt(void *to, const void *from, int n) ...@@ -51,9 +52,6 @@ static inline int copy_from_user_tt(void *to, const void *from, int n)
&current->thread.fault_catcher) : n); &current->thread.fault_catcher) : n);
} }
extern int __do_copy_to_user(void *to, const void *from, int n,
void **fault_addr, void **fault_catcher);
static inline int copy_to_user_tt(void *to, const void *from, int n) static inline int copy_to_user_tt(void *to, const void *from, int n)
{ {
return(access_ok_tt(VERIFY_WRITE, to, n) ? return(access_ok_tt(VERIFY_WRITE, to, n) ?
......
...@@ -39,32 +39,6 @@ unsigned long set_task_sizes_tt(int arg, unsigned long *host_size_out, ...@@ -39,32 +39,6 @@ unsigned long set_task_sizes_tt(int arg, unsigned long *host_size_out,
return(START); return(START);
} }
struct page *arch_validate_tt(struct page *page, int mask, int order)
{
unsigned long addr, zero = 0;
int i;
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;
}
/* /*
* Overrides for Emacs so that we follow Linus's tabbing style. * Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically * Emacs will notice this stuff at the end of the file and automatically
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include "linux/sched.h" #include "linux/sched.h"
#include "linux/signal.h" #include "linux/signal.h"
#include "linux/kernel.h" #include "linux/kernel.h"
#include "linux/interrupt.h"
#include "asm/system.h" #include "asm/system.h"
#include "asm/pgalloc.h" #include "asm/pgalloc.h"
#include "asm/ptrace.h" #include "asm/ptrace.h"
...@@ -111,8 +112,6 @@ void exit_thread_tt(void) ...@@ -111,8 +112,6 @@ void exit_thread_tt(void)
close(current->thread.mode.tt.switch_pipe[1]); close(current->thread.mode.tt.switch_pipe[1]);
} }
extern void schedule_tail(struct task_struct *prev);
static void new_thread_handler(int sig) static void new_thread_handler(int sig)
{ {
int (*fn)(void *); int (*fn)(void *);
...@@ -120,7 +119,7 @@ static void new_thread_handler(int sig) ...@@ -120,7 +119,7 @@ static void new_thread_handler(int sig)
fn = current->thread.request.u.thread.proc; fn = current->thread.request.u.thread.proc;
arg = current->thread.request.u.thread.arg; arg = current->thread.request.u.thread.arg;
current->thread.regs.regs.mode.tt = (void *) (&sig + 1); UPT_SC(&current->thread.regs.regs) = (void *) (&sig + 1);
suspend_new_thread(current->thread.mode.tt.switch_pipe[0]); suspend_new_thread(current->thread.mode.tt.switch_pipe[0]);
block_signals(); block_signals();
...@@ -160,7 +159,7 @@ static int new_thread_proc(void *stack) ...@@ -160,7 +159,7 @@ static int new_thread_proc(void *stack)
void finish_fork_handler(int sig) void finish_fork_handler(int sig)
{ {
current->thread.regs.regs.mode.tt = (void *) (&sig + 1); UPT_SC(&current->thread.regs.regs) = (void *) (&sig + 1);
suspend_new_thread(current->thread.mode.tt.switch_pipe[0]); suspend_new_thread(current->thread.mode.tt.switch_pipe[0]);
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
...@@ -168,6 +167,7 @@ void finish_fork_handler(int sig) ...@@ -168,6 +167,7 @@ void finish_fork_handler(int sig)
#endif #endif
enable_timer(); enable_timer();
change_sig(SIGVTALRM, 1); change_sig(SIGVTALRM, 1);
sti();
force_flush_all(); force_flush_all();
if(current->mm != current->parent->mm) if(current->mm != current->parent->mm)
protect_memory(uml_reserved, high_physmem - uml_reserved, 1, protect_memory(uml_reserved, high_physmem - uml_reserved, 1,
...@@ -187,6 +187,7 @@ int fork_tramp(void *stack) ...@@ -187,6 +187,7 @@ int fork_tramp(void *stack)
{ {
int sig = sigusr1; int sig = sigusr1;
cli();
init_new_thread_stack(stack, finish_fork_handler); init_new_thread_stack(stack, finish_fork_handler);
kill(os_getpid(), sig); kill(os_getpid(), sig);
...@@ -232,10 +233,10 @@ int copy_thread_tt(int nr, unsigned long clone_flags, unsigned long sp, ...@@ -232,10 +233,10 @@ int copy_thread_tt(int nr, unsigned long clone_flags, unsigned long sp,
} }
if(current->thread.forking){ if(current->thread.forking){
sc_to_sc(p->thread.regs.regs.mode.tt, sc_to_sc(UPT_SC(&p->thread.regs.regs),
current->thread.regs.regs.mode.tt); UPT_SC(&current->thread.regs.regs));
SC_SET_SYSCALL_RETURN(p->thread.regs.regs.mode.tt, 0); SC_SET_SYSCALL_RETURN(UPT_SC(&p->thread.regs.regs), 0);
if(sp != 0) SC_SP(p->thread.regs.regs.mode.tt) = sp; if(sp != 0) SC_SP(UPT_SC(&p->thread.regs.regs)) = sp;
} }
p->thread.mode.tt.extern_pid = new_pid; p->thread.mode.tt.extern_pid = new_pid;
......
...@@ -29,14 +29,15 @@ int copy_sc_from_user_tt(void *to_ptr, void *from_ptr, void *data) ...@@ -29,14 +29,15 @@ int copy_sc_from_user_tt(void *to_ptr, void *from_ptr, void *data)
return(err); return(err);
} }
int copy_sc_to_user_tt(void *to_ptr, void *from_ptr, void *data) int copy_sc_to_user_tt(void *to_ptr, void *fp, void *from_ptr, void *data)
{ {
struct arch_frame_data *arch = data; struct arch_frame_data *arch = data;
struct sigcontext *to = to_ptr, *from = from_ptr; struct sigcontext *to = to_ptr, *from = from_ptr;
struct _fpstate *to_fp, *from_fp; struct _fpstate *to_fp, *from_fp;
int err; int err;
to_fp = (struct _fpstate *)((unsigned long) to + sizeof(*to)); to_fp = (struct _fpstate *)
(fp ? (unsigned long) fp : ((unsigned long) to + sizeof(*to)));
from_fp = from->fpstate; from_fp = from->fpstate;
err = copy_to_user_proc(to, from, sizeof(*to)); err = copy_to_user_proc(to, from, sizeof(*to));
if(from_fp != NULL){ if(from_fp != NULL){
......
...@@ -20,29 +20,32 @@ static inline int check_area(void *ptr, int size) ...@@ -20,29 +20,32 @@ static inline int check_area(void *ptr, int size)
static int check_readlink(struct pt_regs *regs) static int check_readlink(struct pt_regs *regs)
{ {
return(check_area((void *) regs->regs.args[1], regs->regs.args[2])); return(check_area((void *) UPT_SYSCALL_ARG1(&regs->regs),
UPT_SYSCALL_ARG2(&regs->regs)));
} }
static int check_utime(struct pt_regs *regs) static int check_utime(struct pt_regs *regs)
{ {
return(check_area((void *) regs->regs.args[1], return(check_area((void *) UPT_SYSCALL_ARG1(&regs->regs),
sizeof(struct utimbuf))); sizeof(struct utimbuf)));
} }
static int check_oldstat(struct pt_regs *regs) static int check_oldstat(struct pt_regs *regs)
{ {
return(check_area((void *) regs->regs.args[1], return(check_area((void *) UPT_SYSCALL_ARG1(&regs->regs),
sizeof(struct __old_kernel_stat))); sizeof(struct __old_kernel_stat)));
} }
static int check_stat(struct pt_regs *regs) static int check_stat(struct pt_regs *regs)
{ {
return(check_area((void *) regs->regs.args[1], sizeof(struct stat))); return(check_area((void *) UPT_SYSCALL_ARG1(&regs->regs),
sizeof(struct stat)));
} }
static int check_stat64(struct pt_regs *regs) static int check_stat64(struct pt_regs *regs)
{ {
return(check_area((void *) regs->regs.args[1], sizeof(struct stat64))); return(check_area((void *) UPT_SYSCALL_ARG1(&regs->regs),
sizeof(struct stat64)));
} }
struct bogus { struct bogus {
...@@ -90,7 +93,7 @@ struct bogus this_is_bogus[256] = { ...@@ -90,7 +93,7 @@ struct bogus this_is_bogus[256] = {
static int check_bogosity(struct pt_regs *regs) static int check_bogosity(struct pt_regs *regs)
{ {
struct bogus *bogon = &this_is_bogus[regs->regs.syscall]; struct bogus *bogon = &this_is_bogus[UPT_SYSCALL_NR(&regs->regs)];
if(!bogon->kernel_ds) return(0); if(!bogon->kernel_ds) return(0);
if(bogon->check_params && (*bogon->check_params)(regs)) if(bogon->check_params && (*bogon->check_params)(regs))
...@@ -109,7 +112,7 @@ long execute_syscall_tt(void *r) ...@@ -109,7 +112,7 @@ long execute_syscall_tt(void *r)
current->thread.nsyscalls++; current->thread.nsyscalls++;
nsyscalls++; nsyscalls++;
syscall = regs->regs.syscall; syscall = UPT_SYSCALL_NR(&regs->regs);
if((syscall >= NR_syscalls) || (syscall < 0)) if((syscall >= NR_syscalls) || (syscall < 0))
res = -ENOSYS; res = -ENOSYS;
......
...@@ -22,15 +22,14 @@ ...@@ -22,15 +22,14 @@
#define ERESTARTNOINTR 513 #define ERESTARTNOINTR 513
#define ERESTARTNOHAND 514 #define ERESTARTNOHAND 514
void syscall_handler_tt(int sig, struct uml_pt_regs *regs) void syscall_handler_tt(int sig, union uml_pt_regs *regs)
{ {
void *sc; void *sc;
long result; long result;
int index, syscall; int index, syscall;
syscall = regs->syscall; syscall = UPT_SYSCALL_NR(regs);
sc = regs->mode.tt; sc = UPT_SC(regs);
sc_to_regs(regs, sc, syscall);
SC_START_SYSCALL(sc); SC_START_SYSCALL(sc);
index = record_syscall_start(syscall); index = record_syscall_start(syscall);
...@@ -40,7 +39,7 @@ void syscall_handler_tt(int sig, struct uml_pt_regs *regs) ...@@ -40,7 +39,7 @@ void syscall_handler_tt(int sig, struct uml_pt_regs *regs)
/* regs->sc may have changed while the system call ran (there may /* regs->sc may have changed while the system call ran (there may
* have been an interrupt or segfault), so it needs to be refreshed. * have been an interrupt or segfault), so it needs to be refreshed.
*/ */
regs->mode.tt = sc; UPT_SC(regs) = sc;
SC_SET_SYSCALL_RETURN(sc, result); SC_SET_SYSCALL_RETURN(sc, result);
if((result == -ERESTARTNOHAND) || (result == -ERESTARTSYS) || if((result == -ERESTARTNOHAND) || (result == -ERESTARTSYS) ||
...@@ -54,7 +53,7 @@ void syscall_handler_tt(int sig, struct uml_pt_regs *regs) ...@@ -54,7 +53,7 @@ void syscall_handler_tt(int sig, struct uml_pt_regs *regs)
int do_syscall(void *task, int pid) int do_syscall(void *task, int pid)
{ {
unsigned long proc_regs[FRAME_SIZE]; unsigned long proc_regs[FRAME_SIZE];
struct uml_pt_regs *regs; union uml_pt_regs *regs;
int syscall; int syscall;
if(ptrace_getregs(pid, proc_regs) < 0) if(ptrace_getregs(pid, proc_regs) < 0)
......
...@@ -14,26 +14,27 @@ ...@@ -14,26 +14,27 @@
#include "task.h" #include "task.h"
#include "tt.h" #include "tt.h"
void sig_handler_common_tt(int sig, struct sigcontext *sc) void sig_handler_common_tt(int sig, void *sc_ptr)
{ {
struct uml_pt_regs save_regs, *r; struct sigcontext *sc = sc_ptr;
struct tt_regs save_regs, *r;
struct signal_info *info; struct signal_info *info;
int save_errno = errno, is_user; int save_errno = errno, is_user;
unprotect_kernel_mem(); unprotect_kernel_mem();
r = (struct uml_pt_regs *) TASK_REGS(get_current()); r = &TASK_REGS(get_current())->tt;
save_regs = *r; save_regs = *r;
is_user = user_context(SC_SP(sc)); is_user = user_context(SC_SP(sc));
r->is_user = is_user; r->sc = sc;
r->mode.tt = sc; if(sig != SIGUSR2)
if(sig != SIGUSR2) r->syscall = -1; r->syscall = -1;
change_sig(SIGUSR1, 1); change_sig(SIGUSR1, 1);
info = &sig_info[sig]; info = &sig_info[sig];
if(!info->is_irq) unblock_signals(); if(!info->is_irq) unblock_signals();
(*info->handler)(sig, r); (*info->handler)(sig, (union uml_pt_regs *) r);
if(is_user){ if(is_user){
interrupt_end(); interrupt_end();
......
...@@ -7,34 +7,7 @@ ...@@ -7,34 +7,7 @@
#include <setjmp.h> #include <setjmp.h>
#include <string.h> #include <string.h>
#include "user_util.h" #include "user_util.h"
#include "uml_uaccess.h"
static unsigned long __do_user_copy(void *to, const void *from, int n,
void **fault_addr, void **fault_catcher,
void (*op)(void *to, const void *from,
int n), int *faulted_out)
{
unsigned long *faddrp = (unsigned long *) fault_addr, ret;
jmp_buf jbuf;
*fault_catcher = &jbuf;
if(setjmp(jbuf) == 0){
(*op)(to, from, n);
ret = 0;
*faulted_out = 0;
}
else {
ret = *faddrp;
*faulted_out = 1;
}
*fault_addr = NULL;
*fault_catcher = NULL;
return ret;
}
static void __do_copy(void *to, const void *from, int n)
{
memcpy(to, from, n);
}
int __do_copy_from_user(void *to, const void *from, int n, int __do_copy_from_user(void *to, const void *from, int n,
void **fault_addr, void **fault_catcher) void **fault_addr, void **fault_catcher)
...@@ -48,19 +21,6 @@ int __do_copy_from_user(void *to, const void *from, int n, ...@@ -48,19 +21,6 @@ int __do_copy_from_user(void *to, const void *from, int n,
else return(n - (fault - (unsigned long) from)); else return(n - (fault - (unsigned long) from));
} }
int __do_copy_to_user(void *to, const void *from, int n,
void **fault_addr, void **fault_catcher)
{
unsigned long fault;
int faulted;
fault = __do_user_copy(to, from, n, fault_addr, fault_catcher,
__do_copy, &faulted);
if(!faulted) return(0);
else return(n - (fault - (unsigned long) to));
}
static void __do_strncpy(void *dst, const void *src, int count) static void __do_strncpy(void *dst, const void *src, int count)
{ {
strncpy(dst, src, count); strncpy(dst, src, count);
......
/*
* Copyright (C) 2001 Chris Emerson (cemerson@chiark.greenend.org.uk)
* Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
* Licensed under the GPL
*/
#include <setjmp.h>
#include <string.h>
/* These are here rather than tt/uaccess.c because skas mode needs them in
* order to do SIGBUS recovery when a tmpfs mount runs out of room.
*/
unsigned long __do_user_copy(void *to, const void *from, int n,
void **fault_addr, void **fault_catcher,
void (*op)(void *to, const void *from,
int n), int *faulted_out)
{
unsigned long *faddrp = (unsigned long *) fault_addr, ret;
jmp_buf jbuf;
*fault_catcher = &jbuf;
if(setjmp(jbuf) == 0){
(*op)(to, from, n);
ret = 0;
*faulted_out = 0;
}
else {
ret = *faddrp;
*faulted_out = 1;
}
*fault_addr = NULL;
*fault_catcher = NULL;
return ret;
}
void __do_copy(void *to, const void *from, int n)
{
memcpy(to, from, n);
}
int __do_copy_to_user(void *to, const void *from, int n,
void **fault_addr, void **fault_catcher)
{
unsigned long fault;
int faulted;
fault = __do_user_copy(to, from, n, fault_addr, fault_catcher,
__do_copy, &faulted);
if(!faulted) return(0);
else return(n - (fault - (unsigned long) to));
}
/*
* 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:
*/
...@@ -10,10 +10,7 @@ ...@@ -10,10 +10,7 @@
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include "user_util.h" #include "user_util.h"
#include "mem_user.h" #include "mem_user.h"
#include "uml-config.h"
/* XXX All the __CONFIG_* stuff is broken because this file can't include
* config.h
*/
/* Had to steal this from linux/module.h because that file can't be included /* Had to steal this from linux/module.h because that file can't be included
* since this includes various user-level headers. * since this includes various user-level headers.
......
...@@ -117,7 +117,7 @@ void arch_check_bugs(void) ...@@ -117,7 +117,7 @@ void arch_check_bugs(void)
if(check_cpu_feature("xmm", &have_it)) cpu_has_xmm = have_it; if(check_cpu_feature("xmm", &have_it)) cpu_has_xmm = have_it;
} }
int arch_handle_signal(int sig, struct uml_pt_regs *regs) int arch_handle_signal(int sig, union uml_pt_regs *regs)
{ {
unsigned long ip; unsigned long ip;
......
...@@ -21,7 +21,7 @@ int sc_size(void *data) ...@@ -21,7 +21,7 @@ int sc_size(void *data)
void sc_to_sc(void *to_ptr, void *from_ptr) void sc_to_sc(void *to_ptr, void *from_ptr)
{ {
struct sigcontext *to = to_ptr, *from = from_ptr; struct sigcontext *to = to_ptr, *from = from_ptr;
int size = sizeof(*to) + signal_frame_sc.arch.fpstate_size; int size = sizeof(*to) + signal_frame_sc.common.arch.fpstate_size;
memcpy(to, from, size); memcpy(to, from, size);
if(from->fpstate != NULL) to->fpstate = (struct _fpstate *) (to + 1); if(from->fpstate != NULL) to->fpstate = (struct _fpstate *) (to + 1);
......
...@@ -9,7 +9,7 @@ extern void print_tail(void); ...@@ -9,7 +9,7 @@ extern void print_tail(void);
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
print_head(); print_head();
print_ptr("TASK_REGS", "struct uml_pt_regs", print_ptr("TASK_REGS", "union uml_pt_regs",
offsetof(struct task_struct, thread.regs)); offsetof(struct task_struct, thread.regs));
print("TASK_PID", "int", offsetof(struct task_struct, pid)); print("TASK_PID", "int", offsetof(struct task_struct, pid));
print_tail(); print_tail();
......
...@@ -48,7 +48,7 @@ typedef elf_greg_t elf_gregset_t[ELF_NGREG]; ...@@ -48,7 +48,7 @@ typedef elf_greg_t elf_gregset_t[ELF_NGREG];
/* fake once used fs and gs selectors? */ \ /* fake once used fs and gs selectors? */ \
pr_reg[9] = PT_REGS_DS(regs); \ pr_reg[9] = PT_REGS_DS(regs); \
pr_reg[10] = PT_REGS_DS(regs); \ pr_reg[10] = PT_REGS_DS(regs); \
pr_reg[11] = regs->regs.syscall; \ pr_reg[11] = PT_REGS_SYSCALL_NR(regs); \
pr_reg[12] = PT_REGS_IP(regs); \ pr_reg[12] = PT_REGS_IP(regs); \
pr_reg[13] = PT_REGS_CS(regs); \ pr_reg[13] = PT_REGS_CS(regs); \
pr_reg[14] = PT_REGS_EFLAGS(regs); \ pr_reg[14] = PT_REGS_EFLAGS(regs); \
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
#include "linux/config.h" #include "linux/config.h"
#include "skas_ptrace.h"
#include "asm/current.h" #include "asm/current.h"
#define pt_regs pt_regs_subarch #define pt_regs pt_regs_subarch
...@@ -23,9 +23,10 @@ ...@@ -23,9 +23,10 @@
#undef instruction_pointer #undef instruction_pointer
#include "sysdep/ptrace.h" #include "sysdep/ptrace.h"
#include "skas_ptrace.h"
struct pt_regs { struct pt_regs {
struct uml_pt_regs regs; union uml_pt_regs regs;
}; };
#define EMPTY_REGS { regs : EMPTY_UML_PT_REGS } #define EMPTY_REGS { regs : EMPTY_UML_PT_REGS }
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#ifndef __UM_PTRACE_I386_H #ifndef __UM_PTRACE_I386_H
#define __UM_PTRACE_I386_H #define __UM_PTRACE_I386_H
#include "sysdep/ptrace.h"
#include "asm/ptrace-generic.h" #include "asm/ptrace-generic.h"
#define PT_REGS_EAX(r) UPT_EAX(&(r)->regs) #define PT_REGS_EAX(r) UPT_EAX(&(r)->regs)
...@@ -29,7 +30,7 @@ ...@@ -29,7 +30,7 @@
#define PT_REGS_SYSCALL_RET(r) PT_REGS_EAX(r) #define PT_REGS_SYSCALL_RET(r) PT_REGS_EAX(r)
#define PT_FIX_EXEC_STACK(sp) do ; while(0) #define PT_FIX_EXEC_STACK(sp) do ; while(0)
#define user_mode(r) ((r)->regs.is_user) #define user_mode(r) UPT_IS_USER(&(r)->regs)
#endif #endif
......
#ifndef _ASM_UM_UCONTEXT_H
#define _ASM_UM_UCONTEXT_H
#include "asm/arch/ucontext.h"
#endif
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