linux-um archives
 help / color / mirror / Atom feed
From: Alex LIU <alex.liu@st.com>
To: UML-dev <user-mode-linux-devel@lists.sourceforge.net>
Subject: [uml-devel] Segmentation fault with kernel thread in UML-2.6.7 TT mode
Date: Fri, 15 Jul 2005 17:59:59 +0800	[thread overview]
Message-ID: <001401c58923$f6dee2b0$9eb3c68a@SHZ.ST.COM> (raw)

Hi,all:

I just modified the kernel thread function in UML 2.6.7 tt mode. I want the kernel thread go to the user space after finished the kernel function rather than exit. It's just like a system call return or a return from fork...

But now the problem is that there will be segmentation fault just before the kernel thread go to the user space. After tracing I found when the segmentation fault occur, in handle_page_fault function, (!(vma->vm_flags & VM_GROWSDOWN)) is true and the err is -14. What's the meaning of such value?

I modified the new_thread_handler function with regarding to finish_fork_handler function. (also add pt_regs as a parameter of the kernel thread function)
My modified new_thread_handler function is following:
-------------------------------------------------------
static void new_thread_handler(int sig)
{
        unsigned long disable;
        int (*fn)(void *);
        void *arg;
        struct pt_regs *regs;
                                                                                                                             
        fn = current->thread.request.u.thread.proc;
        arg = current->thread.request.u.thread.arg;
                                                                                                                             
        regs = &current->thread.regs;
                                                                                                                             
        UPT_SC(&current->thread.regs.regs) = (void *) (&sig + 1);
        disable = (1 << (SIGVTALRM - 1)) | (1 << (SIGALRM - 1)) |
                (1 << (SIGIO - 1)) | (1 << (SIGPROF - 1));
        SC_SIGMASK(UPT_SC(&current->thread.regs.regs)) &= ~disable;                                                                                                                             
                                                                       
        suspend_new_thread(current->thread.mode.tt.switch_pipe[0]);
                                                                                                                             
        force_flush_all();
        if(current->thread.prev_sched != NULL)
                schedule_tail(current->thread.prev_sched);
        current->thread.prev_sched = NULL;
                                                                                                                             
        init_new_thread_signals(1);
        enable_timer();
                                                                                                                             
        change_sig(SIGVTALRM, 1);
        local_irq_enable();
        if(current->mm != current->parent->mm)
                protect_memory(uml_reserved, high_physmem - uml_reserved, 1,
                               1, 0, 1);
        task_protections((unsigned long) current_thread);
                                                                                                                             
                                                                                                                             
        free_page(current->thread.temp_stack);
        set_cmdline("(bproc kernel thread)");
                                                                                                                             
        change_sig(SIGUSR1, 1);
        change_sig(SIGPROF, 1);
                                                                                                                             
        if(!run_kernel_thread(fn, regs, arg, &current->thread.exec_buf)){
                local_irq_disable();
                change_sig(SIGUSR1, 0);
                set_user_mode(current);
        }
                                                                                                                             
        /* XXX No set_user_mode here because a newly execed process will
         * immediately segfault on its non-existent IP, coming straight back
         * to the signal handler, which will call set_user_mode on its way
         * out.  This should probably change since it's confusing.
         */
}
----------------------------------------------
For convenience,I also attached the original UML functions:

void finish_fork_handler(int sig)
{
        UPT_SC(&current->thread.regs.regs) = (void *) (&sig + 1);
        suspend_new_thread(current->thread.mode.tt.switch_pipe[0]);
                                                                                                                             
        force_flush_all();
        if(current->thread.prev_sched != NULL)
                schedule_tail(current->thread.prev_sched);
        current->thread.prev_sched = NULL;
                                                                                                                             
        enable_timer();
        change_sig(SIGVTALRM, 1);
        local_irq_enable();
        if(current->mm != current->parent->mm)
                protect_memory(uml_reserved, high_physmem - uml_reserved, 1,
                               1, 0, 1);
        task_protections((unsigned long) current_thread);
                                                                                                                             
        free_page(current->thread.temp_stack);
        local_irq_disable();
        change_sig(SIGUSR1, 0);
        set_user_mode(current);
}

static void new_thread_handler(int sig)
{
        unsigned long disable;
        int (*fn)(void *);
        void *arg;
                                                                                                                             
        fn = current->thread.request.u.thread.proc;
        arg = current->thread.request.u.thread.arg;
                                                                                                                             
        UPT_SC(&current->thread.regs.regs) = (void *) (&sig + 1);
        disable = (1 << (SIGVTALRM - 1)) | (1 << (SIGALRM - 1)) |
                (1 << (SIGIO - 1)) | (1 << (SIGPROF - 1));
        SC_SIGMASK(UPT_SC(&current->thread.regs.regs)) &= ~disable;
                                                                                                                             
        suspend_new_thread(current->thread.mode.tt.switch_pipe[0]);
                                                                                                                             
        force_flush_all();
        if(current->thread.prev_sched != NULL)
                schedule_tail(current->thread.prev_sched);
        current->thread.prev_sched = NULL;
                                                                                                                             
        init_new_thread_signals(1);
        enable_timer();
        free_page(current->thread.temp_stack);
        set_cmdline("(kernel thread)");
                                                                                                                             
        change_sig(SIGUSR1, 1);
        change_sig(SIGVTALRM, 1);
        change_sig(SIGPROF, 1);
        local_irq_enable();
        if(!run_kernel_thread(fn, arg, &current->thread.exec_buf))
                do_exit(0);
                                                                                                                             
        /* XXX No set_user_mode here because a newly execed process will
         * immediately segfault on its non-existent IP, coming straight back
         * to the signal handler, which will call set_user_mode on its way
         * out.  This should probably change since it's confusing.
         */
}
------------------------------------------------
I also modified the copy_thread_tt function and create the sigcontext for the kernel thread just like fork:
------------------------------------------------
         sc_to_sc(UPT_SC(&p->thread.regs.regs),
                UPT_SC(&current->thread.regs.regs));
         SC_SET_SYSCALL_RETURN(UPT_SC(&p->thread.regs.regs), 0);
         if(sp != 0) SC_SP(UPT_SC(&p->thread.regs.regs)) = sp;
------------------------------------------------

Any ideas? 
Thanks a lot!

Alex



-------------------------------------------------------
SF.Net email is sponsored by: Discover Easy Linux Migration Strategies
from IBM. Find simple to follow Roadmaps, straightforward articles,
informative Webcasts and more! Get everything you need to get up to
speed, fast. http://ads.osdn.com/?ad_idt77&alloc_id\x16492&op�k
_______________________________________________
User-mode-linux-devel mailing list
User-mode-linux-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel

             reply	other threads:[~2005-07-15 10:00 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-07-15  9:59 Alex LIU [this message]
2005-07-15 18:25 ` [uml-devel] Segmentation fault with kernel thread in UML-2.6.7 TT mode Blaisorblade
2005-07-17  7:52   ` Alex LIU
2005-07-17 14:09     ` Jeff Dike
2005-08-12 18:38     ` Blaisorblade

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='001401c58923$f6dee2b0$9eb3c68a@SHZ.ST.COM' \
    --to=alex.liu@st.com \
    --cc=user-mode-linux-devel@lists.sourceforge.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox