diff options
Diffstat (limited to 'arch/um')
| -rw-r--r-- | arch/um/drivers/mconsole_kern.c | 1 | ||||
| -rw-r--r-- | arch/um/include/asm/processor-generic.h | 9 | ||||
| -rw-r--r-- | arch/um/include/shared/common-offsets.h | 10 | ||||
| -rw-r--r-- | arch/um/include/shared/user.h | 11 | ||||
| -rw-r--r-- | arch/um/kernel/exec.c | 25 | ||||
| -rw-r--r-- | arch/um/kernel/process.c | 8 | ||||
| -rw-r--r-- | arch/um/kernel/signal.c | 6 | ||||
| -rw-r--r-- | arch/um/kernel/syscall.c | 24 | ||||
| -rw-r--r-- | arch/um/os-Linux/time.c | 2 | ||||
| -rw-r--r-- | arch/um/scripts/Makefile.rules | 2 |
10 files changed, 41 insertions, 57 deletions
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c index 664a60e8dfb4..c17de0db6736 100644 --- a/arch/um/drivers/mconsole_kern.c +++ b/arch/um/drivers/mconsole_kern.c | |||
| @@ -705,6 +705,7 @@ static void stack_proc(void *arg) | |||
| 705 | struct task_struct *from = current, *to = arg; | 705 | struct task_struct *from = current, *to = arg; |
| 706 | 706 | ||
| 707 | to->thread.saved_task = from; | 707 | to->thread.saved_task = from; |
| 708 | rcu_switch(from, to); | ||
| 708 | switch_to(from, to, from); | 709 | switch_to(from, to, from); |
| 709 | } | 710 | } |
| 710 | 711 | ||
diff --git a/arch/um/include/asm/processor-generic.h b/arch/um/include/asm/processor-generic.h index 69f1c57a8d0d..33a6a2423bd2 100644 --- a/arch/um/include/asm/processor-generic.h +++ b/arch/um/include/asm/processor-generic.h | |||
| @@ -20,14 +20,6 @@ struct mm_struct; | |||
| 20 | 20 | ||
| 21 | struct thread_struct { | 21 | struct thread_struct { |
| 22 | struct task_struct *saved_task; | 22 | struct task_struct *saved_task; |
| 23 | /* | ||
| 24 | * This flag is set to 1 before calling do_fork (and analyzed in | ||
| 25 | * copy_thread) to mark that we are begin called from userspace (fork / | ||
| 26 | * vfork / clone), and reset to 0 after. It is left to 0 when called | ||
| 27 | * from kernelspace (i.e. kernel_thread() or fork_idle(), | ||
| 28 | * as of 2.6.11). | ||
| 29 | */ | ||
| 30 | int forking; | ||
| 31 | struct pt_regs regs; | 23 | struct pt_regs regs; |
| 32 | int singlestep_syscall; | 24 | int singlestep_syscall; |
| 33 | void *fault_addr; | 25 | void *fault_addr; |
| @@ -58,7 +50,6 @@ struct thread_struct { | |||
| 58 | 50 | ||
| 59 | #define INIT_THREAD \ | 51 | #define INIT_THREAD \ |
| 60 | { \ | 52 | { \ |
| 61 | .forking = 0, \ | ||
| 62 | .regs = EMPTY_REGS, \ | 53 | .regs = EMPTY_REGS, \ |
| 63 | .fault_addr = NULL, \ | 54 | .fault_addr = NULL, \ |
| 64 | .prev_sched = NULL, \ | 55 | .prev_sched = NULL, \ |
diff --git a/arch/um/include/shared/common-offsets.h b/arch/um/include/shared/common-offsets.h index 40db8f71deae..2df313b6a586 100644 --- a/arch/um/include/shared/common-offsets.h +++ b/arch/um/include/shared/common-offsets.h | |||
| @@ -7,16 +7,6 @@ DEFINE(UM_KERN_PAGE_MASK, PAGE_MASK); | |||
| 7 | DEFINE(UM_KERN_PAGE_SHIFT, PAGE_SHIFT); | 7 | DEFINE(UM_KERN_PAGE_SHIFT, PAGE_SHIFT); |
| 8 | DEFINE(UM_NSEC_PER_SEC, NSEC_PER_SEC); | 8 | DEFINE(UM_NSEC_PER_SEC, NSEC_PER_SEC); |
| 9 | 9 | ||
| 10 | DEFINE_STR(UM_KERN_EMERG, KERN_EMERG); | ||
| 11 | DEFINE_STR(UM_KERN_ALERT, KERN_ALERT); | ||
| 12 | DEFINE_STR(UM_KERN_CRIT, KERN_CRIT); | ||
| 13 | DEFINE_STR(UM_KERN_ERR, KERN_ERR); | ||
| 14 | DEFINE_STR(UM_KERN_WARNING, KERN_WARNING); | ||
| 15 | DEFINE_STR(UM_KERN_NOTICE, KERN_NOTICE); | ||
| 16 | DEFINE_STR(UM_KERN_INFO, KERN_INFO); | ||
| 17 | DEFINE_STR(UM_KERN_DEBUG, KERN_DEBUG); | ||
| 18 | DEFINE_STR(UM_KERN_CONT, KERN_CONT); | ||
| 19 | |||
| 20 | DEFINE(UM_ELF_CLASS, ELF_CLASS); | 10 | DEFINE(UM_ELF_CLASS, ELF_CLASS); |
| 21 | DEFINE(UM_ELFCLASS32, ELFCLASS32); | 11 | DEFINE(UM_ELFCLASS32, ELFCLASS32); |
| 22 | DEFINE(UM_ELFCLASS64, ELFCLASS64); | 12 | DEFINE(UM_ELFCLASS64, ELFCLASS64); |
diff --git a/arch/um/include/shared/user.h b/arch/um/include/shared/user.h index 4fa82c055aab..cef068563336 100644 --- a/arch/um/include/shared/user.h +++ b/arch/um/include/shared/user.h | |||
| @@ -26,6 +26,17 @@ | |||
| 26 | extern void panic(const char *fmt, ...) | 26 | extern void panic(const char *fmt, ...) |
| 27 | __attribute__ ((format (printf, 1, 2))); | 27 | __attribute__ ((format (printf, 1, 2))); |
| 28 | 28 | ||
| 29 | /* Requires preincluding include/linux/kern_levels.h */ | ||
| 30 | #define UM_KERN_EMERG KERN_EMERG | ||
| 31 | #define UM_KERN_ALERT KERN_ALERT | ||
| 32 | #define UM_KERN_CRIT KERN_CRIT | ||
| 33 | #define UM_KERN_ERR KERN_ERR | ||
| 34 | #define UM_KERN_WARNING KERN_WARNING | ||
| 35 | #define UM_KERN_NOTICE KERN_NOTICE | ||
| 36 | #define UM_KERN_INFO KERN_INFO | ||
| 37 | #define UM_KERN_DEBUG KERN_DEBUG | ||
| 38 | #define UM_KERN_CONT KERN_CONT | ||
| 39 | |||
| 29 | #ifdef UML_CONFIG_PRINTK | 40 | #ifdef UML_CONFIG_PRINTK |
| 30 | extern int printk(const char *fmt, ...) | 41 | extern int printk(const char *fmt, ...) |
| 31 | __attribute__ ((format (printf, 1, 2))); | 42 | __attribute__ ((format (printf, 1, 2))); |
diff --git a/arch/um/kernel/exec.c b/arch/um/kernel/exec.c index 6cade9366364..8c82786da823 100644 --- a/arch/um/kernel/exec.c +++ b/arch/um/kernel/exec.c | |||
| @@ -39,34 +39,21 @@ void flush_thread(void) | |||
| 39 | 39 | ||
| 40 | void start_thread(struct pt_regs *regs, unsigned long eip, unsigned long esp) | 40 | void start_thread(struct pt_regs *regs, unsigned long eip, unsigned long esp) |
| 41 | { | 41 | { |
| 42 | get_safe_registers(regs->regs.gp, regs->regs.fp); | ||
| 42 | PT_REGS_IP(regs) = eip; | 43 | PT_REGS_IP(regs) = eip; |
| 43 | PT_REGS_SP(regs) = esp; | 44 | PT_REGS_SP(regs) = esp; |
| 44 | } | 45 | current->ptrace &= ~PT_DTRACE; |
| 45 | EXPORT_SYMBOL(start_thread); | ||
| 46 | |||
| 47 | static long execve1(const char *file, | ||
| 48 | const char __user *const __user *argv, | ||
| 49 | const char __user *const __user *env) | ||
| 50 | { | ||
| 51 | long error; | ||
| 52 | |||
| 53 | error = do_execve(file, argv, env, ¤t->thread.regs); | ||
| 54 | if (error == 0) { | ||
| 55 | task_lock(current); | ||
| 56 | current->ptrace &= ~PT_DTRACE; | ||
| 57 | #ifdef SUBARCH_EXECVE1 | 46 | #ifdef SUBARCH_EXECVE1 |
| 58 | SUBARCH_EXECVE1(¤t->thread.regs.regs); | 47 | SUBARCH_EXECVE1(regs->regs); |
| 59 | #endif | 48 | #endif |
| 60 | task_unlock(current); | ||
| 61 | } | ||
| 62 | return error; | ||
| 63 | } | 49 | } |
| 50 | EXPORT_SYMBOL(start_thread); | ||
| 64 | 51 | ||
| 65 | long um_execve(const char *file, const char __user *const __user *argv, const char __user *const __user *env) | 52 | long um_execve(const char *file, const char __user *const __user *argv, const char __user *const __user *env) |
| 66 | { | 53 | { |
| 67 | long err; | 54 | long err; |
| 68 | 55 | ||
| 69 | err = execve1(file, argv, env); | 56 | err = do_execve(file, argv, env, ¤t->thread.regs); |
| 70 | if (!err) | 57 | if (!err) |
| 71 | UML_LONGJMP(current->thread.exec_buf, 1); | 58 | UML_LONGJMP(current->thread.exec_buf, 1); |
| 72 | return err; | 59 | return err; |
| @@ -81,7 +68,7 @@ long sys_execve(const char __user *file, const char __user *const __user *argv, | |||
| 81 | filename = getname(file); | 68 | filename = getname(file); |
| 82 | error = PTR_ERR(filename); | 69 | error = PTR_ERR(filename); |
| 83 | if (IS_ERR(filename)) goto out; | 70 | if (IS_ERR(filename)) goto out; |
| 84 | error = execve1(filename, argv, env); | 71 | error = do_execve(filename, argv, env, ¤t->thread.regs); |
| 85 | putname(filename); | 72 | putname(filename); |
| 86 | out: | 73 | out: |
| 87 | return error; | 74 | return error; |
diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index 57fc7028714a..c5f5afa50745 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c | |||
| @@ -181,11 +181,12 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, | |||
| 181 | struct pt_regs *regs) | 181 | struct pt_regs *regs) |
| 182 | { | 182 | { |
| 183 | void (*handler)(void); | 183 | void (*handler)(void); |
| 184 | int kthread = current->flags & PF_KTHREAD; | ||
| 184 | int ret = 0; | 185 | int ret = 0; |
| 185 | 186 | ||
| 186 | p->thread = (struct thread_struct) INIT_THREAD; | 187 | p->thread = (struct thread_struct) INIT_THREAD; |
| 187 | 188 | ||
| 188 | if (current->thread.forking) { | 189 | if (!kthread) { |
| 189 | memcpy(&p->thread.regs.regs, ®s->regs, | 190 | memcpy(&p->thread.regs.regs, ®s->regs, |
| 190 | sizeof(p->thread.regs.regs)); | 191 | sizeof(p->thread.regs.regs)); |
| 191 | PT_REGS_SET_SYSCALL_RETURN(&p->thread.regs, 0); | 192 | PT_REGS_SET_SYSCALL_RETURN(&p->thread.regs, 0); |
| @@ -195,8 +196,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, | |||
| 195 | handler = fork_handler; | 196 | handler = fork_handler; |
| 196 | 197 | ||
| 197 | arch_copy_thread(¤t->thread.arch, &p->thread.arch); | 198 | arch_copy_thread(¤t->thread.arch, &p->thread.arch); |
| 198 | } | 199 | } else { |
| 199 | else { | ||
| 200 | get_safe_registers(p->thread.regs.regs.gp, p->thread.regs.regs.fp); | 200 | get_safe_registers(p->thread.regs.regs.gp, p->thread.regs.regs.fp); |
| 201 | p->thread.request.u.thread = current->thread.request.u.thread; | 201 | p->thread.request.u.thread = current->thread.request.u.thread; |
| 202 | handler = new_thread_handler; | 202 | handler = new_thread_handler; |
| @@ -204,7 +204,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, | |||
| 204 | 204 | ||
| 205 | new_thread(task_stack_page(p), &p->thread.switch_buf, handler); | 205 | new_thread(task_stack_page(p), &p->thread.switch_buf, handler); |
| 206 | 206 | ||
| 207 | if (current->thread.forking) { | 207 | if (!kthread) { |
| 208 | clear_flushed_tls(p); | 208 | clear_flushed_tls(p); |
| 209 | 209 | ||
| 210 | /* | 210 | /* |
diff --git a/arch/um/kernel/signal.c b/arch/um/kernel/signal.c index 7362d58efc29..cc9c2350e417 100644 --- a/arch/um/kernel/signal.c +++ b/arch/um/kernel/signal.c | |||
| @@ -22,9 +22,13 @@ static void handle_signal(struct pt_regs *regs, unsigned long signr, | |||
| 22 | struct k_sigaction *ka, siginfo_t *info) | 22 | struct k_sigaction *ka, siginfo_t *info) |
| 23 | { | 23 | { |
| 24 | sigset_t *oldset = sigmask_to_save(); | 24 | sigset_t *oldset = sigmask_to_save(); |
| 25 | int singlestep = 0; | ||
| 25 | unsigned long sp; | 26 | unsigned long sp; |
| 26 | int err; | 27 | int err; |
| 27 | 28 | ||
| 29 | if ((current->ptrace & PT_DTRACE) && (current->ptrace & PT_PTRACED)) | ||
| 30 | singlestep = 1; | ||
| 31 | |||
| 28 | /* Did we come from a system call? */ | 32 | /* Did we come from a system call? */ |
| 29 | if (PT_REGS_SYSCALL_NR(regs) >= 0) { | 33 | if (PT_REGS_SYSCALL_NR(regs) >= 0) { |
| 30 | /* If so, check system call restarting.. */ | 34 | /* If so, check system call restarting.. */ |
| @@ -61,7 +65,7 @@ static void handle_signal(struct pt_regs *regs, unsigned long signr, | |||
| 61 | if (err) | 65 | if (err) |
| 62 | force_sigsegv(signr, current); | 66 | force_sigsegv(signr, current); |
| 63 | else | 67 | else |
| 64 | signal_delivered(signr, info, ka, regs, 0); | 68 | signal_delivered(signr, info, ka, regs, singlestep); |
| 65 | } | 69 | } |
| 66 | 70 | ||
| 67 | static int kern_do_signal(struct pt_regs *regs) | 71 | static int kern_do_signal(struct pt_regs *regs) |
diff --git a/arch/um/kernel/syscall.c b/arch/um/kernel/syscall.c index f958cb876ee3..a4c6d8eee74c 100644 --- a/arch/um/kernel/syscall.c +++ b/arch/um/kernel/syscall.c | |||
| @@ -17,25 +17,25 @@ | |||
| 17 | 17 | ||
| 18 | long sys_fork(void) | 18 | long sys_fork(void) |
| 19 | { | 19 | { |
| 20 | long ret; | 20 | return do_fork(SIGCHLD, UPT_SP(¤t->thread.regs.regs), |
| 21 | |||
| 22 | current->thread.forking = 1; | ||
| 23 | ret = do_fork(SIGCHLD, UPT_SP(¤t->thread.regs.regs), | ||
| 24 | ¤t->thread.regs, 0, NULL, NULL); | 21 | ¤t->thread.regs, 0, NULL, NULL); |
| 25 | current->thread.forking = 0; | ||
| 26 | return ret; | ||
| 27 | } | 22 | } |
| 28 | 23 | ||
| 29 | long sys_vfork(void) | 24 | long sys_vfork(void) |
| 30 | { | 25 | { |
| 31 | long ret; | 26 | return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, |
| 32 | |||
| 33 | current->thread.forking = 1; | ||
| 34 | ret = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, | ||
| 35 | UPT_SP(¤t->thread.regs.regs), | 27 | UPT_SP(¤t->thread.regs.regs), |
| 36 | ¤t->thread.regs, 0, NULL, NULL); | 28 | ¤t->thread.regs, 0, NULL, NULL); |
| 37 | current->thread.forking = 0; | 29 | } |
| 38 | return ret; | 30 | |
| 31 | long sys_clone(unsigned long clone_flags, unsigned long newsp, | ||
| 32 | void __user *parent_tid, void __user *child_tid) | ||
| 33 | { | ||
| 34 | if (!newsp) | ||
| 35 | newsp = UPT_SP(¤t->thread.regs.regs); | ||
| 36 | |||
| 37 | return do_fork(clone_flags, newsp, ¤t->thread.regs, 0, parent_tid, | ||
| 38 | child_tid); | ||
| 39 | } | 39 | } |
| 40 | 40 | ||
| 41 | long old_mmap(unsigned long addr, unsigned long len, | 41 | long old_mmap(unsigned long addr, unsigned long len, |
diff --git a/arch/um/os-Linux/time.c b/arch/um/os-Linux/time.c index f60238559af3..0748fe0c8a73 100644 --- a/arch/um/os-Linux/time.c +++ b/arch/um/os-Linux/time.c | |||
| @@ -114,7 +114,7 @@ static void deliver_alarm(void) | |||
| 114 | skew += this_tick - last_tick; | 114 | skew += this_tick - last_tick; |
| 115 | 115 | ||
| 116 | while (skew >= one_tick) { | 116 | while (skew >= one_tick) { |
| 117 | alarm_handler(SIGVTALRM, NULL); | 117 | alarm_handler(SIGVTALRM, NULL, NULL); |
| 118 | skew -= one_tick; | 118 | skew -= one_tick; |
| 119 | } | 119 | } |
| 120 | 120 | ||
diff --git a/arch/um/scripts/Makefile.rules b/arch/um/scripts/Makefile.rules index d50270d26b42..15889df9b466 100644 --- a/arch/um/scripts/Makefile.rules +++ b/arch/um/scripts/Makefile.rules | |||
| @@ -8,7 +8,7 @@ USER_OBJS += $(filter %_user.o,$(obj-y) $(obj-m) $(USER_SINGLE_OBJS)) | |||
| 8 | USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file)) | 8 | USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file)) |
| 9 | 9 | ||
| 10 | $(USER_OBJS:.o=.%): \ | 10 | $(USER_OBJS:.o=.%): \ |
| 11 | c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) -include user.h $(CFLAGS_$(basetarget).o) | 11 | c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) -include $(srctree)/include/linux/kern_levels.h -include user.h $(CFLAGS_$(basetarget).o) |
| 12 | 12 | ||
| 13 | # These are like USER_OBJS but filter USER_CFLAGS through unprofile instead of | 13 | # These are like USER_OBJS but filter USER_CFLAGS through unprofile instead of |
| 14 | # using it directly. | 14 | # using it directly. |
