On Wed, Jul 2, 2008 at 12:45 AM, Peter Teoh <htmldeveloper@xxxxxxxxx> wrote: > On Mon, Jun 30, 2008 at 7:55 PM, Mulyadi Santosa > <mulyadi.santosa@xxxxxxxxx> wrote: >> Hi! >> >> On Sat, Jun 28, 2008 at 4:02 PM, Peter Teoh <htmldeveloper@xxxxxxxxx> wrote: >>> Looked the last few lines of this: >>> >>> http://lkml.org/lkml/2003/7/10/74 >>> >>> >>> I am trying to trying to understand the control path of IDT in userspace vs >>> kernelspace: >>> >>> 1. The patch mentioned NMI can returned back to userspace.....is that >>> correct? >> >> yes...think like this, interrupt can come anytime...whether you're in >> user mode or kernel mode. So logically, after you're being >> interrupted, you come back to the place you were interrupted, right? >> >>> How and where in the kernel is this return to userspace >>> controlled/directed? >> >> IIRC, entry.S...but i forgot in which directory the file resides. >> >> Check the file...i am sure you get the idea... the label like >> "ret_from_fork" (kinda OOT, just to give you idea) will ease you to >> make conclusion.. >> > > Yes, your memory is superb, Mulyadi - in arch/x86/kernel/entry_32.S: > > ENTRY(ret_from_fork) > CFI_STARTPROC > pushl %eax > CFI_ADJUST_CFA_OFFSET 4 > call schedule_tail > GET_THREAD_INFO(%ebp) > popl %eax > CFI_ADJUST_CFA_OFFSET -4 > pushl $0x0202 # Reset kernel eflags > CFI_ADJUST_CFA_OFFSET 4 > popfl > CFI_ADJUST_CFA_OFFSET -4 > jmp syscall_exit > CFI_ENDPROC > END(ret_from_fork) > > /* > * Return to user mode is not as complex as all this looks, > * but we want the default path for a system call return to > * go as quickly as possible which is why some of this is > * less clear than it otherwise should be. > */ > > # userspace resumption stub bypassing syscall exit tracing > ALIGN > RING0_PTREGS_FRAME > ret_from_exception: > preempt_stop(CLBR_ANY) > ret_from_intr: > GET_THREAD_INFO(%ebp) > check_userspace: > movl PT_EFLAGS(%esp), %eax # mix EFLAGS and CS > movb PT_CS(%esp), %al > andl $(X86_EFLAGS_VM | SEGMENT_RPL_MASK), %eax > cmpl $USER_RPL, %eax > jb resume_kernel # not returning to v8086 or userspace > > ENTRY(resume_userspace) > LOCKDEP_SYS_EXIT > DISABLE_INTERRUPTS(CLBR_ANY) # make sure we don't miss an interrupt > # setting need_resched or sigpending > # between sampling and the iret > TRACE_IRQS_OFF > movl TI_flags(%ebp), %ecx > andl $_TIF_WORK_MASK, %ecx # is there any work to be done on > # int/exception return? > jne work_pending > > >> >>> 2. When in userspace, the IDT table - which have the return address of the >>> functions in the kernel...cannot be used. So how is the control path of >>> "int 3" looked like when processes execute it? Userspace will have >>> exception handling etc....but I think all these processing comes after the >>> kernel handle the exception right? And these userspace exception are >>> therefore controlled by kernel - where is it? >> >> you were talking about ptrace-ing, right? it's the parent (the one >> that issued ptrace command) that will check the ptraced process's >> stack frame and target process' PID. >> >> Specifically, in the context of ptrace, it's not just the instruction >> that's replaced by INT 3, but kernel also deliver SIGCHLD (if I >> remember correctly) to the ptracing process. That way, the tracing >> process know the ptraced process has hit the INT 3.... >> > > Let me check out your statement. But my question was actually this: > > Insert the following into your code: > > __asm {int 3} and execute it as a userspace program. > > What happened? How does the OS handle the exception in the userspace > program, or generally, any exception that it encountered (eg, div by > zero)? In kernel these will trigger the hardware IDT into action. > But how about userspace - it ought to right? But it cannot see the > IDT's address right (since these are kernel address)....so how it > flow? > Part of answer is here --> which is kill_pgrp() - the following is for handling ctrl-C receive from user scenario: http://lkml.org/lkml/2008/7/1/250 > diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c > index 8096389..74018ef 100644 > --- a/drivers/char/n_tty.c > +++ b/drivers/char/n_tty.c > @@ -759,20 +759,9 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c) > signal = SIGTSTP; > if (c == SUSP_CHAR(tty)) { > send_signal: > - /* > - * Echo character, and then send the signal. > - * Note that we do not use isig() here because we want > - * the order to be: > - * 1) flush, 2) echo, 3) signal > - */ > - if (!L_NOFLSH(tty)) { > - n_tty_flush_buffer(tty); > - tty_driver_flush_buffer(tty); > - } > if (L_ECHO(tty)) > echo_char(c, tty); > - if (tty->pgrp) > - kill_pgrp(tty->pgrp, signal, 1); > + isig(signal, tty, 0); > return; > } > } so effectively, the propagation of the interrupt processing is via kill_pgrp(). Correct? Which somehow...should flow back to userspace program's exception handler --> correct? (as decided and controlled by glibc) > > Thanks again. > >> I hope I clear your doubts. >> >> regards, >> >> Mulyadi. >> > > > > -- > Regards, > Peter Teoh > -- Regards, Peter Teoh -- To unsubscribe from this list: send an email with "unsubscribe kernelnewbies" to ecartis@xxxxxxxxxxxx Please read the FAQ at http://kernelnewbies.org/FAQ