]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/um/os-Linux/start_up.c
Input: add microphone insert switch definition
[linux-2.6-omap-h63xx.git] / arch / um / os-Linux / start_up.c
index f22715868929e9ba0e5f7343c0461e0558661278..b4b36e0f2e8960d3d195d9617576fe02a8d86f08 100644 (file)
 #include "mem_user.h"
 #include "ptrace_user.h"
 #include "registers.h"
+#include "skas.h"
 #include "skas_ptrace.h"
 
-static int ptrace_child(void *arg)
+static void ptrace_child(void)
 {
        int ret;
+       /* Calling os_getpid because some libcs cached getpid incorrectly */
        int pid = os_getpid(), ppid = getppid();
        int sc_result;
 
-       change_sig(SIGWINCH, 0);
-       if (ptrace(PTRACE_TRACEME, 0, 0, 0) < 0) {
+       if (change_sig(SIGWINCH, 0) < 0 ||
+           ptrace(PTRACE_TRACEME, 0, 0, 0) < 0) {
                perror("ptrace");
-               os_kill_process(pid, 0);
+               kill(pid, SIGKILL);
        }
        kill(pid, SIGSTOP);
 
@@ -59,10 +61,11 @@ static int ptrace_child(void *arg)
                 * the UML code itself.
                 */
                ret = 2;
-       _exit(ret);
+
+       exit(ret);
 }
 
-static void fatal_perror(char *str)
+static void fatal_perror(const char *str)
 {
        perror(str);
        exit(1);
@@ -73,9 +76,8 @@ static void fatal(char *fmt, ...)
        va_list list;
 
        va_start(list, fmt);
-       vprintf(fmt, list);
+       vfprintf(stderr, fmt, list);
        va_end(list);
-       fflush(stdout);
 
        exit(1);
 }
@@ -85,36 +87,27 @@ static void non_fatal(char *fmt, ...)
        va_list list;
 
        va_start(list, fmt);
-       vprintf(fmt, list);
+       vfprintf(stderr, fmt, list);
        va_end(list);
-       fflush(stdout);
 }
 
-static int start_ptraced_child(void **stack_out)
+static int start_ptraced_child(void)
 {
-       void *stack;
-       unsigned long sp;
        int pid, n, status;
 
-       stack = mmap(NULL, UM_KERN_PAGE_SIZE,
-                    PROT_READ | PROT_WRITE | PROT_EXEC,
-                    MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
-       if (stack == MAP_FAILED)
-               fatal_perror("check_ptrace : mmap failed");
-
-       sp = (unsigned long) stack + UM_KERN_PAGE_SIZE - sizeof(void *);
-       pid = clone(ptrace_child, (void *) sp, SIGCHLD, NULL);
-       if (pid < 0)
-               fatal_perror("start_ptraced_child : clone failed");
+       pid = fork();
+       if (pid == 0)
+               ptrace_child();
+       else if (pid < 0)
+               fatal_perror("start_ptraced_child : fork failed");
 
        CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
        if (n < 0)
-               fatal_perror("check_ptrace : clone failed");
+               fatal_perror("check_ptrace : waitpid failed");
        if (!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP))
                fatal("check_ptrace : expected SIGSTOP, got status = %d",
                      status);
 
-       *stack_out = stack;
        return pid;
 }
 
@@ -124,8 +117,7 @@ static int start_ptraced_child(void **stack_out)
  * So only for SYSEMU features we test mustpanic, while normal host features
  * must work anyway!
  */
-static int stop_ptraced_child(int pid, void *stack, int exitcode,
-                             int mustexit)
+static int stop_ptraced_child(int pid, int exitcode, int mustexit)
 {
        int status, n, ret = 0;
 
@@ -145,20 +137,31 @@ static int stop_ptraced_child(int pid, void *stack, int exitcode,
                ret = -1;
        }
 
-       if (munmap(stack, UM_KERN_PAGE_SIZE) < 0)
-               fatal_perror("check_ptrace : munmap failed");
        return ret;
 }
 
 /* Changed only during early boot */
-int ptrace_faultinfo = 1;
-int ptrace_ldt = 1;
-int proc_mm = 1;
-int skas_needs_stub = 0;
+int ptrace_faultinfo;
+static int disable_ptrace_faultinfo;
+
+int ptrace_ldt;
+static int disable_ptrace_ldt;
+
+int proc_mm;
+static int disable_proc_mm;
+
+int have_switch_mm;
+static int disable_switch_mm;
+
+int skas_needs_stub;
 
 static int __init skas0_cmd_param(char *str, int* add)
 {
-       ptrace_faultinfo = proc_mm = 0;
+       disable_ptrace_faultinfo = 1;
+       disable_ptrace_ldt = 1;
+       disable_proc_mm = 1;
+       disable_switch_mm = 1;
+
        return 0;
 }
 
@@ -168,15 +171,12 @@ static int __init mode_skas0_cmd_param(char *str, int* add)
        __attribute__((alias("skas0_cmd_param")));
 
 __uml_setup("skas0", skas0_cmd_param,
-               "skas0\n"
-               "    Disables SKAS3 usage, so that SKAS0 is used, unless \n"
-               "    you specify mode=tt.\n\n");
+"skas0\n"
+"    Disables SKAS3 and SKAS4 usage, so that SKAS0 is used\n\n");
 
 __uml_setup("mode=skas0", mode_skas0_cmd_param,
-               "mode=skas0\n"
-               "    Disables SKAS3 usage, so that SKAS0 is used, unless you \n"
-               "    specify mode=tt. Note that this was recently added - on \n"
-               "    older kernels you must use simply \"skas0\".\n\n");
+"mode=skas0\n"
+"    Disables SKAS3 and SKAS4 usage, so that SKAS0 is used.\n\n");
 
 /* Changed only during early boot */
 static int force_sysemu_disabled = 0;
@@ -198,13 +198,12 @@ __uml_setup("nosysemu", nosysemu_cmd_param,
 
 static void __init check_sysemu(void)
 {
-       void *stack;
        unsigned long regs[MAX_REG_NR];
        int pid, n, status, count=0;
 
        non_fatal("Checking syscall emulation patch for ptrace...");
        sysemu_supported = 0;
-       pid = start_ptraced_child(&stack);
+       pid = start_ptraced_child();
 
        if (ptrace(PTRACE_SYSEMU, pid, 0, 0) < 0)
                goto fail;
@@ -231,7 +230,7 @@ static void __init check_sysemu(void)
                goto fail;
        }
 
-       if (stop_ptraced_child(pid, stack, 0, 0) < 0)
+       if (stop_ptraced_child(pid, 0, 0) < 0)
                goto fail_stopped;
 
        sysemu_supported = 1;
@@ -239,7 +238,7 @@ static void __init check_sysemu(void)
        set_using_sysemu(!force_sysemu_disabled);
 
        non_fatal("Checking advanced syscall emulation patch for ptrace...");
-       pid = start_ptraced_child(&stack);
+       pid = start_ptraced_child();
 
        if ((ptrace(PTRACE_OLDSETOPTIONS, pid, 0,
                   (void *) PTRACE_O_TRACESYSGOOD) < 0))
@@ -271,7 +270,7 @@ static void __init check_sysemu(void)
                        fatal("check_ptrace : expected SIGTRAP or "
                              "(SIGTRAP | 0x80), got status = %d", status);
        }
-       if (stop_ptraced_child(pid, stack, 0, 0) < 0)
+       if (stop_ptraced_child(pid, 0, 0) < 0)
                goto fail_stopped;
 
        sysemu_supported = 2;
@@ -282,18 +281,17 @@ static void __init check_sysemu(void)
        return;
 
 fail:
-       stop_ptraced_child(pid, stack, 1, 0);
+       stop_ptraced_child(pid, 1, 0);
 fail_stopped:
        non_fatal("missing\n");
 }
 
 static void __init check_ptrace(void)
 {
-       void *stack;
        int pid, syscall, n, status;
 
        non_fatal("Checking that ptrace can change system call numbers...");
-       pid = start_ptraced_child(&stack);
+       pid = start_ptraced_child();
 
        if ((ptrace(PTRACE_OLDSETOPTIONS, pid, 0,
                   (void *) PTRACE_O_TRACESYSGOOD) < 0))
@@ -323,7 +321,7 @@ static void __init check_ptrace(void)
                        break;
                }
        }
-       stop_ptraced_child(pid, stack, 0, 1);
+       stop_ptraced_child(pid, 0, 1);
        non_fatal("OK\n");
        check_sysemu();
 }
@@ -353,6 +351,8 @@ static void __init check_coredump_limit(void)
 
 void __init os_early_checks(void)
 {
+       int pid;
+
        /* Print out the core dump limits early */
        check_coredump_limit();
 
@@ -362,11 +362,16 @@ void __init os_early_checks(void)
         * kernel is running.
         */
        check_tmpexec();
+
+       pid = start_ptraced_child();
+       if (init_registers(pid))
+               fatal("Failed to initialize default registers");
+       stop_ptraced_child(pid, 1, 1);
 }
 
 static int __init noprocmm_cmd_param(char *str, int* add)
 {
-       proc_mm = 0;
+       disable_proc_mm = 1;
        return 0;
 }
 
