Friday, 14 September 2018

entry_64.S

entry_64.S is collection of functions written in assembly. This file has many routines which are used in interrupts, system calls etc.
Let us see one by one how many such routines are present in this file.

Functions present in this file :

A) save_rest : Handle the saving of extra registers

B) ret_from_fork : This function is executed by the child process right after its creation through a fork
Called from :
1. copy_thread
 p->thread.ip = (unsigned long) ret_from_fork;
This is done to set the new threads instruction pointer.

2. /* Save restore flags to clear handle leaking NT */
#define switch_to(prev, next, last) \
...
     "jnz   ret_from_fork\n\t"   \
...
From switch_to the function ret_from_fork is called if the program was never executed.


C) system_call : This is the entry of any system call.

MSR_LSTAR is initialised with this function at startup.
This fiunction calls the system call function from the sys_call_table :
call *sys_call_table(,%rax,8)  # XXX: rip relative

Also entry to system call and return from system call is handled.
ret_from_sys_call :
on a return for system call the process scheduling in called :
...
 SCHEDULE_USER
...
# define SCHEDULE_USER call schedule


D)  The various stub functions are usually entries in the sys_call_table

stub_execve, stub_rt_sigreturn, stub_x32_execve
0 syscalls_64.h       60 __SYSCALL_64(59, stub_execve, stub_execve)
1 sys_call_table_64.c 33 #define stub_execve sys_execve

0 syscalls_64.h       16 __SYSCALL_64(15, stub_rt_sigreturn, stub_rt_sigreturn)
1 sys_call_table_64.c 34 #define stub_rt_sigreturn sys_rt_sigreturn

0 syscalls_64.h 309 __SYSCALL_X32(513, stub_x32_rt_sigreturn, stub_x32_rt_sigreturn)

0 syscalls_64.h 316 __SYSCALL_X32(520, stub_x32_execve, stub_x32_execve)


E) interrupt and "irq_entries_start"
ENTRY(interrupt)
ENTRY(irq_entries_start)
In native_init_IRQ the interrupt entry is used to initialize IDT with the defaults :
set_intr_gate(i, interrupt[i - FIRST_EXTERNAL_VECTOR]);

F) Interrupt entry/exit
Now comes the interrupt entry and exit functions. Under common_interrupt label we see that do_IRQ function is called.

If interrupt came when we were in kernel mode then control jumps to retint_kernel which calls for scheduling:

retint_kernel :
 preempt_schedule_irq
 void __sched preempt_schedule_irq(void)
  ...
  local_irq_enable();
  __schedule();
  local_irq_disable();
  ...

If interrupt came when we were in USER mode then control jumps to retint_careful which calls for scheduling:
retint_careful:
...
SCHEDULE_USER
...

G) ENTRY(call_softirq)
Call softirq on interrupt stack. This function is called from do_softirq()

No comments:

Post a Comment