11d3468a6SJeff Dike /* 21d3468a6SJeff Dike * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com) 31d3468a6SJeff Dike * Licensed under the GPL 41d3468a6SJeff Dike */ 51d3468a6SJeff Dike 61d3468a6SJeff Dike #include "linux/slab.h" 71d3468a6SJeff Dike #include "linux/smp_lock.h" 81d3468a6SJeff Dike #include "linux/ptrace.h" 91d3468a6SJeff Dike #include "asm/ptrace.h" 101d3468a6SJeff Dike #include "asm/pgtable.h" 111d3468a6SJeff Dike #include "asm/tlbflush.h" 121d3468a6SJeff Dike #include "asm/uaccess.h" 131d3468a6SJeff Dike #include "user_util.h" 141d3468a6SJeff Dike #include "kern_util.h" 151d3468a6SJeff Dike #include "mem_user.h" 161d3468a6SJeff Dike #include "kern.h" 171d3468a6SJeff Dike #include "irq_user.h" 181d3468a6SJeff Dike #include "tlb.h" 191d3468a6SJeff Dike #include "os.h" 201d3468a6SJeff Dike #include "choose-mode.h" 211d3468a6SJeff Dike #include "mode_kern.h" 221d3468a6SJeff Dike 231d3468a6SJeff Dike void flush_thread(void) 241d3468a6SJeff Dike { 251d3468a6SJeff Dike arch_flush_thread(¤t->thread.arch); 261d3468a6SJeff Dike CHOOSE_MODE(flush_thread_tt(), flush_thread_skas()); 271d3468a6SJeff Dike } 281d3468a6SJeff Dike 291d3468a6SJeff Dike void start_thread(struct pt_regs *regs, unsigned long eip, unsigned long esp) 301d3468a6SJeff Dike { 311d3468a6SJeff Dike CHOOSE_MODE_PROC(start_thread_tt, start_thread_skas, regs, eip, esp); 321d3468a6SJeff Dike } 331d3468a6SJeff Dike 341d3468a6SJeff Dike #ifdef CONFIG_TTY_LOG 351d3468a6SJeff Dike extern void log_exec(char **argv, void *tty); 361d3468a6SJeff Dike #endif 371d3468a6SJeff Dike 381d3468a6SJeff Dike static long execve1(char *file, char __user * __user *argv, 391d3468a6SJeff Dike char __user *__user *env) 401d3468a6SJeff Dike { 411d3468a6SJeff Dike long error; 4224ec839cSPeter Zijlstra struct tty_struct *tty; 431d3468a6SJeff Dike 441d3468a6SJeff Dike #ifdef CONFIG_TTY_LOG 45b1fc0b1fSAlan Cox mutex_lock(&tty_mutex); 4624ec839cSPeter Zijlstra tty = get_current_tty(); 4724ec839cSPeter Zijlstra if (tty) 4824ec839cSPeter Zijlstra log_exec(argv, tty); 49b1fc0b1fSAlan Cox mutex_unlock(&tty_mutex); 501d3468a6SJeff Dike #endif 511d3468a6SJeff Dike error = do_execve(file, argv, env, ¤t->thread.regs); 521d3468a6SJeff Dike if (error == 0){ 531d3468a6SJeff Dike task_lock(current); 541d3468a6SJeff Dike current->ptrace &= ~PT_DTRACE; 551d3468a6SJeff Dike #ifdef SUBARCH_EXECVE1 561d3468a6SJeff Dike SUBARCH_EXECVE1(¤t->thread.regs.regs); 571d3468a6SJeff Dike #endif 581d3468a6SJeff Dike task_unlock(current); 591d3468a6SJeff Dike set_cmdline(current_cmd()); 601d3468a6SJeff Dike } 611d3468a6SJeff Dike return(error); 621d3468a6SJeff Dike } 631d3468a6SJeff Dike 641d3468a6SJeff Dike long um_execve(char *file, char __user *__user *argv, char __user *__user *env) 651d3468a6SJeff Dike { 661d3468a6SJeff Dike long err; 671d3468a6SJeff Dike 681d3468a6SJeff Dike err = execve1(file, argv, env); 691d3468a6SJeff Dike if(!err) 701d3468a6SJeff Dike do_longjmp(current->thread.exec_buf, 1); 711d3468a6SJeff Dike return(err); 721d3468a6SJeff Dike } 731d3468a6SJeff Dike 741d3468a6SJeff Dike long sys_execve(char __user *file, char __user *__user *argv, 751d3468a6SJeff Dike char __user *__user *env) 761d3468a6SJeff Dike { 771d3468a6SJeff Dike long error; 781d3468a6SJeff Dike char *filename; 791d3468a6SJeff Dike 801d3468a6SJeff Dike lock_kernel(); 811d3468a6SJeff Dike filename = getname(file); 821d3468a6SJeff Dike error = PTR_ERR(filename); 831d3468a6SJeff Dike if (IS_ERR(filename)) goto out; 841d3468a6SJeff Dike error = execve1(filename, argv, env); 851d3468a6SJeff Dike putname(filename); 861d3468a6SJeff Dike out: 871d3468a6SJeff Dike unlock_kernel(); 881d3468a6SJeff Dike return(error); 891d3468a6SJeff Dike } 90