From: Jeff Dike This moves the register shuffling code into arch/um/os-Linux/sys-$(SUBARCH), making it purely userspace code. It also adds an x86_64 implementation of registers.c. Signed-off-by: Jeff Dike Signed-off-by: Andrew Morton --- 25-akpm/arch/um/include/registers.h | 27 +++++ 25-akpm/arch/um/kernel/process.c | 1 25-akpm/arch/um/kernel/skas/include/skas.h | 3 25-akpm/arch/um/kernel/skas/process.c | 89 ------------------ 25-akpm/arch/um/kernel/skas/process_kern.c | 8 - 25-akpm/arch/um/os-Linux/Makefile | 3 25-akpm/arch/um/os-Linux/sys-i386/Makefile | 11 ++ 25-akpm/arch/um/os-Linux/sys-i386/registers.c | 115 ++++++++++++++++++++++++ 25-akpm/arch/um/os-Linux/sys-x86_64/Makefile | 11 ++ 25-akpm/arch/um/os-Linux/sys-x86_64/registers.c | 82 +++++++++++++++++ 10 files changed, 255 insertions(+), 95 deletions(-) diff -puN arch/um/include/registers.h~uml-factor-out-register-saving-and-restoring arch/um/include/registers.h --- 25/arch/um/include/registers.h~uml-factor-out-register-saving-and-restoring 2005-01-09 23:44:06.116233680 -0800 +++ 25-akpm/arch/um/include/registers.h 2005-01-09 23:44:06.132231248 -0800 @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2004 PathScale, Inc + * Licensed under the GPL + */ + +#ifndef __REGISTERS_H +#define __REGISTERS_H + +#include "sysdep/ptrace.h" + +extern void init_thread_registers(union uml_pt_regs *to); +extern void save_registers(int pid, union uml_pt_regs *regs); +extern void restore_registers(int pid, union uml_pt_regs *regs); +extern void init_registers(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: + */ diff -puN arch/um/kernel/process.c~uml-factor-out-register-saving-and-restoring arch/um/kernel/process.c --- 25/arch/um/kernel/process.c~uml-factor-out-register-saving-and-restoring 2005-01-09 23:44:06.118233376 -0800 +++ 25-akpm/arch/um/kernel/process.c 2005-01-09 23:44:06.133231096 -0800 @@ -40,6 +40,7 @@ #ifdef UML_CONFIG_MODE_SKAS #include "skas.h" #include "skas_ptrace.h" +#include "registers.h" #endif void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int)) diff -puN arch/um/kernel/skas/include/skas.h~uml-factor-out-register-saving-and-restoring arch/um/kernel/skas/include/skas.h --- 25/arch/um/kernel/skas/include/skas.h~uml-factor-out-register-saving-and-restoring 2005-01-09 23:44:06.119233224 -0800 +++ 25-akpm/arch/um/kernel/skas/include/skas.h 2005-01-09 23:44:06.133231096 -0800 @@ -29,10 +29,7 @@ extern int protect(int fd, unsigned long int r, int w, int x, int must_succeed); extern void user_signal(int sig, union uml_pt_regs *regs); extern int new_mm(int from); -extern void save_registers(union uml_pt_regs *regs); -extern void restore_registers(union uml_pt_regs *regs); extern void start_userspace(int cpu); -extern void init_registers(int pid); #endif diff -puN arch/um/kernel/skas/process.c~uml-factor-out-register-saving-and-restoring arch/um/kernel/skas/process.c --- 25/arch/um/kernel/skas/process.c~uml-factor-out-register-saving-and-restoring 2005-01-09 23:44:06.121232920 -0800 +++ 25-akpm/arch/um/kernel/skas/process.c 2005-01-09 23:44:06.134230944 -0800 @@ -28,6 +28,7 @@ #include "skas_ptrace.h" #include "chan_user.h" #include "signal_user.h" +#include "registers.h" int is_skas_winch(int pid, int fd, void *data) { @@ -38,13 +39,6 @@ int is_skas_winch(int pid, int fd, void return(1); } -/* These are set once at boot time and not changed thereafter */ - -unsigned long exec_regs[FRAME_SIZE]; -unsigned long exec_fp_regs[HOST_FP_SIZE]; -unsigned long exec_fpx_regs[HOST_XFP_SIZE]; -int have_fpx_regs = 1; - static void handle_segv(int pid) { struct ptrace_faultinfo fault; @@ -143,7 +137,7 @@ void userspace(union uml_pt_regs *regs) int err, status, op, pid = userspace_pid[0]; int local_using_sysemu; /*To prevent races if using_sysemu changes under us.*/ - restore_registers(regs); + restore_registers(pid, regs); local_using_sysemu = get_using_sysemu(); @@ -160,7 +154,7 @@ void userspace(union uml_pt_regs *regs) errno); regs->skas.is_user = 1; - save_registers(regs); + save_registers(pid, regs); UPT_SYSCALL_NR(regs) = -1; /* Assume: It's not a syscall */ if(WIFSTOPPED(status)){ @@ -192,7 +186,7 @@ void userspace(union uml_pt_regs *regs) PT_SYSCALL_NR(regs->skas.regs) = -1; } - restore_registers(regs); + restore_registers(pid, regs); /*Now we ended the syscall, so re-read local_using_sysemu.*/ local_using_sysemu = get_using_sysemu(); @@ -243,58 +237,6 @@ void thread_wait(void *sw, void *fb) siglongjmp(*fork_buf, 1); } -static int move_registers(int pid, int int_op, int fp_op, - union uml_pt_regs *regs, unsigned long *fp_regs) -{ - if(ptrace(int_op, pid, 0, regs->skas.regs) < 0) - return(-errno); - if(ptrace(fp_op, pid, 0, fp_regs) < 0) - return(-errno); - return(0); -} - -void save_registers(union uml_pt_regs *regs) -{ - unsigned long *fp_regs; - int err, fp_op; - - if(have_fpx_regs){ - fp_op = PTRACE_GETFPXREGS; - fp_regs = regs->skas.xfp; - } - else { - fp_op = PTRACE_GETFPREGS; - fp_regs = regs->skas.fp; - } - - err = move_registers(userspace_pid[0], PTRACE_GETREGS, fp_op, regs, - fp_regs); - if(err) - panic("save_registers - saving registers failed, errno = %d\n", - -err); -} - -void restore_registers(union uml_pt_regs *regs) -{ - unsigned long *fp_regs; - int err, fp_op; - - if(have_fpx_regs){ - fp_op = PTRACE_SETFPXREGS; - fp_regs = regs->skas.xfp; - } - else { - fp_op = PTRACE_SETFPREGS; - fp_regs = regs->skas.fp; - } - - err = move_registers(userspace_pid[0], PTRACE_SETREGS, fp_op, regs, - fp_regs); - if(err) - panic("restore_registers - saving registers failed, " - "errno = %d\n", -err); -} - void switch_threads(void *me, void *next) { sigjmp_buf my_buf, **me_ptr = me, *next_buf = next; @@ -394,29 +336,6 @@ void kill_off_processes_skas(void) os_kill_ptraced_process(userspace_pid[0], 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 diff -puN arch/um/kernel/skas/process_kern.c~uml-factor-out-register-saving-and-restoring arch/um/kernel/skas/process_kern.c --- 25/arch/um/kernel/skas/process_kern.c~uml-factor-out-register-saving-and-restoring 2005-01-09 23:44:06.122232768 -0800 +++ 25-akpm/arch/um/kernel/skas/process_kern.c 2005-01-09 23:44:06.135230792 -0800 @@ -22,6 +22,7 @@ #include "kern.h" #include "mode.h" #include "proc_mm.h" +#include "registers.h" void *switch_to_skas(void *prev, void *next) { @@ -118,12 +119,7 @@ int copy_thread_skas(int nr, unsigned lo handler = fork_handler; } else { - memcpy(p->thread.regs.regs.skas.regs, exec_regs, - sizeof(p->thread.regs.regs.skas.regs)); - memcpy(p->thread.regs.regs.skas.fp, exec_fp_regs, - sizeof(p->thread.regs.regs.skas.fp)); - memcpy(p->thread.regs.regs.skas.xfp, exec_fpx_regs, - sizeof(p->thread.regs.regs.skas.xfp)); + init_thread_registers(&p->thread.regs.regs); p->thread.request.u.thread = current->thread.request.u.thread; handler = new_thread_handler; } diff -puN arch/um/os-Linux/Makefile~uml-factor-out-register-saving-and-restoring arch/um/os-Linux/Makefile --- 25/arch/um/os-Linux/Makefile~uml-factor-out-register-saving-and-restoring 2005-01-09 23:44:06.124232464 -0800 +++ 25-akpm/arch/um/os-Linux/Makefile 2005-01-09 23:44:06.135230792 -0800 @@ -3,7 +3,8 @@ # Licensed under the GPL # -obj-y = elf_aux.o file.o process.o time.o tty.o user_syms.o drivers/ +obj-y = elf_aux.o file.o process.o time.o tty.o user_syms.o drivers/ \ + sys-$(SUBARCH)/ USER_OBJS := elf_aux.o file.o process.o time.o tty.o USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file)) diff -puN arch/um/os-Linux/sys-i386/Makefile~uml-factor-out-register-saving-and-restoring arch/um/os-Linux/sys-i386/Makefile --- 25/arch/um/os-Linux/sys-i386/Makefile~uml-factor-out-register-saving-and-restoring 2005-01-09 23:44:06.125232312 -0800 +++ 25-akpm/arch/um/os-Linux/sys-i386/Makefile 2005-01-09 23:44:06.135230792 -0800 @@ -0,0 +1,11 @@ +# +# Copyright (C) 2000 Jeff Dike (jdike@karaya.com) +# Licensed under the GPL +# + +obj-$(CONFIG_MODE_SKAS) = registers.o + +USER_OBJS := $(foreach file,$(obj-y),$(obj)/$(file)) + +$(USER_OBJS) : %.o: %.c + $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $< diff -puN arch/um/os-Linux/sys-i386/registers.c~uml-factor-out-register-saving-and-restoring arch/um/os-Linux/sys-i386/registers.c --- 25/arch/um/os-Linux/sys-i386/registers.c~uml-factor-out-register-saving-and-restoring 2005-01-09 23:44:06.127232008 -0800 +++ 25-akpm/arch/um/os-Linux/sys-i386/registers.c 2005-01-09 23:44:06.136230640 -0800 @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2004 PathScale, Inc + * Licensed under the GPL + */ + +#include +#include +#include +#include "sysdep/ptrace.h" +#include "uml-config.h" +#include "skas_ptregs.h" +#include "registers.h" +#include "user.h" + +/* These are set once at boot time and not changed thereafter */ + +static unsigned long exec_regs[HOST_FRAME_SIZE]; +static unsigned long exec_fp_regs[HOST_FP_SIZE]; +static unsigned long exec_fpx_regs[HOST_XFP_SIZE]; +static int have_fpx_regs = 1; + +void init_thread_registers(union uml_pt_regs *to) +{ + memcpy(to->skas.regs, exec_regs, sizeof(to->skas.regs)); + memcpy(to->skas.fp, exec_fp_regs, sizeof(to->skas.fp)); + if(have_fpx_regs) + memcpy(to->skas.xfp, exec_fpx_regs, sizeof(to->skas.xfp)); +} + +static int move_registers(int pid, int int_op, union uml_pt_regs *regs, + int fp_op, unsigned long *fp_regs) +{ + if(ptrace(int_op, pid, 0, regs->skas.regs) < 0) + return(-errno); + + if(ptrace(fp_op, pid, 0, fp_regs) < 0) + return(-errno); + + return(0); +} + +void save_registers(int pid, union uml_pt_regs *regs) +{ + unsigned long *fp_regs; + int err, fp_op; + + if(have_fpx_regs){ + fp_op = PTRACE_GETFPXREGS; + fp_regs = regs->skas.xfp; + } + else { + fp_op = PTRACE_GETFPREGS; + fp_regs = regs->skas.fp; + } + + err = move_registers(pid, PTRACE_GETREGS, regs, fp_op, fp_regs); + if(err) + panic("save_registers - saving registers failed, errno = %d\n", + -err); +} + +void restore_registers(int pid, union uml_pt_regs *regs) +{ + unsigned long *fp_regs; + int err, fp_op; + + if(have_fpx_regs){ + fp_op = PTRACE_SETFPXREGS; + fp_regs = regs->skas.xfp; + } + else { + fp_op = PTRACE_SETFPREGS; + fp_regs = regs->skas.fp; + } + + err = move_registers(pid, PTRACE_SETREGS, regs, fp_op, fp_regs); + if(err) + panic("restore_registers - saving registers failed, " + "errno = %d\n", -err); +} + +void init_registers(int pid) +{ + int err; + + err = ptrace(PTRACE_GETREGS, pid, 0, exec_regs); + if(err) + panic("check_ptrace : PTRACE_GETREGS failed, errno = %d", + err); + + err = ptrace(PTRACE_GETFPXREGS, pid, 0, exec_fpx_regs); + if(!err) + return; + + have_fpx_regs = 0; + if(err != EIO) + panic("check_ptrace : PTRACE_GETFPXREGS failed, errno = %d", + err); + + err = ptrace(PTRACE_GETFPREGS, pid, 0, exec_fp_regs); + if(err) + panic("check_ptrace : PTRACE_GETFPREGS failed, errno = %d", + err); +} + +/* + * 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: + */ diff -puN arch/um/os-Linux/sys-x86_64/Makefile~uml-factor-out-register-saving-and-restoring arch/um/os-Linux/sys-x86_64/Makefile --- 25/arch/um/os-Linux/sys-x86_64/Makefile~uml-factor-out-register-saving-and-restoring 2005-01-09 23:44:06.128231856 -0800 +++ 25-akpm/arch/um/os-Linux/sys-x86_64/Makefile 2005-01-09 23:44:06.136230640 -0800 @@ -0,0 +1,11 @@ +# +# Copyright (C) 2000 Jeff Dike (jdike@karaya.com) +# Licensed under the GPL +# + +obj-$(CONFIG_MODE_SKAS) = registers.o + +USER_OBJS := $(foreach file,$(obj-y),$(obj)/$(file)) + +$(USER_OBJS) : %.o: %.c + $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $< diff -puN arch/um/os-Linux/sys-x86_64/registers.c~uml-factor-out-register-saving-and-restoring arch/um/os-Linux/sys-x86_64/registers.c --- 25/arch/um/os-Linux/sys-x86_64/registers.c~uml-factor-out-register-saving-and-restoring 2005-01-09 23:44:06.129231704 -0800 +++ 25-akpm/arch/um/os-Linux/sys-x86_64/registers.c 2005-01-09 23:44:06.137230488 -0800 @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2004 PathScale, Inc + * Licensed under the GPL + */ + +#include +#include +#include +#include "sysdep/ptrace.h" +#include "uml-config.h" +#include "skas_ptregs.h" +#include "registers.h" +#include "user.h" + +/* These are set once at boot time and not changed thereafter */ + +static unsigned long exec_regs[HOST_FRAME_SIZE]; +static unsigned long exec_fp_regs[HOST_FP_SIZE]; + +void init_thread_registers(union uml_pt_regs *to) +{ + memcpy(to->skas.regs, exec_regs, sizeof(to->skas.regs)); + memcpy(to->skas.fp, exec_fp_regs, sizeof(to->skas.fp)); +} + +static int move_registers(int pid, int int_op, int fp_op, + union uml_pt_regs *regs) +{ + if(ptrace(int_op, pid, 0, regs->skas.regs) < 0) + return(-errno); + + if(ptrace(fp_op, pid, 0, regs->skas.fp) < 0) + return(-errno); + + return(0); +} + +void save_registers(int pid, union uml_pt_regs *regs) +{ + int err; + + err = move_registers(pid, PTRACE_GETREGS, PTRACE_GETFPREGS, regs); + if(err) + panic("save_registers - saving registers failed, errno = %d\n", + -err); +} + +void restore_registers(int pid, union uml_pt_regs *regs) +{ + int err; + + err = move_registers(pid, PTRACE_SETREGS, PTRACE_SETFPREGS, regs); + if(err) + panic("restore_registers - saving registers failed, " + "errno = %d\n", -err); +} + +void init_registers(int pid) +{ + int err; + + err = ptrace(PTRACE_GETREGS, pid, 0, exec_regs); + if(err) + panic("check_ptrace : PTRACE_GETREGS failed, errno = %d", + err); + + err = ptrace(PTRACE_GETFPREGS, pid, 0, exec_fp_regs); + if(err) + panic("check_ptrace : PTRACE_GETFPREGS failed, errno = %d", + err); +} + +/* + * 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: + */ _