]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/um/os-Linux/skas/process.c
Merge branch 'for-linus' of git://git.kernel.dk/data/git/linux-2.6-block
[linux-2.6-omap-h63xx.git] / arch / um / os-Linux / skas / process.c
index 0036164bb0fb48e1b99d0f2827865ff8f33c97fc..d77c81d7068a06309ecf935ee0ccb9938d4cd8b6 100644 (file)
@@ -177,7 +177,7 @@ static int userspace_tramp(void *stack)
 
        ptrace(PTRACE_TRACEME, 0, 0, 0);
 
-       init_new_thread_signals();
+       signal(SIGTERM, SIG_DFL);
        err = set_interval();
        if (err)
                panic("userspace_tramp - setting timer failed, errno = %d\n",
@@ -191,22 +191,23 @@ static int userspace_tramp(void *stack)
                int fd;
                unsigned long long offset;
                fd = phys_mapping(to_phys(&__syscall_stub_start), &offset);
-               addr = mmap64((void *) UML_CONFIG_STUB_CODE, UM_KERN_PAGE_SIZE,
+               addr = mmap64((void *) STUB_CODE, UM_KERN_PAGE_SIZE,
                              PROT_EXEC, MAP_FIXED | MAP_PRIVATE, fd, offset);
                if (addr == MAP_FAILED) {
-                       printk(UM_KERN_ERR "mapping mmap stub failed, "
-                              "errno = %d\n", errno);
+                       printk(UM_KERN_ERR "mapping mmap stub at 0x%lx failed, "
+                              "errno = %d\n", STUB_CODE, errno);
                        exit(1);
                }
 
                if (stack != NULL) {
                        fd = phys_mapping(to_phys(stack), &offset);
-                       addr = mmap((void *) UML_CONFIG_STUB_DATA,
+                       addr = mmap((void *) STUB_DATA,
                                    UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE,
                                    MAP_FIXED | MAP_SHARED, fd, offset);
                        if (addr == MAP_FAILED) {
                                printk(UM_KERN_ERR "mapping segfault stack "
-                                      "failed, errno = %d\n", errno);
+                                      "at 0x%lx failed, errno = %d\n",
+                                      STUB_DATA, errno);
                                exit(1);
                        }
                }
@@ -214,15 +215,14 @@ static int userspace_tramp(void *stack)
        if (!ptrace_faultinfo && (stack != NULL)) {
                struct sigaction sa;
 
-               unsigned long v = UML_CONFIG_STUB_CODE +
+               unsigned long v = STUB_CODE +
                                  (unsigned long) stub_segv_handler -
                                  (unsigned long) &__syscall_stub_start;
 
-               set_sigstack((void *) UML_CONFIG_STUB_DATA, UM_KERN_PAGE_SIZE);
+               set_sigstack((void *) STUB_DATA, UM_KERN_PAGE_SIZE);
                sigemptyset(&sa.sa_mask);
                sigaddset(&sa.sa_mask, SIGIO);
                sigaddset(&sa.sa_mask, SIGWINCH);
-               sigaddset(&sa.sa_mask, SIGALRM);
                sigaddset(&sa.sa_mask, SIGVTALRM);
                sigaddset(&sa.sa_mask, SIGUSR1);
                sa.sa_flags = SA_ONSTACK;
@@ -287,10 +287,18 @@ int start_userspace(unsigned long stub_stack)
 
 void userspace(struct uml_pt_regs *regs)
 {
+       struct itimerval timer;
+       unsigned long long nsecs, now;
        int err, status, op, pid = userspace_pid[0];
        /* To prevent races if using_sysemu changes under us.*/
        int local_using_sysemu;
 
+       if (getitimer(ITIMER_VIRTUAL, &timer))
+               printk("Failed to get itimer, errno = %d\n", errno);
+       nsecs = timer.it_value.tv_sec * UM_NSEC_PER_SEC +
+               timer.it_value.tv_usec * UM_NSEC_PER_USEC;
+       nsecs += os_nsecs();
+
        while (1) {
                restore_registers(pid, regs);
 
@@ -333,8 +341,20 @@ void userspace(struct uml_pt_regs *regs)
                        case SIGTRAP:
                                relay_signal(SIGTRAP, regs);
                                break;
-                       case SIGIO:
                        case SIGVTALRM:
+                               now = os_nsecs();
+                               if(now < nsecs)
+                                       break;
+                               block_signals();
+                               (*sig_info[sig])(sig, regs);
+                               unblock_signals();
+                               nsecs = timer.it_value.tv_sec *
+                                       UM_NSEC_PER_SEC +
+                                       timer.it_value.tv_usec *
+                                       UM_NSEC_PER_USEC;
+                               nsecs += os_nsecs();
+                               break;
+                       case SIGIO:
                        case SIGILL:
                        case SIGBUS:
                        case SIGFPE:
@@ -363,10 +383,10 @@ static int __init init_thread_regs(void)
 {
        get_safe_registers(thread_regs);
        /* Set parent's instruction pointer to start of clone-stub */
-       thread_regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE +
+       thread_regs[REGS_IP_INDEX] = STUB_CODE +
                                (unsigned long) stub_clone_handler -
                                (unsigned long) &__syscall_stub_start;
-       thread_regs[REGS_SP_INDEX] = UML_CONFIG_STUB_DATA + UM_KERN_PAGE_SIZE -
+       thread_regs[REGS_SP_INDEX] = STUB_DATA + UM_KERN_PAGE_SIZE -
                sizeof(void *);
 #ifdef __SIGNAL_FRAMESIZE
        thread_regs[REGS_SP_INDEX] -= __SIGNAL_FRAMESIZE;
@@ -378,6 +398,7 @@ __initcall(init_thread_regs);
 
 int copy_context_skas0(unsigned long new_stack, int pid)
 {
+       struct timeval tv = { .tv_sec = 0, .tv_usec = UM_USEC_PER_SEC / UM_HZ };
        int err;
        unsigned long current_stack = current_stub_stack();
        struct stub_data *data = (struct stub_data *) current_stack;
@@ -392,9 +413,9 @@ int copy_context_skas0(unsigned long new_stack, int pid)
        *data = ((struct stub_data) { .offset   = MMAP_OFFSET(new_offset),
                                      .fd       = new_fd,
                                      .timer    = ((struct itimerval)
-                                                   { { 0, 1000000 / UM_HZ },
-                                                     { 0, 1000000 / UM_HZ }})
-                                });
+                                                  { .it_value = tv,
+                                                    .it_interval = tv }) });
+
        err = ptrace_setregs(pid, thread_regs);
        if (err < 0)
                panic("copy_context_skas0 : PTRACE_SETREGS failed, "
@@ -423,7 +444,7 @@ int copy_context_skas0(unsigned long new_stack, int pid)
         * child's stack and check it.
         */
        wait_stub_done(pid);
-       if (child_data->err != UML_CONFIG_STUB_DATA)
+       if (child_data->err != STUB_DATA)
                panic("copy_context_skas0 - stub-child reports error %ld\n",
                      child_data->err);
 
@@ -520,8 +541,7 @@ int start_idle_thread(void *stack, jmp_buf *switch_buf)
        int n;
 
        set_handler(SIGWINCH, (__sighandler_t) sig_handler,
-                   SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGALRM,
-                   SIGVTALRM, -1);
+                   SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGVTALRM, -1);
 
        /*
         * Can't use UML_SETJMP or UML_LONGJMP here because they save