@@ -378,7 +383,7 @@ __uml_setup("noprocmm", noprocmm_cmd_param,
 
 static int __init noptracefaultinfo_cmd_param(char *str, int* add)
 {
-       ptrace_faultinfo = 0;
+       disable_ptrace_faultinfo = 1;
        return 0;
 }
 
@@ -390,7 +395,7 @@ __uml_setup("noptracefaultinfo", noptracefaultinfo_cmd_param,
 
 static int __init noptraceldt_cmd_param(char *str, int* add)
 {
-       ptrace_ldt = 0;
+       disable_ptrace_ldt = 1;
        return 0;
 }
 
@@ -403,35 +408,30 @@ __uml_setup("noptraceldt", noptraceldt_cmd_param,
 static inline void check_skas3_ptrace_faultinfo(void)
 {
        struct ptrace_faultinfo fi;
-       void *stack;
        int pid, n;
 
        non_fatal("  - PTRACE_FAULTINFO...");
-       pid = start_ptraced_child(&stack);
+       pid = start_ptraced_child();
 
        n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi);
        if (n < 0) {
-               ptrace_faultinfo = 0;
                if (errno == EIO)
                        non_fatal("not found\n");
                else
                        perror("not found");
-       }
+       } else if (disable_ptrace_faultinfo)
+               non_fatal("found but disabled on command line\n");
        else {
-               if (!ptrace_faultinfo)
-                       non_fatal("found but disabled on command line\n");
-               else
-                       non_fatal("found\n");
+               ptrace_faultinfo = 1;
+               non_fatal("found\n");
        }
 
-       init_registers(pid);
-       stop_ptraced_child(pid, stack, 1, 1);
+       stop_ptraced_child(pid, 1, 1);
 }
 
 static inline void check_skas3_ptrace_ldt(void)
 {
 #ifdef PTRACE_LDT
-       void *stack;
        int pid, n;
        unsigned char ldtbuf[40];
        struct ptrace_ldt ldt_op = (struct ptrace_ldt) {
@@ -440,47 +440,39 @@ static inline void check_skas3_ptrace_ldt(void)
                .bytecount = sizeof(ldtbuf)};
 
        non_fatal("  - PTRACE_LDT...");
-       pid = start_ptraced_child(&stack);
+       pid = start_ptraced_child();
 
        n = ptrace(PTRACE_LDT, pid, 0, (unsigned long) &ldt_op);
        if (n < 0) {
                if (errno == EIO)
                        non_fatal("not found\n");
-               else {
+               else
                        perror("not found");
-               }
-               ptrace_ldt = 0;
-       }
+       } else if (disable_ptrace_ldt)
+               non_fatal("found, but use is disabled\n");
        else {
-               if (ptrace_ldt)
-                       non_fatal("found\n");
-               else
-                       non_fatal("found, but use is disabled\n");
+               ptrace_ldt = 1;
+               non_fatal("found\n");
        }
 
-       stop_ptraced_child(pid, stack, 1, 1);
-#else
-       /* PTRACE_LDT might be disabled via cmdline option.
-        * We want to override this, else we might use the stub
-        * without real need
-        */
-       ptrace_ldt = 1;
+       stop_ptraced_child(pid, 1, 1);
 #endif
 }
 
 static inline void check_skas3_proc_mm(void)
 {
        non_fatal("  - /proc/mm...");
-       if (access("/proc/mm", W_OK) < 0) {
-               proc_mm = 0;
+       if (access("/proc/mm", W_OK) < 0)
                perror("not found");
-       }
-       else if (!proc_mm)
+       else if (disable_proc_mm)
                non_fatal("found but disabled on command line\n");
-       else non_fatal("found\n");
+       else {
+               proc_mm = 1;
+               non_fatal("found\n");
+       }
 }
 
-int can_do_skas(void)
+void can_do_skas(void)
 {
        non_fatal("Checking for the skas3 patch in the host:\n");
 
@@ -490,8 +482,6 @@ int can_do_skas(void)
 
        if (!proc_mm || !ptrace_faultinfo || !ptrace_ldt)
                skas_needs_stub = 1;
-
-       return 1;
 }
 
 int __init parse_iomem(char *str, int *add)
@@ -504,14 +494,14 @@ int __init parse_iomem(char *str, int *add)
        driver = str;
        file = strchr(str,',');
        if (file == NULL) {
-               printf("parse_iomem : failed to parse iomem\n");
+               fprintf(stderr, "parse_iomem : failed to parse iomem\n");
                goto out;
        }
        *file = '\0';
        file++;
        fd = open(file, O_RDWR, 0);
        if (fd < 0) {
-               os_print_error(fd, "parse_iomem - Couldn't open io file");
+               perror("parse_iomem - Couldn't open io file");
                goto out;
        }