Messages in this thread | | | Date | Wed, 21 Mar 2007 21:25:04 +0200 | Subject | Re: i386: Why putting __USER_DS in kernel threads stack initialization? | From | "Ahmed S. Darwish" <> |
| |
On Mon, Mar 19, 2007 at 07:23:25AM -0400, linux-os (Dick Johnson) wrote: > > On Sun, 18 Mar 2007, Ahmed S. Darwish wrote: > > > Hi list, > > > > Reading the kernel threads initialization code I see: > > > > int kernel_thread(...) { > > > > struct pt_regs regs; > > memset(®s, 0, sizeof(regs)); > > [...] > > ** regs.xds = __USER_DS; > > ** regs.xes = __USER_DS; > > [...] > > /* Ok, create the new process.. */ > > return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, \ > > 0, NULL, NULL); > > > > Continuing with the code, the threads stack (beginning from %esp) is > > initialized with the passed *regs from do_fork: > > > > int copy_thread(..., struct task_struct *p, struct pt_regs *regs) { > > > > struct pt_regs * childregs; > > struct task_struct *tsk; > > childregs = task_pt_regs(p); > > ** *childregs = *regs; > > [...] > > ** p->thread.esp = (unsigned long) childregs; > > > > > > So the question is what will a _kernel_ thread do with the Usermode Segment > > address ? > > > > Thanks, > > > > P.S. I've tried commenting out both lines which led to a non functional init, > > Also setting them to __USER_DS made init start but stopped issuing the error: > > `Panic: Segment violation at 0x8049798 - Sleeping for 30 seconds' > >
Sorry, I meant "setting them to __KERNEL_DS" here.
> > You might be confusing two routines. The kernel thread routine sets > DS and ES to the kernel data segment, __KERNEL_DS, not the user data > segment.
And that's what's _not_ happening in the code as I mentioned in original post.
> This is so the kernel thread can access the kernel data. Note > that this is done by putting the values in the pt_regs structure so > it doesn't happen 'now', but after the fork.
I've searched the code for such case (setting xds to __KERNEL_DS _After_ copy_thread()) with no success. As I understand, the kernel thread executes the passed function immediately (when given control by scheduler):
i386/kernel/process::kernel_thread(): ** regs.ebx = (unsigned long) fn; regs.edx = (unsigned long) arg; regs.xds = __USER_DS; regs.xes = __USER_DS; regs.xfs = __KERNEL_PDA; regs.orig_eax = -1; ** regs.eip = (unsigned long) kernel_thread_helper; do_fork(...)
entry.S::kernel_thread_helper (removing CFI_* pseudo ops):
ENTRY(kernel_thread_helper) pushl $0 movl %edx,%eax push %edx ** call *%ebx push %eax call do_exit
Am I interpreting the forking process completely wrong?. I'm just curious why the __USER_DS is playing a vital rule in kernel threads regs/stack ?
Thanks alot,
-- Ahmed S. Darwish http://darwish.07.googlepages.com
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |