Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 340306
b: refs/heads/master
c: ea4a1da
h: refs/heads/master
v: v3
  • Loading branch information
Al Viro committed Nov 1, 2012
1 parent b638142 commit 3c6f5fc
Show file tree
Hide file tree
Showing 14 changed files with 111 additions and 93 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 71915d21e59c153c1202e3198916817c2d18da32
refs/heads/master: ea4a1da9b2e6f419526b5fde15cd5563096368eb
2 changes: 0 additions & 2 deletions trunk/arch/h8300/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ config H8300
select GENERIC_IRQ_SHOW
select GENERIC_CPU_DEVICES
select MODULES_USE_ELF_RELA
select GENERIC_KERNEL_THREAD
select GENERIC_KERNEL_EXECVE

config SYMBOL_PREFIX
string
Expand Down
2 changes: 2 additions & 0 deletions trunk/arch/h8300/include/asm/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ static inline void release_thread(struct task_struct *dead_task)
{
}

extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);

/*
* Free current thread data structures etc..
*/
Expand Down
2 changes: 0 additions & 2 deletions trunk/arch/h8300/include/asm/ptrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,6 @@ struct pt_regs {
#define user_mode(regs) (!((regs)->ccr & PS_S))
#define instruction_pointer(regs) ((regs)->pc)
#define profile_pc(regs) instruction_pointer(regs)
#define current_pt_regs() ((struct pt_regs *) \
(THREAD_SIZE + (unsigned long)current_thread_info()) - 1)
#endif /* __KERNEL__ */
#endif /* __ASSEMBLY__ */
#endif /* _H8300_PTRACE_H */
1 change: 0 additions & 1 deletion trunk/arch/h8300/include/asm/unistd.h
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,6 @@
#define __ARCH_WANT_SYS_SIGPROCMASK
#define __ARCH_WANT_SYS_RT_SIGACTION
#define __ARCH_WANT_SYS_RT_SIGSUSPEND
#define __ARCH_WANT_SYS_EXECVE

/*
* "Conditional" syscalls
Expand Down
9 changes: 0 additions & 9 deletions trunk/arch/h8300/kernel/entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,6 @@ INTERRUPTS = 128
.globl SYMBOL_NAME(system_call)
.globl SYMBOL_NAME(ret_from_exception)
.globl SYMBOL_NAME(ret_from_fork)
.globl SYMBOL_NAME(ret_from_kernel_thread)
.globl SYMBOL_NAME(ret_from_interrupt)
.globl SYMBOL_NAME(interrupt_redirect_table)
.globl SYMBOL_NAME(sw_ksp),SYMBOL_NAME(sw_usp)
Expand Down Expand Up @@ -331,14 +330,6 @@ SYMBOL_NAME_LABEL(ret_from_fork)
jsr @SYMBOL_NAME(schedule_tail)
jmp @SYMBOL_NAME(ret_from_exception)

SYMBOL_NAME_LABEL(ret_from_kernel_thread)
mov.l er2,er0
jsr @SYMBOL_NAME(schedule_tail)
mov.l @(LER4:16,sp),er0
mov.l @(LER5:16,sp),er1
jsr @er1
jmp @SYMBOL_NAME(ret_from_exception)

SYMBOL_NAME_LABEL(resume)
/*
* Beware - when entering resume, offset of tss is in d1,
Expand Down
1 change: 1 addition & 0 deletions trunk/arch/h8300/kernel/h8300_ksyms.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ EXPORT_SYMBOL(strncmp);

EXPORT_SYMBOL(ip_fast_csum);

EXPORT_SYMBOL(kernel_thread);
EXPORT_SYMBOL(enable_irq);
EXPORT_SYMBOL(disable_irq);

Expand Down
62 changes: 54 additions & 8 deletions trunk/arch/h8300/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ void (*pm_power_off)(void) = NULL;
EXPORT_SYMBOL(pm_power_off);

asmlinkage void ret_from_fork(void);
asmlinkage void ret_from_kernel_thread(void);

/*
* The idle loop on an H8/300..
Expand Down Expand Up @@ -123,6 +122,39 @@ void show_regs(struct pt_regs * regs)
printk("\n");
}

/*
* Create a kernel thread
*/
int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
{
long retval;
long clone_arg;
mm_segment_t fs;

fs = get_fs();
set_fs (KERNEL_DS);
clone_arg = flags | CLONE_VM;
__asm__("mov.l sp,er3\n\t"
"sub.l er2,er2\n\t"
"mov.l %2,er1\n\t"
"mov.l %1,er0\n\t"
"trapa #0\n\t"
"cmp.l sp,er3\n\t"
"beq 1f\n\t"
"mov.l %4,er0\n\t"
"mov.l %3,er1\n\t"
"jsr @er1\n\t"
"mov.l %5,er0\n\t"
"trapa #0\n"
"1:\n\t"
"mov.l er0,%0"
:"=r"(retval)
:"i"(__NR_clone),"g"(clone_arg),"g"(fn),"g"(arg),"i"(__NR_exit)
:"er0","er1","er2","er3");
set_fs (fs);
return retval;
}

