在trap_init中對SYSCALL_VECTOR(編號0x80)的向量進行初始化。
808 set_system_trap_gate(SYSCALL_VECTOR, &system_call);將system call初始化為trap門,加入到IDT table中,發生中斷以后,會跳轉到對應system_call的地址去執行后續的中斷流程。發生中斷到跳轉執行中斷向量的過程在kernel 中斷分析三——中斷處理流程有詳細解釋,本篇只關注system_call的運行過程。
_TIF_ALLWORK_MASK 的定義如下:
144 /* Work to do on any return to user space. */145 #define _TIF_ALLWORK_MASK /146 (_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_SINGLESTEP|/147 _TIF_ASYNC_TLB|_TIF_NOTIFY_RESUME)當以下情況之一發生時,返回用戶態之前需要進入syscall_exit_work處理: 1. 當前進程有信號pending 2. 當前進程需要被重新調度 3. 設置了_TIF_SINGLESTEP,restore singlestep on return to user mode 4. got an async TLB fault in kernel 5. callback before returning to user
670 syscall_exit_work: 671 testl $_TIF_WORK_SYSCALL_EXIT, %ecx----------1 672 jz work_pending 673 TRACE_IRQS_ON 674 ENABLE_INTERRUPTS(CLBR_ANY) # could let syscall_trace_leave() call 675 # schedule() instead 676 movl %esp, %eax 677 call syscall_trace_leave 678 jmp resume_userspace------------------------2 679 END(syscall_exit_work)檢測是否有work pending否則開中斷然后返回用戶態 607 work_pending: 608 testb $_TIF_NEED_RESCHED, %cl -------------1 609 jz work_notifysig -------------2 610 work_resched: -------------3 611 call schedule 612 LOCKDEP_SYS_EXIT 613 DISABLE_INTERRUPTS(CLBR_ANY) # make sure we don't miss an interrupt 614 # setting need_resched or sigpending 615 # between sampling and the iret 616 TRACE_IRQS_OFF 617 movl TI_flags(%ebp), %ecx 618 andl $_TIF_WORK_MASK, %ecx # is there any work to be done other 619 # than syscall tracing? 620 jz restore_all 621 testb $_TIF_NEED_RESCHED, %cl 622 jnz work_resched 623 624 work_notifysig: # deal with pending signals and-------------------4 625 # notify-resume requests 626 #ifdef CONFIG_VM86 627 testl $X86_EFLAGS_VM, PT_EFLAGS(%esp) 628 movl %esp, %eax 629 jne work_notifysig_v86 # returning to kernel-space or 630 # vm86-space 631 1: 632 #else 633 movl %esp, %eax 634 #endif 635 TRACE_IRQS_ON 636 ENABLE_INTERRUPTS(CLBR_NONE) 637 movb PT_CS(%esp), %bl 638 andb $SEGMENT_RPL_MASK, %bl 639 cmpb $USER_RPL, %bl 640 jb resume_kernel 641 xorl %edx, %edx 642 call do_notify_resume -------------------5 643 jmp resume_userspace 644 645 #ifdef CONFIG_VM86 646 ALIGN 647 work_notifysig_v86: 648 pushl_cfi %ecx # save ti_flags for do_notify_resume 649 call save_v86_state # %eax contains pt_regs pointer 650 popl_cfi %ecx 651 movl %eax, %esp 652 jmp 1b 653 #endif 654 END(work_pending)檢測_TIF_NEED_RESCHED,若被設置,跳轉到work_resched,否則跳轉到work_notifysig,進行信號處理調用schedule主動讓出CPU處理pending的信號,具體的處理流程在do_notify_resume 中的do_signal整個處理流程用流程圖表現得更加直觀:
新聞熱點
疑難解答