Tuesday, 14 August 2018

Linux internals segmentation fault generation


Linux process has many sections. Vaguely speaking these sections can be data, text, stack heap etc.
When a Linux process is created these sections are formed and virtual memory is allocated to these.

Presence of these sections in Linux kernel.

Each of these sections are represented by vm_area_struct in Linux.

The Linux task_struct has memory struct in mm_struct. The mm_struct has vm_area_struct for all these sections.

For all the sections the virtual address will be accessed.

https://en.wikipedia.org/wiki/Memory_management_unit MMU diagram tells the translation of virtual memory to physical memory by CPU/MMU.

The MMU part of CPU checks if the virtual to physical translation is present in the TLB cache.
If no translation exist in TLB it raises an page fault exception.

As a result of the Page fault exception the page fault handler is called.

In Linux the page fault handler is do_page_fault function. In the do_page_fault function faulting address is taken from the cr2 register: read_cr2();

__do_page_fault is called. This function checks if there is vm_area_struct present for the faulting address.

If the virtual area is present in a VMA then good_area handling is invoked, else it goes bad_area function:

bad_area function : 
Eventually a SEGV is generated in __bad_area_nosemaphore function.
tsk->thread.cr2 = address;
tsk->thread.error_code = error_code;
tsk->thread.trap_nr = X86_TRAP_PF;

force_sig_info_fault(SIGSEGV, si_code, address, tsk, 0);


good_area handling :
If we see that the faulting address is correct then handle_mm_fault function is called to allocate a new page frame, similar to the demand paging explained in the Memory Initialization topic.

No comments:

Post a comment