void flush_thread(void)
{
}
Expand Down Expand Up @@ -166,13 +198,6 @@ int copy_thread(unsigned long clone_flags,

childregs = (struct pt_regs *) (THREAD_SIZE + task_stack_page(p)) - 1;

if (unlikely(p->flags & PF_KTHREAD)) {
memset(childregs, 0, sizeof(struct pt_regs));
childregs->retpc = (unsigned long) ret_from_kernel_thread;
childregs->er4 = topstk; /* arg */
childregs->er5 = usp; /* fn */
p->thread.ksp = (unsigned long)childregs;
}
*childregs = *regs;
childregs->retpc = (unsigned long) ret_from_fork;
childregs->er0 = 0;
Expand All @@ -183,6 +208,27 @@ int copy_thread(unsigned long clone_flags,
return 0;
}

/*
* sys_execve() executes a new program.
*/
asmlinkage int sys_execve(const char *name,
const char *const *argv,
const char *const *envp,
int dummy, ...)
{
int error;
struct filename *filename;
struct pt_regs *regs = (struct pt_regs *) ((unsigned char *)&dummy-4);

filename = getname(name);
error = PTR_ERR(filename);
if (IS_ERR(filename))
return error;
error = do_execve(filename->name, argv, envp, regs);
putname(filename);
return error;
}

unsigned long thread_saved_pc(struct task_struct *tsk)
{
return ((struct pt_regs *)tsk->thread.esp0)->pc;
Expand Down
26 changes: 26 additions & 0 deletions trunk/arch/h8300/kernel/sys_h8300.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,29 @@ asmlinkage void syscall_print(void *dummy,...)
((regs->pc)&0xffffff)-2,regs->orig_er0,regs->er1,regs->er2,regs->er3,regs->er0);
}
#endif

/*
* Do a system call from kernel instead of calling sys_execve so we
* end up with proper pt_regs.
*/
asmlinkage
int kernel_execve(const char *filename,
const char *const argv[],
const char *const envp[])
{
register long res __asm__("er0");
register const char *const *_c __asm__("er3") = envp;
register const char *const *_b __asm__("er2") = argv;
register const char * _a __asm__("er1") = filename;
__asm__ __volatile__ ("mov.l %1,er0\n\t"
"trapa #0\n\t"
: "=r" (res)
: "g" (__NR_execve),
"g" (_a),
"g" (_b),
"g" (_c)
: "cc", "memory");
return res;
}


2 changes: 2 additions & 0 deletions trunk/arch/m32r/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ config M32R
select GENERIC_ATOMIC64
select ARCH_USES_GETTIMEOFFSET
select MODULES_USE_ELF_RELA
select GENERIC_KERNEL_THREAD
select GENERIC_KERNEL_EXECVE

config SBUS
bool
Expand Down
5 changes: 0 additions & 5 deletions trunk/arch/m32r/include/asm/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,11 +118,6 @@ struct mm_struct;
/* Free all resources held by a thread. */
extern void release_thread(struct task_struct *);

/*
* create a kernel thread without removing it from tasklists
*/
extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);

/* Copy and release all segment info associated with a VM */
extern void copy_segments(struct task_struct *p, struct mm_struct * mm);
extern void release_segments(struct mm_struct * mm);
Expand Down
9 changes: 9 additions & 0 deletions trunk/arch/m32r/kernel/entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,15 @@
and \reg, sp
.endm

ENTRY(ret_from_kernel_thread)
pop r0
bl schedule_tail
GET_THREAD_INFO(r8)
ld r0, R0(r8)
ld r1, R1(r8)
jl r1
bra syscall_exit

ENTRY(ret_from_fork)
pop r0
bl schedule_tail
Expand Down
60 changes: 16 additions & 44 deletions trunk/arch/m32r/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -164,41 +164,6 @@ void show_regs(struct pt_regs * regs)
#endif
}

/*
* Create a kernel thread
*/

/*
* This is the mechanism for creating a new kernel thread.
*
* NOTE! Only a kernel-only process(ie the swapper or direct descendants
* who haven't done an "execve()") should use this: it will work within
* a system call from a "real" process, but the process memory space will
* not be free'd until both the parent and the child have exited.
*/
static void kernel_thread_helper(void *nouse, int (*fn)(void *), void *arg)
{
fn(arg);
do_exit(-1);
}

int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
{
struct pt_regs regs;

memset(&regs, 0, sizeof (regs));
regs.r1 = (unsigned long)fn;
regs.r2 = (unsigned long)arg;

regs.bpc = (unsigned long)kernel_thread_helper;

regs.psw = M32R_PSW_BIE;

/* Ok, create the new process. */
return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL,
NULL);
}

/*
* Free current thread data structures etc..
*/
Expand Down Expand Up @@ -227,19 +192,26 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu)
}

int copy_thread(unsigned long clone_flags, unsigned long spu,
unsigned long unused, struct task_struct *tsk, struct pt_regs *regs)
unsigned long arg, struct task_struct *tsk, struct pt_regs *regs)
{
struct pt_regs *childregs = task_pt_regs(tsk);
extern void ret_from_fork(void);

/* Copy registers */
*childregs = *regs;

childregs->spu = spu;
childregs->r0 = 0; /* Child gets zero as return value */
regs->r0 = tsk->pid;
extern void ret_from_kernel_thread(void);

if (unlikely(tsk->flags & PF_KTHREAD)) {
memset(childregs, 0, sizeof(struct pt_regs));
childregs->psw = M32R_PSW_BIE;
childregs->r1 = spu; /* fn */
childregs->r0 = arg;
tsk->thread.lr = (unsigned long)ret_from_kernel_thread;
} else {
/* Copy registers */
*childregs = *regs;
childregs->spu = spu;
childregs->r0 = 0; /* Child gets zero as return value */
tsk->thread.lr = (unsigned long)ret_from_fork;
}
tsk->thread.sp = (unsigned long)childregs;
tsk->thread.lr = (unsigned long)ret_from_fork;

return 0;
}
Expand Down
21 changes: 0 additions & 21 deletions trunk/arch/m32r/kernel/sys_m32r.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,24 +88,3 @@ asmlinkage int sys_cachectl(char *addr, int nbytes, int op)
/* Not implemented yet. */
return -ENOSYS;
}

/*
* Do a system call from kernel instead of calling sys_execve so we
* end up with proper pt_regs.
*/
int kernel_execve(const char *filename,
const char *const argv[],
const char *const envp[])
{
register long __scno __asm__ ("r7") = __NR_execve;
register long __arg3 __asm__ ("r2") = (long)(envp);
register long __arg2 __asm__ ("r1") = (long)(argv);
register long __res __asm__ ("r0") = (long)(filename);
__asm__ __volatile__ (
"trap #" SYSCALL_VECTOR "|| nop"
: "=r" (__res)
: "r" (__scno), "0" (__res), "r" (__arg2),
"r" (__arg3)
: "memory");
return __res;
}

0 comments on commit 3c6f5fc

Please sign in to comment.