X-Git-Url: http://git.onelab.eu/?p=linux-2.6.git;a=blobdiff_plain;f=arch%2Fum%2Fkernel%2Ftt%2Fprocess_kern.c;h=776310fd5b8b7e34d4b651b5fd2216a27b0a8935;hp=1f4d12b27195e884eb9415e571014db781d36279;hb=f7f1b0f1e2fbadeab12d24236000e778aa9b1ead;hpb=e3f6fb6212a7102bdb56ba38fa1e98fe72950475 diff --git a/arch/um/kernel/tt/process_kern.c b/arch/um/kernel/tt/process_kern.c index 1f4d12b27..776310fd5 100644 --- a/arch/um/kernel/tt/process_kern.c +++ b/arch/um/kernel/tt/process_kern.c @@ -32,10 +32,6 @@ void *switch_to_tt(void *prev, void *next, void *last) unsigned long flags; int err, vtalrm, alrm, prof, cpu; char c; - /* jailing and SMP are incompatible, so this doesn't need to be - * made per-cpu - */ - static int reading; from = prev; to = next; @@ -59,14 +55,11 @@ void *switch_to_tt(void *prev, void *next, void *last) c = 0; set_current(to); - reading = 0; err = os_write_file(to->thread.mode.tt.switch_pipe[1], &c, sizeof(c)); if(err != sizeof(c)) panic("write of switch_pipe failed, err = %d", -err); - reading = 1; - if((from->exit_state == EXIT_ZOMBIE) || - (from->exit_state == EXIT_DEAD)) + if(from->thread.mode.tt.switch_pipe[0] == -1) os_kill_process(os_getpid(), 0); err = os_read_file(from->thread.mode.tt.switch_pipe[0], &c, sizeof(c)); @@ -81,28 +74,9 @@ void *switch_to_tt(void *prev, void *next, void *last) * in case it has not already killed itself. */ prev_sched = current->thread.prev_sched; - if((prev_sched->exit_state == EXIT_ZOMBIE) || - (prev_sched->exit_state == EXIT_DEAD)) + if(prev_sched->thread.mode.tt.switch_pipe[0] == -1) os_kill_process(prev_sched->thread.mode.tt.extern_pid, 1); - /* This works around a nasty race with 'jail'. If we are switching - * between two threads of a threaded app and the incoming process - * runs before the outgoing process reaches the read, and it makes - * it all the way out to userspace, then it will have write-protected - * the outgoing process stack. Then, when the outgoing process - * returns from the write, it will segfault because it can no longer - * write its own stack. So, in order to avoid that, the incoming - * thread sits in a loop yielding until 'reading' is set. This - * isn't entirely safe, since there may be a reschedule from a timer - * happening between setting 'reading' and sleeping in read. But, - * it should get a whole quantum in which to reach the read and sleep, - * which should be enough. - */ - - if(jail){ - while(!reading) sched_yield(); - } - change_sig(SIGVTALRM, vtalrm); change_sig(SIGALRM, alrm); change_sig(SIGPROF, prof); @@ -119,14 +93,18 @@ void release_thread_tt(struct task_struct *task) { int pid = task->thread.mode.tt.extern_pid; + /* + * We first have to kill the other process, before + * closing its switch_pipe. Else it might wake up + * and receive "EOF" before we could kill it. + */ if(os_getpid() != pid) os_kill_process(pid, 0); -} -void exit_thread_tt(void) -{ - os_close_file(current->thread.mode.tt.switch_pipe[0]); - os_close_file(current->thread.mode.tt.switch_pipe[1]); + os_close_file(task->thread.mode.tt.switch_pipe[0]); + os_close_file(task->thread.mode.tt.switch_pipe[1]); + /* use switch_pipe as flag: thread is released */ + task->thread.mode.tt.switch_pipe[0] = -1; } void suspend_new_thread(int fd) @@ -394,84 +372,6 @@ void init_idle_tt(void) default_idle(); } -/* Changed by jail_setup, which is a setup */ -int jail = 0; - -int __init jail_setup(char *line, int *add) -{ - int ok = 1; - - if(jail) return(0); -#ifdef CONFIG_SMP - printf("'jail' may not used used in a kernel with CONFIG_SMP " - "enabled\n"); - ok = 0; -#endif -#ifdef CONFIG_HOSTFS - printf("'jail' may not used used in a kernel with CONFIG_HOSTFS " - "enabled\n"); - ok = 0; -#endif -#ifdef CONFIG_MODULES - printf("'jail' may not used used in a kernel with CONFIG_MODULES " - "enabled\n"); - ok = 0; -#endif - if(!ok) exit(1); - - /* CAP_SYS_RAWIO controls the ability to open /dev/mem and /dev/kmem. - * Removing it from the bounding set eliminates the ability of anything - * to acquire it, and thus read or write kernel memory. - */ - cap_lower(cap_bset, CAP_SYS_RAWIO); - jail = 1; - return(0); -} - -__uml_setup("jail", jail_setup, -"jail\n" -" Enables the protection of kernel memory from processes.\n\n" -); - -static void mprotect_kernel_mem(int w) -{ - unsigned long start, end; - int pages; - - if(!jail || (current == &init_task)) return; - - pages = (1 << CONFIG_KERNEL_STACK_ORDER); - - start = (unsigned long) current_thread + PAGE_SIZE; - end = (unsigned long) current_thread + PAGE_SIZE * pages; - protect_memory(uml_reserved, start - uml_reserved, 1, w, 1, 1); - protect_memory(end, high_physmem - end, 1, w, 1, 1); - - start = (unsigned long) UML_ROUND_DOWN(&_stext); - end = (unsigned long) UML_ROUND_UP(&_etext); - protect_memory(start, end - start, 1, w, 1, 1); - - start = (unsigned long) UML_ROUND_DOWN(&_unprotected_end); - end = (unsigned long) UML_ROUND_UP(&_edata); - protect_memory(start, end - start, 1, w, 1, 1); - - start = (unsigned long) UML_ROUND_DOWN(&__bss_start); - end = (unsigned long) UML_ROUND_UP(brk_start); - protect_memory(start, end - start, 1, w, 1, 1); - - mprotect_kernel_vm(w); -} - -void unprotect_kernel_mem(void) -{ - mprotect_kernel_mem(1); -} - -void protect_kernel_mem(void) -{ - mprotect_kernel_mem(0); -} - extern void start_kernel(void); static int start_kernel_proc(void *unused)