Merge branches 'release', 'asus', 'sony-laptop' and 'thinkpad' into release
[pandora-kernel.git] / arch / um / os-Linux / util.c
index c307a89..a6f31d4 100644 (file)
 
 void stack_protections(unsigned long address)
 {
-       int prot = PROT_READ | PROT_WRITE | PROT_EXEC;
-
-       if(mprotect((void *) address, UM_KERN_PAGE_SIZE, prot) < 0)
-               panic("protecting stack failed, errno = %d", errno);
-}
-
-void task_protections(unsigned long address)
-{
-       unsigned long guard = address + UM_KERN_PAGE_SIZE;
-       unsigned long stack = guard + UM_KERN_PAGE_SIZE;
-       int prot = 0, pages;
-
-#ifdef notdef
-       if(mprotect((void *) stack, UM_KERN_PAGE_SIZE, prot) < 0)
-               panic("protecting guard page failed, errno = %d", errno);
-#endif
-       pages = (1 << UML_CONFIG_KERNEL_STACK_ORDER) - 2;
-       prot = PROT_READ | PROT_WRITE | PROT_EXEC;
-       if(mprotect((void *) stack, pages * UM_KERN_PAGE_SIZE, prot) < 0)
+       if(mprotect((void *) address, UM_THREAD_SIZE,
+                   PROT_READ | PROT_WRITE | PROT_EXEC) < 0)
                panic("protecting stack failed, errno = %d", errno);
 }
 
@@ -72,7 +55,7 @@ int raw(int fd)
 
        /* XXX tcsetattr could have applied only some changes
         * (and cfmakeraw() is a set of changes) */
-       return(0);
+       return 0;
 }
 
 void setup_machinename(char *machine_out)
@@ -105,23 +88,46 @@ void setup_hostinfo(char *buf, int len)
                 host.release, host.version, host.machine);
 }
 
-int setjmp_wrapper(void (*proc)(void *, void *), ...)
-{
-       va_list args;
-       jmp_buf buf;
-       int n;
-
-       n = UML_SETJMP(&buf);
-       if(n == 0){
-               va_start(args, proc);
-               (*proc)(&buf, &args);
-       }
-       va_end(args);
-       return n;
-}
-
 void os_dump_core(void)
 {
+       int pid;
+
        signal(SIGSEGV, SIG_DFL);
+
+       /*
+        * We are about to SIGTERM this entire process group to ensure that
+        * nothing is around to run after the kernel exits.  The
+        * kernel wants to abort, not die through SIGTERM, so we
+        * ignore it here.
+        */
+
+       signal(SIGTERM, SIG_IGN);
+       kill(0, SIGTERM);
+       /*
+        * Most of the other processes associated with this UML are
+        * likely sTopped, so give them a SIGCONT so they see the
+        * SIGTERM.
+        */
+       kill(0, SIGCONT);
+
+       /*
+        * Now, having sent signals to everyone but us, make sure they
+        * die by ptrace.  Processes can survive what's been done to
+        * them so far - the mechanism I understand is receiving a
+        * SIGSEGV and segfaulting immediately upon return.  There is
+        * always a SIGSEGV pending, and (I'm guessing) signals are
+        * processed in numeric order so the SIGTERM (signal 15 vs
+        * SIGSEGV being signal 11) is never handled.
+        *
+        * Run a waitpid loop until we get some kind of error.
+        * Hopefully, it's ECHILD, but there's not a lot we can do if
+        * it's something else.  Tell os_kill_ptraced_process not to
+        * wait for the child to report its death because there's
+        * nothing reasonable to do if that fails.
+        */
+
+       while ((pid = waitpid(-1, NULL, WNOHANG | __WALL)) > 0)
+               os_kill_ptraced_process(pid, 0);
+
        abort();
 }