0
votes

having an assembly user-space program like this:

_start:
data: db"DATA..........."
    mov eax, 5

result in CPU executing data which will result in a Hardware exception which is supposed to be catch by linux kernal which will result in segmentation fault and terminating the program. My question is how CPU tell kernal about the exception and if there is some details (like division by zero or data execution exception) and how it knows what next instruction to execute when an exception like this happen to deal with the exception (something like kernal hardware exception handler I guess)

2
will result in a Hardware exception - not if that data happens to be a sequence of valid machine instructions (no #UD illegal instruction), and which don't page-fault (no invalid memory operands), or other exceptions. So really it's no different from asking how the kernel handles divide-by-zero, page-fault, or other exceptions (including illegal instruction) - Peter Cordes

2 Answers

3
votes

My question is how CPU tell kernel about the exception ...

... and how it knows what next instruction to execute ...

On x86 CPUs, exceptions are interrupts (just like hardware interrupts or interrupts called by the int instruction):

When some exception happens, the CPU will push the address of the instruction and some other information on the kernel's stack and jump to the address specified in the interrupt vector table.

The kernel may read the address pushed on the stack to get information about which instruction caused the exception.

... and if there is some details ...

Different types of exceptions call different interrupt vectors:

A "division by zero" will cause a jump to the address specified in the first entry in the interrupt vector table; a "page fault" will cause a jump to the address specified in the 15th entry of that table.

The OS has different "exception handlers" (assembly programs which are called by the hardware in the case of an exception) for different kinds of exceptions. The addresses of these handlers are stored in the interrupt vector table. The CPU will read the address of the handler from that table.

For some exception types (e.g. "general protection fault") the CPU writes additional information to the stack. For other exception types (e.g. "page fault") there are special registers containing additional information.

3
votes

Executing arbitrary data will generally lead to an undefined instruction exception, #UD. (But it could also cause a page fault, GP fault, or some other exception first. And there’s a possibility it could get into a loop with no fault.)

When the CPU detects a fault, it transitions to kernel mode and loads the descriptor from the IDT corresponding to the fault number (descriptor 6 for #UD). It pushes the current SS, RSP, flags, CS, and RIP onto the kernel stack. It starts executing kernel code at the address in the IDT descriptor. The kernel can tell it was #UD instead of some other exception by the address of the handler that begins executing.