Monday, October 20, 2014

How a system call is executed in X86 architecture?

  • A vector in the interrupt descriptor table (IDT) is used to invoke the system call. 
  • Only one vector is allocated for the system calls.
  • Immediately a question comes into our mind that since there is only one vector so how so many system calls can be serviced?
  • This is done by having a generic function (we can say an ISR) which will multiplex all other system calls. 
  • That means when an interrupt (software interrupt using INT instruction) is raised on this vector, the generic function will be called and a system call number is passed as an argument to this function.
  • This generic function uses this system call number as an index into the sys_call_table array and gets the address (function pointer) of the system call and invokes that system call. 
  • arch/x86/kernel/syscall_64.c#L25
  • Interrupt vector used for the system call is 0x80(128), i.e interrupt descriptor table's 128th entry.(80 in hex is 128 in decimal).
  •  128th entry in the IDT table contains the address of the system_call() function. system_call() is defined in arch/x86/kernel/entry_32.S.

493         RING0_INT_FRAME                 # can't unwind into user space anyway
494         ASM_CLAC
495         pushl_cfi %eax                  # save orig_eax
496         SAVE_ALL
497         GET_THREAD_INFO(%ebp)
498                                         # system call tracing in operation / emulation
499         testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%ebp)
500         jnz syscall_trace_entry
501         cmpl $(NR_syscalls), %eax
502         jae syscall_badsys
503 syscall_call:
504         call *sys_call_table(,%eax,4)