]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - arch/um/os-Linux/start_up.c
[PATCH] uml: fix style violations
[mv-sheeva.git] / arch / um / os-Linux / start_up.c
index 829d6b0d8b02496821ff14a0a7c869192383368a..735d035a7f33f06408c2462a01cc572ab3511608 100644 (file)
@@ -3,6 +3,7 @@
  * Licensed under the GPL
  */
 
+#include <pty.h>
 #include <stdio.h>
 #include <stddef.h>
 #include <stdarg.h>
@@ -13,7 +14,6 @@
 #include <sched.h>
 #include <fcntl.h>
 #include <errno.h>
-#include <setjmp.h>
 #include <sys/time.h>
 #include <sys/wait.h>
 #include <sys/mman.h>
@@ -54,7 +54,7 @@ static int ptrace_child(void *arg)
                perror("ptrace");
                os_kill_process(pid, 0);
        }
-       os_stop_process(pid);
+       kill(pid, SIGSTOP);
 
        /*This syscall will be intercepted by the parent. Don't call more than
         * once, please.*/
@@ -95,7 +95,7 @@ static int start_ptraced_child(void **stack_out)
                      status);
 
        *stack_out = stack;
-       return(pid);
+       return pid;
 }
 
 /* When testing for SYSEMU support, if it is one of the broken versions, we
@@ -133,6 +133,7 @@ static int stop_ptraced_child(int pid, void *stack, int exitcode,
        return ret;
 }
 
+/* Changed only during early boot */
 int ptrace_faultinfo = 1;
 int ptrace_ldt = 1;
 int proc_mm = 1;
@@ -160,6 +161,7 @@ __uml_setup("mode=skas0", mode_skas0_cmd_param,
                "    specify mode=tt. Note that this was recently added - on \n"
                "    older kernels you must use simply \"skas0\".\n\n");
 
+/* Changed only during early boot */
 static int force_sysemu_disabled = 0;
 
 static int __init nosysemu_cmd_param(char *str, int* add)
@@ -180,7 +182,7 @@ __uml_setup("nosysemu", nosysemu_cmd_param,
 static void __init check_sysemu(void)
 {
        void *stack;
-       int pid, n, status, count=0;
+       int pid, n, status, count=0;
 
        printf("Checking syscall emulation patch for ptrace...");
        sysemu_supported = 0;
@@ -295,29 +297,7 @@ static void __init check_ptrace(void)
        check_sysemu();
 }
 
-extern int create_tmp_file(unsigned long long len);
-
-static void check_tmpexec(void)
-{
-       void *addr;
-       int err, fd = create_tmp_file(UM_KERN_PAGE_SIZE);
-
-       addr = mmap(NULL, UM_KERN_PAGE_SIZE,
-                   PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, fd, 0);
-       printf("Checking PROT_EXEC mmap in /tmp...");
-       fflush(stdout);
-       if(addr == MAP_FAILED){
-               err = errno;
-               perror("failed");
-               if(err == EPERM)
-                       printf("/tmp must be not mounted noexec\n");
-               exit(1);
-       }
-       printf("OK\n");
-       munmap(addr, UM_KERN_PAGE_SIZE);
-
-       close(fd);
-}
+extern void check_tmpexec(void);
 
 void os_early_checks(void)
 {
@@ -437,8 +417,8 @@ static inline void check_skas3_ptrace_ldt(void)
 static inline void check_skas3_proc_mm(void)
 {
        printf("  - /proc/mm...");
-       if (os_access("/proc/mm", OS_ACC_W_OK) < 0) {
-               proc_mm = 0;
+       if (access("/proc/mm", W_OK) < 0) {
+               proc_mm = 0;
                printf("not found\n");
        }
        else {
@@ -465,35 +445,16 @@ int can_do_skas(void)
 #else
 int can_do_skas(void)
 {
-       return(0);
+       return 0;
 }
 #endif
 
-int have_devanon = 0;
-
-/* Runs on boot kernel stack - already safe to use printk. */
-
-void check_devanon(void)
-{
-       int fd;
-
-       printk("Checking for /dev/anon on the host...");
-       fd = open("/dev/anon", O_RDWR);
-       if(fd < 0){
-               printk("Not available (open failed with errno %d)\n", errno);
-               return;
-       }
-
-       printk("OK\n");
-       have_devanon = 1;
-}
-
 int __init parse_iomem(char *str, int *add)
 {
        struct iomem_region *new;
-       struct uml_stat buf;
+       struct stat64 buf;
        char *file, *driver;
-       int fd, err, size;
+       int fd, size;
 
        driver = str;
        file = strchr(str,',');
@@ -503,15 +464,14 @@ int __init parse_iomem(char *str, int *add)
        }
        *file = '\0';
        file++;
-       fd = os_open_file(file, of_rdwr(OPENFLAGS()), 0);
+       fd = open(file, O_RDWR, 0);
        if(fd < 0){
                os_print_error(fd, "parse_iomem - Couldn't open io file");
                goto out;
        }
 
-       err = os_stat_fd(fd, &buf);
-       if(err < 0){
-               os_print_error(err, "parse_iomem - cannot stat_fd file");
+       if(fstat64(fd, &buf) < 0){
+               perror("parse_iomem - cannot stat_fd file");
                goto out_close;
        }
 
@@ -521,7 +481,7 @@ int __init parse_iomem(char *str, int *add)
                goto out_close;
        }
 
-       size = (buf.ust_size + UM_KERN_PAGE_SIZE) & ~(UM_KERN_PAGE_SIZE - 1);
+       size = (buf.st_size + UM_KERN_PAGE_SIZE) & ~(UM_KERN_PAGE_SIZE - 1);
 
        *new = ((struct iomem_region) { .next           = iomem_regions,
                                        .driver         = driver,
@@ -532,10 +492,154 @@ int __init parse_iomem(char *str, int *add)
        iomem_regions = new;
        iomem_size += new->size + UM_KERN_PAGE_SIZE;
 
-       return(0);
+       return 0;
  out_close:
-       os_close_file(fd);
+       close(fd);
  out:
-       return(1);
+       return 1;
+}
+
+
+/* Changed during early boot */
+int pty_output_sigio = 0;
+int pty_close_sigio = 0;
+
+/* Used as a flag during SIGIO testing early in boot */
+static volatile int got_sigio = 0;
+
+static void __init handler(int sig)
+{
+       got_sigio = 1;
+}
+
+struct openpty_arg {
+       int master;
+       int slave;
+       int err;
+};
+
+static void openpty_cb(void *arg)
+{
+       struct openpty_arg *info = arg;
+
+       info->err = 0;
+       if(openpty(&info->master, &info->slave, NULL, NULL, NULL))
+               info->err = -errno;
+}
+
+static int async_pty(int master, int slave)
+{
+       int flags;
+
+       flags = fcntl(master, F_GETFL);
+       if(flags < 0)
+               return -errno;
+
+       if((fcntl(master, F_SETFL, flags | O_NONBLOCK | O_ASYNC) < 0) ||
+          (fcntl(master, F_SETOWN, os_getpid()) < 0))
+               return -errno;
+
+       if((fcntl(slave, F_SETFL, flags | O_NONBLOCK) < 0))
+               return -errno;
+
+       return(0);
+}
+
+static void __init check_one_sigio(void (*proc)(int, int))
+{
+       struct sigaction old, new;
+       struct openpty_arg pty = { .master = -1, .slave = -1 };
+       int master, slave, err;
+
+       initial_thread_cb(openpty_cb, &pty);
+       if(pty.err){
+               printk("openpty failed, errno = %d\n", -pty.err);
+               return;
+       }
+
+       master = pty.master;
+       slave = pty.slave;
+
+       if((master == -1) || (slave == -1)){
+               printk("openpty failed to allocate a pty\n");
+               return;
+       }
+
+       /* Not now, but complain so we now where we failed. */
+       err = raw(master);
+       if (err < 0)
+               panic("check_sigio : __raw failed, errno = %d\n", -err);
+
+       err = async_pty(master, slave);
+       if(err < 0)
+               panic("tty_fds : sigio_async failed, err = %d\n", -err);
+
+       if(sigaction(SIGIO, NULL, &old) < 0)
+               panic("check_sigio : sigaction 1 failed, errno = %d\n", errno);
+       new = old;
+       new.sa_handler = handler;
+       if(sigaction(SIGIO, &new, NULL) < 0)
+               panic("check_sigio : sigaction 2 failed, errno = %d\n", errno);
+
+       got_sigio = 0;
+       (*proc)(master, slave);
+
+       close(master);
+       close(slave);
+
+       if(sigaction(SIGIO, &old, NULL) < 0)
+               panic("check_sigio : sigaction 3 failed, errno = %d\n", errno);
+}
+
+static void tty_output(int master, int slave)
+{
+       int n;
+       char buf[512];
+
+       printk("Checking that host ptys support output SIGIO...");
+
+       memset(buf, 0, sizeof(buf));
+
+       while(os_write_file(master, buf, sizeof(buf)) > 0) ;
+       if(errno != EAGAIN)
+               panic("check_sigio : write failed, errno = %d\n", errno);
+       while(((n = os_read_file(slave, buf, sizeof(buf))) > 0) && !got_sigio) ;
+
+       if(got_sigio){
+               printk("Yes\n");
+               pty_output_sigio = 1;
+       }
+       else if(n == -EAGAIN) printk("No, enabling workaround\n");
+       else panic("check_sigio : read failed, err = %d\n", n);
+}
+
+static void tty_close(int master, int slave)
+{
+       printk("Checking that host ptys support SIGIO on close...");
+
+       close(slave);
+       if(got_sigio){
+               printk("Yes\n");
+               pty_close_sigio = 1;
+       }
+       else printk("No, enabling workaround\n");
+}
+
+void __init check_sigio(void)
+{
+       if((os_access("/dev/ptmx", OS_ACC_R_OK) < 0) &&
+          (os_access("/dev/ptyp0", OS_ACC_R_OK) < 0)){
+               printk("No pseudo-terminals available - skipping pty SIGIO "
+                      "check\n");
+               return;
+       }
+       check_one_sigio(tty_output);
+       check_one_sigio(tty_close);
+}
+
+void os_check_bugs(void)
+{
+       check_ptrace();
+       check_sigio();
 }