Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'for-linus-3.6-rc-final' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/uml

Pull UML fixes from Richard Weinberger.

* 'for-linus-3.6-rc-final' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/uml:
um: Preinclude include/linux/kern_levels.h
um: Fix IPC on um
um: kill thread->forking
um: let signal_delivered() do SIGTRAP on singlestepping into handler
um: don't leak floating point state and segment registers on execve()
um: take cleaning singlestep to start_thread()

+54 -107
-9
arch/um/include/asm/processor-generic.h
··· 20 20 21 21 struct thread_struct { 22 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 23 struct pt_regs regs; 32 24 int singlestep_syscall; 33 25 void *fault_addr; ··· 50 58 51 59 #define INIT_THREAD \ 52 60 { \ 53 - .forking = 0, \ 54 61 .regs = EMPTY_REGS, \ 55 62 .fault_addr = NULL, \ 56 63 .prev_sched = NULL, \
-10
arch/um/include/shared/common-offsets.h
··· 7 7 DEFINE(UM_KERN_PAGE_SHIFT, PAGE_SHIFT); 8 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 10 DEFINE(UM_ELF_CLASS, ELF_CLASS); 21 11 DEFINE(UM_ELFCLASS32, ELFCLASS32); 22 12 DEFINE(UM_ELFCLASS64, ELFCLASS64);
+11
arch/um/include/shared/user.h
··· 26 26 extern void panic(const char *fmt, ...) 27 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 40 #ifdef UML_CONFIG_PRINTK 30 41 extern int printk(const char *fmt, ...) 31 42 __attribute__ ((format (printf, 1, 2)));
+7 -20
arch/um/kernel/exec.c
··· 39 39 40 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 43 PT_REGS_IP(regs) = eip; 43 44 PT_REGS_SP(regs) = esp; 45 + current->ptrace &= ~PT_DTRACE; 46 + #ifdef SUBARCH_EXECVE1 47 + SUBARCH_EXECVE1(regs->regs); 48 + #endif 44 49 } 45 50 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, &current->thread.regs); 54 - if (error == 0) { 55 - task_lock(current); 56 - current->ptrace &= ~PT_DTRACE; 57 - #ifdef SUBARCH_EXECVE1 58 - SUBARCH_EXECVE1(&current->thread.regs.regs); 59 - #endif 60 - task_unlock(current); 61 - } 62 - return error; 63 - } 64 51 65 52 long um_execve(const char *file, const char __user *const __user *argv, const char __user *const __user *env) 66 53 { 67 54 long err; 68 55 69 - err = execve1(file, argv, env); 56 + err = do_execve(file, argv, env, &current->thread.regs); 70 57 if (!err) 71 58 UML_LONGJMP(current->thread.exec_buf, 1); 72 59 return err; ··· 68 81 filename = getname(file); 69 82 error = PTR_ERR(filename); 70 83 if (IS_ERR(filename)) goto out; 71 - error = execve1(filename, argv, env); 84 + error = do_execve(filename, argv, env, &current->thread.regs); 72 85 putname(filename); 73 86 out: 74 87 return error;
+4 -4
arch/um/kernel/process.c
··· 181 181 struct pt_regs *regs) 182 182 { 183 183 void (*handler)(void); 184 + int kthread = current->flags & PF_KTHREAD; 184 185 int ret = 0; 185 186 186 187 p->thread = (struct thread_struct) INIT_THREAD; 187 188 188 - if (current->thread.forking) { 189 + if (!kthread) { 189 190 memcpy(&p->thread.regs.regs, &regs->regs, 190 191 sizeof(p->thread.regs.regs)); 191 192 PT_REGS_SET_SYSCALL_RETURN(&p->thread.regs, 0); ··· 196 195 handler = fork_handler; 197 196 198 197 arch_copy_thread(&current->thread.arch, &p->thread.arch); 199 - } 200 - else { 198 + } else { 201 199 get_safe_registers(p->thread.regs.regs.gp, p->thread.regs.regs.fp); 202 200 p->thread.request.u.thread = current->thread.request.u.thread; 203 201 handler = new_thread_handler; ··· 204 204 205 205 new_thread(task_stack_page(p), &p->thread.switch_buf, handler); 206 206 207 - if (current->thread.forking) { 207 + if (!kthread) { 208 208 clear_flushed_tls(p); 209 209 210 210 /*
+5 -1
arch/um/kernel/signal.c
··· 22 22 struct k_sigaction *ka, siginfo_t *info) 23 23 { 24 24 sigset_t *oldset = sigmask_to_save(); 25 + int singlestep = 0; 25 26 unsigned long sp; 26 27 int err; 28 + 29 + if ((current->ptrace & PT_DTRACE) && (current->ptrace & PT_PTRACED)) 30 + singlestep = 1; 27 31 28 32 /* Did we come from a system call? */ 29 33 if (PT_REGS_SYSCALL_NR(regs) >= 0) { ··· 65 61 if (err) 66 62 force_sigsegv(signr, current); 67 63 else 68 - signal_delivered(signr, info, ka, regs, 0); 64 + signal_delivered(signr, info, ka, regs, singlestep); 69 65 } 70 66 71 67 static int kern_do_signal(struct pt_regs *regs)
+12 -12
arch/um/kernel/syscall.c
··· 17 17 18 18 long sys_fork(void) 19 19 { 20 - long ret; 21 - 22 - current->thread.forking = 1; 23 - ret = do_fork(SIGCHLD, UPT_SP(&current->thread.regs.regs), 20 + return do_fork(SIGCHLD, UPT_SP(&current->thread.regs.regs), 24 21 &current->thread.regs, 0, NULL, NULL); 25 - current->thread.forking = 0; 26 - return ret; 27 22 } 28 23 29 24 long sys_vfork(void) 30 25 { 31 - long ret; 32 - 33 - current->thread.forking = 1; 34 - ret = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, 26 + return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, 35 27 UPT_SP(&current->thread.regs.regs), 36 28 &current->thread.regs, 0, NULL, NULL); 37 - current->thread.forking = 0; 38 - return ret; 29 + } 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(&current->thread.regs.regs); 36 + 37 + return do_fork(clone_flags, newsp, &current->thread.regs, 0, parent_tid, 38 + child_tid); 39 39 } 40 40 41 41 long old_mmap(unsigned long addr, unsigned long len,
+1 -1
arch/um/scripts/Makefile.rules
··· 8 8 USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file)) 9 9 10 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 13 # These are like USER_OBJS but filter USER_CFLAGS through unprofile instead of 14 14 # using it directly.
+1
arch/x86/um/Kconfig
··· 21 21 config X86_32 22 22 def_bool !64BIT 23 23 select HAVE_AOUT 24 + select ARCH_WANT_IPC_PARSE_VERSION 24 25 25 26 config X86_64 26 27 def_bool 64BIT
-3
arch/x86/um/shared/sysdep/kernel-offsets.h
··· 7 7 #define DEFINE(sym, val) \ 8 8 asm volatile("\n->" #sym " %0 " #val : : "i" (val)) 9 9 10 - #define STR(x) #x 11 - #define DEFINE_STR(sym, val) asm volatile("\n->" #sym " " STR(val) " " #val: : ) 12 - 13 10 #define BLANK() asm volatile("\n->" : : ) 14 11 15 12 #define OFFSET(sym, str, mem) \
+2
arch/x86/um/shared/sysdep/syscalls.h
··· 1 + extern long sys_clone(unsigned long clone_flags, unsigned long newsp, 2 + void __user *parent_tid, void __user *child_tid); 1 3 #ifdef __i386__ 2 4 #include "syscalls_32.h" 3 5 #else
-6
arch/x86/um/signal.c
··· 416 416 PT_REGS_AX(regs) = (unsigned long) sig; 417 417 PT_REGS_DX(regs) = (unsigned long) 0; 418 418 PT_REGS_CX(regs) = (unsigned long) 0; 419 - 420 - if ((current->ptrace & PT_DTRACE) && (current->ptrace & PT_PTRACED)) 421 - ptrace_notify(SIGTRAP); 422 419 return 0; 423 420 } 424 421 ··· 463 466 PT_REGS_AX(regs) = (unsigned long) sig; 464 467 PT_REGS_DX(regs) = (unsigned long) &frame->info; 465 468 PT_REGS_CX(regs) = (unsigned long) &frame->uc; 466 - 467 - if ((current->ptrace & PT_DTRACE) && (current->ptrace & PT_PTRACED)) 468 - ptrace_notify(SIGTRAP); 469 469 return 0; 470 470 } 471 471
+1 -1
arch/x86/um/sys_call_table_32.c
··· 28 28 #define ptregs_execve sys_execve 29 29 #define ptregs_iopl sys_iopl 30 30 #define ptregs_vm86old sys_vm86old 31 - #define ptregs_clone sys_clone 31 + #define ptregs_clone i386_clone 32 32 #define ptregs_vm86 sys_vm86 33 33 #define ptregs_sigaltstack sys_sigaltstack 34 34 #define ptregs_vfork sys_vfork
+7 -20
arch/x86/um/syscalls_32.c
··· 3 3 * Licensed under the GPL 4 4 */ 5 5 6 - #include "linux/sched.h" 7 - #include "linux/shm.h" 8 - #include "linux/ipc.h" 9 - #include "linux/syscalls.h" 10 - #include "asm/mman.h" 11 - #include "asm/uaccess.h" 12 - #include "asm/unistd.h" 6 + #include <linux/syscalls.h> 7 + #include <sysdep/syscalls.h> 13 8 14 9 /* 15 10 * The prototype on i386 is: 16 11 * 17 - * int clone(int flags, void * child_stack, int * parent_tidptr, struct user_desc * newtls, int * child_tidptr) 12 + * int clone(int flags, void * child_stack, int * parent_tidptr, struct user_desc * newtls 18 13 * 19 14 * and the "newtls" arg. on i386 is read by copy_thread directly from the 20 15 * register saved on the stack. 21 16 */ 22 - long sys_clone(unsigned long clone_flags, unsigned long newsp, 23 - int __user *parent_tid, void *newtls, int __user *child_tid) 17 + long i386_clone(unsigned long clone_flags, unsigned long newsp, 18 + int __user *parent_tid, void *newtls, int __user *child_tid) 24 19 { 25 - long ret; 26 - 27 - if (!newsp) 28 - newsp = UPT_SP(&current->thread.regs.regs); 29 - 30 - current->thread.forking = 1; 31 - ret = do_fork(clone_flags, newsp, &current->thread.regs, 0, parent_tid, 32 - child_tid); 33 - current->thread.forking = 0; 34 - return ret; 20 + return sys_clone(clone_flags, newsp, parent_tid, child_tid); 35 21 } 22 + 36 23 37 24 long sys_sigaction(int sig, const struct old_sigaction __user *act, 38 25 struct old_sigaction __user *oact)
+3 -20
arch/x86/um/syscalls_64.c
··· 5 5 * Licensed under the GPL 6 6 */ 7 7 8 - #include "linux/linkage.h" 9 - #include "linux/personality.h" 10 - #include "linux/utsname.h" 11 - #include "asm/prctl.h" /* XXX This should get the constants from libc */ 12 - #include "asm/uaccess.h" 13 - #include "os.h" 8 + #include <linux/sched.h> 9 + #include <asm/prctl.h> /* XXX This should get the constants from libc */ 10 + #include <os.h> 14 11 15 12 long arch_prctl(struct task_struct *task, int code, unsigned long __user *addr) 16 13 { ··· 74 77 long sys_arch_prctl(int code, unsigned long addr) 75 78 { 76 79 return arch_prctl(current, code, (unsigned long __user *) addr); 77 - } 78 - 79 - long sys_clone(unsigned long clone_flags, unsigned long newsp, 80 - void __user *parent_tid, void __user *child_tid) 81 - { 82 - long ret; 83 - 84 - if (!newsp) 85 - newsp = UPT_SP(&current->thread.regs.regs); 86 - current->thread.forking = 1; 87 - ret = do_fork(clone_flags, newsp, &current->thread.regs, 0, parent_tid, 88 - child_tid); 89 - current->thread.forking = 0; 90 - return ret; 91 80 } 92 81 93 82 void arch_switch_to(struct task_struct *to)