Skip to content

Commit

Permalink
um: kill thread->forking
Browse files Browse the repository at this point in the history
we only use that to tell copy_thread() done by syscall from that
done by kernel_thread().  However, it's easier to do simply by
checking PF_KTHREAD in thread flags.

Merge sys_clone() guts for 32bit and 64bit, while we are at it...

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
  • Loading branch information
Al Viro authored and Richard Weinberger committed Sep 27, 2012
1 parent f9a38ea commit d2ce4e9
Show file tree
Hide file tree
Showing 7 changed files with 29 additions and 66 deletions.
9 changes: 0 additions & 9 deletions arch/um/include/asm/processor-generic.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,6 @@ struct mm_struct;

struct thread_struct {
struct task_struct *saved_task;
/*
* This flag is set to 1 before calling do_fork (and analyzed in
* copy_thread) to mark that we are begin called from userspace (fork /
* vfork / clone), and reset to 0 after. It is left to 0 when called
* from kernelspace (i.e. kernel_thread() or fork_idle(),
* as of 2.6.11).
*/
int forking;
struct pt_regs regs;
int singlestep_syscall;
void *fault_addr;
Expand Down Expand Up @@ -58,7 +50,6 @@ struct thread_struct {

#define INIT_THREAD \
{ \
.forking = 0, \
.regs = EMPTY_REGS, \
.fault_addr = NULL, \
.prev_sched = NULL, \
Expand Down
8 changes: 4 additions & 4 deletions arch/um/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -181,11 +181,12 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
struct pt_regs *regs)
{
void (*handler)(void);
int kthread = current->flags & PF_KTHREAD;
int ret = 0;

p->thread = (struct thread_struct) INIT_THREAD;

if (current->thread.forking) {
if (!kthread) {
memcpy(&p->thread.regs.regs, &regs->regs,
sizeof(p->thread.regs.regs));
PT_REGS_SET_SYSCALL_RETURN(&p->thread.regs, 0);
Expand All @@ -195,16 +196,15 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
handler = fork_handler;

arch_copy_thread(&current->thread.arch, &p->thread.arch);
}
else {
} else {
get_safe_registers(p->thread.regs.regs.gp, p->thread.regs.regs.fp);
p->thread.request.u.thread = current->thread.request.u.thread;
handler = new_thread_handler;
}

new_thread(task_stack_page(p), &p->thread.switch_buf, handler);

if (current->thread.forking) {
if (!kthread) {
clear_flushed_tls(p);

/*
Expand Down
24 changes: 12 additions & 12 deletions arch/um/kernel/syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,25 @@

long sys_fork(void)
{
long ret;

current->thread.forking = 1;
ret = do_fork(SIGCHLD, UPT_SP(&current->thread.regs.regs),
return do_fork(SIGCHLD, UPT_SP(&current->thread.regs.regs),
&current->thread.regs, 0, NULL, NULL);
current->thread.forking = 0;
return ret;
}

long sys_vfork(void)
{
long ret;

current->thread.forking = 1;
ret = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD,
return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD,
UPT_SP(&current->thread.regs.regs),
&current->thread.regs, 0, NULL, NULL);
current->thread.forking = 0;
return ret;
}

long sys_clone(unsigned long clone_flags, unsigned long newsp,
void __user *parent_tid, void __user *child_tid)
{
if (!newsp)
newsp = UPT_SP(&current->thread.regs.regs);

return do_fork(clone_flags, newsp, &current->thread.regs, 0, parent_tid,
child_tid);
}

long old_mmap(unsigned long addr, unsigned long len,
Expand Down
2 changes: 2 additions & 0 deletions arch/x86/um/shared/sysdep/syscalls.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
extern long sys_clone(unsigned long clone_flags, unsigned long newsp,
void __user *parent_tid, void __user *child_tid);
#ifdef __i386__
#include "syscalls_32.h"
#else
Expand Down
2 changes: 1 addition & 1 deletion arch/x86/um/sys_call_table_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
#define ptregs_execve sys_execve
#define ptregs_iopl sys_iopl
#define ptregs_vm86old sys_vm86old
#define ptregs_clone sys_clone
#define ptregs_clone i386_clone
#define ptregs_vm86 sys_vm86
#define ptregs_sigaltstack sys_sigaltstack
#define ptregs_vfork sys_vfork
Expand Down
27 changes: 7 additions & 20 deletions arch/x86/um/syscalls_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,37 +3,24 @@
* Licensed under the GPL
*/

#include "linux/sched.h"
#include "linux/shm.h"
#include "linux/ipc.h"
#include "linux/syscalls.h"
#include "asm/mman.h"
#include "asm/uaccess.h"
#include "asm/unistd.h"
#include <linux/syscalls.h>
#include <sysdep/syscalls.h>

/*
* The prototype on i386 is:
*
* int clone(int flags, void * child_stack, int * parent_tidptr, struct user_desc * newtls, int * child_tidptr)
* int clone(int flags, void * child_stack, int * parent_tidptr, struct user_desc * newtls
*
* and the "newtls" arg. on i386 is read by copy_thread directly from the
* register saved on the stack.
*/
long sys_clone(unsigned long clone_flags, unsigned long newsp,
int __user *parent_tid, void *newtls, int __user *child_tid)
long i386_clone(unsigned long clone_flags, unsigned long newsp,
int __user *parent_tid, void *newtls, int __user *child_tid)
{
long ret;

if (!newsp)
newsp = UPT_SP(&current->thread.regs.regs);

current->thread.forking = 1;
ret = do_fork(clone_flags, newsp, &current->thread.regs, 0, parent_tid,
child_tid);
current->thread.forking = 0;
return ret;
return sys_clone(clone_flags, newsp, parent_tid, child_tid);
}


long sys_sigaction(int sig, const struct old_sigaction __user *act,
struct old_sigaction __user *oact)
{
Expand Down
23 changes: 3 additions & 20 deletions arch/x86/um/syscalls_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,9 @@
* Licensed under the GPL
*/

#include "linux/linkage.h"
#include "linux/personality.h"
#include "linux/utsname.h"
#include "asm/prctl.h" /* XXX This should get the constants from libc */
#include "asm/uaccess.h"
#include "os.h"
#include <linux/sched.h>
#include <asm/prctl.h> /* XXX This should get the constants from libc */
#include <os.h>

long arch_prctl(struct task_struct *task, int code, unsigned long __user *addr)
{
Expand Down Expand Up @@ -79,20 +76,6 @@ long sys_arch_prctl(int code, unsigned long addr)
return arch_prctl(current, code, (unsigned long __user *) addr);
}

long sys_clone(unsigned long clone_flags, unsigned long newsp,
void __user *parent_tid, void __user *child_tid)
{
long ret;

if (!newsp)
newsp = UPT_SP(&current->thread.regs.regs);
current->thread.forking = 1;
ret = do_fork(clone_flags, newsp, &current->thread.regs, 0, parent_tid,
child_tid);
current->thread.forking = 0;
return ret;
}

void arch_switch_to(struct task_struct *to)
{
if ((to->thread.arch.fs == 0) || (to->mm == NULL))
Expand Down

0 comments on commit d2ce4e9

Please sign in to comment.