]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/um/os-Linux/util.c
uml: fix !NO_HZ busy-loop
[linux-2.6-omap-h63xx.git] / arch / um / os-Linux / util.c
index 0e771bb04dd215c87b3fde37f979fa0f0c563a0f..ef095436a78c24f669dfc54d1ef8af9eb376687d 100644 (file)
 #include "uml-config.h"
 #include "os.h"
 #include "longjmp.h"
+#include "kern_constants.h"
 
 void stack_protections(unsigned long address)
 {
-       int prot = PROT_READ | PROT_WRITE | PROT_EXEC;
-
-       if(mprotect((void *) address, page_size(), prot) < 0)
-               panic("protecting stack failed, errno = %d", errno);
-}
-
-void task_protections(unsigned long address)
-{
-       unsigned long guard = address + page_size();
-       unsigned long stack = guard + page_size();
-       int prot = 0, pages;
-
-#ifdef notdef
-       if(mprotect((void *) stack, 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 * 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);
 }
 
@@ -71,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)
@@ -118,3 +102,47 @@ int setjmp_wrapper(void (*proc)(void *, void *), ...)
        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)) > 0)
+               os_kill_ptraced_process(pid, 0);
+
+       abort();
+}