Merge branch 'torvalds/master'
[firefly-linux-kernel-4.4.55.git] / arch / um / os-Linux / process.c
index b8f34c9e53ae9fc820f81e215253ec2bc70f9ffc..8408aba915b29f7e603233fc5c27e80abd081864 100644 (file)
@@ -4,6 +4,7 @@
  */
 
 #include <stdio.h>
+#include <stdlib.h>
 #include <unistd.h>
 #include <errno.h>
 #include <signal.h>
@@ -15,7 +16,6 @@
 #include <init.h>
 #include <longjmp.h>
 #include <os.h>
-#include <skas_ptrace.h>
 
 #define ARBITRARY_ADDR -1
 #define FAILURE_PID    -1
@@ -101,21 +101,6 @@ void os_kill_process(int pid, int reap_child)
                CATCH_EINTR(waitpid(pid, NULL, __WALL));
 }
 
-/* This is here uniquely to have access to the userspace errno, i.e. the one
- * used by ptrace in case of error.
- */
-
-long os_ptrace_ldt(long pid, long addr, long data)
-{
-       int ret;
-
-       ret = ptrace(PTRACE_LDT, pid, addr, data);
-
-       if (ret < 0)
-               return -errno;
-       return ret;
-}
-
 /* Kill off a ptraced child by all means available.  kill it normally first,
  * then PTRACE_KILL it, then PTRACE_CONT it in case it's in a run state from
  * which it can't exit directly.
@@ -232,6 +217,57 @@ out:
        return ok;
 }
 
+static int os_page_mincore(void *addr)
+{
+       char vec[2];
+       int ret;
+
+       ret = mincore(addr, UM_KERN_PAGE_SIZE, vec);
+       if (ret < 0) {
+               if (errno == ENOMEM || errno == EINVAL)
+                       return 0;
+               else
+                       return -errno;
+       }
+
+       return vec[0] & 1;
+}
+
+int os_mincore(void *addr, unsigned long len)
+{
+       char *vec;
+       int ret, i;
+
+       if (len <= UM_KERN_PAGE_SIZE)
+               return os_page_mincore(addr);
+
+       vec = calloc(1, (len + UM_KERN_PAGE_SIZE - 1) / UM_KERN_PAGE_SIZE);
+       if (!vec)
+               return -ENOMEM;
+
+       ret = mincore(addr, UM_KERN_PAGE_SIZE, vec);
+       if (ret < 0) {
+               if (errno == ENOMEM || errno == EINVAL)
+                       ret = 0;
+               else
+                       ret = -errno;
+
+               goto out;
+       }
+
+       for (i = 0; i < ((len + UM_KERN_PAGE_SIZE - 1) / UM_KERN_PAGE_SIZE); i++) {
+               if (!(vec[i] & 1)) {
+                       ret = 0;
+                       goto out;
+               }
+       }
+
+       ret = 1;
+out:
+       free(vec);
+       return ret;
+}
+
 void init_new_thread_signals(void)
 {
        set_handler(SIGSEGV);
@@ -242,5 +278,4 @@ void init_new_thread_signals(void)
        signal(SIGHUP, SIG_IGN);
        set_handler(SIGIO);
        signal(SIGWINCH, SIG_IGN);
-       signal(SIGTERM, SIG_DFL);
 }