Context switch in Linux ©Gabriel Kliot, Technion
Memory layout – general picture Stack Stack Stack Process X user memory Process Y user memory Process Z user memory Stack Process X kernel stack and task_struct task_struct Stack Process Y kernel stack and task_struct task_struct Stack Process Z kernel stack and task_struct task_struct TSS of CPU i tss->esp0 Kernel memory ©Gabriel Kliot, Technion
©Gabriel Kliot, Technion #1 – kernel stack after any system call, before context switch prev ss esp eflags cs eip orig_eax es ds eax ebp edi esi edx ecx ebx User Stack User Code … TSS … … tss->esp0 Schedule() function frame esp Saved on the kernel stack during transition to kernel mode by int80 and by SAVE_ALL macro task_struct thread.esp0 ©Gabriel Kliot, Technion
#2 – stack of prev before switch_to macro in schedule() func … Schedule() saved EAX, ECX, EDX Arguments to contex_switch() Return address to schedule() TSS Old (schedule’s()) EBP tss->esp0 … esp task_struct thread.eip thread.esp thread.esp0 ©Gabriel Kliot, Technion
#3 – switch_to: save esi, edi, ebp on the stack of prev … Schedule() saved EAX, ECX, EDX Arguments to contex_switch() Return address to schedule() TSS Old (schedule’s()) EBP tss->esp0 … ESI EDI EBP esp task_struct thread.eip thread.esp thread.esp0 ©Gabriel Kliot, Technion
#4 – switch_to: save esp in prev->thread.esp … Schedule() saved EAX, ECX, EDX Arguments to contex_switch() Return address to schedule() TSS Old (schedule’s()) EBP tss->esp0 … ESI EDI EBP esp task_struct thread.eip thread.esp thread.esp0 ©Gabriel Kliot, Technion
#5 – switch_to: load next->thread.esp into esp prev next … … Schedule() saved EAX, ECX, EDX Schedule() saved EAX, ECX, EDX Arguments to contex_switch() Arguments to contex_switch() Return address to schedule() TSS Return address to schedule() Old (schedule’s()) EBP Old (schedule’s()) EBP tss->esp0 … … ESI ESI EDI EDI EBP EBP esp task_struct thread.eip thread.esp thread.esp0 task_struct thread.eip $1f thread.esp thread.esp0 ©Gabriel Kliot, Technion
#6 – switch_to: save return address in the prev->thread.eip next … … Schedule() saved EAX, ECX, EDX Schedule() saved EAX, ECX, EDX Arguments to contex_switch() Arguments to contex_switch() Return address to schedule() TSS Return address to schedule() Old (schedule’s()) EBP Old (schedule’s()) EBP tss->esp0 … … ESI ESI EDI EDI EBP EBP esp task_struct thread.eip thread.esp thread.esp0 task_struct $1f thread.eip $1f thread.esp thread.esp0 ©Gabriel Kliot, Technion
#7 – switch_to: save return address on the stack of next prev next … … Schedule() saved EAX, ECX, EDX Schedule() saved EAX, ECX, EDX Arguments to contex_switch() Arguments to contex_switch() Return address to schedule() TSS Return address to schedule() Old (schedule’s()) EBP Old (schedule’s()) EBP tss->esp0 … … ESI ESI EDI EDI EBP EBP $1f esp task_struct thread.eip thread.esp thread.esp0 task_struct $1f thread.eip $1f thread.esp thread.esp0 ©Gabriel Kliot, Technion
#8 – __switch_to func: save the base of next’s stack in TSS prev next … … TSS tss->esp0 Schedule() saved EAX, ECX, EDX Schedule() saved EAX, ECX, EDX Arguments to contex_switch() Arguments to contex_switch() Return address to schedule() Return address to schedule() Old (schedule’s()) EBP Old (schedule’s()) EBP … … ESI ESI EDI EDI EBP EBP $1f esp task_struct thread.eip thread.esp thread.esp0 task_struct $1f thread.eip $1f thread.esp thread.esp0 ©Gabriel Kliot, Technion
#9 – back in switch_to: eip points to $1f instruction label prev next … … TSS tss->esp0 Schedule() saved EAX, ECX, EDX Schedule() saved EAX, ECX, EDX Arguments to contex_switch() Arguments to contex_switch() Return address to schedule() Return address to schedule() Old (schedule’s()) EBP Old (schedule’s()) EBP … … ESI ESI eip 1: EDI EDI EBP EBP esp task_struct thread.eip thread.esp thread.esp0 task_struct $1f thread.eip $1f thread.esp thread.esp0 ©Gabriel Kliot, Technion
#10 – switch_to: restore esi, edi, ebp from the stack of next prev next … … Schedule() saved EAX, ECX, EDX Schedule() saved EAX, ECX, EDX Arguments to contex_switch() Arguments to contex_switch() Return address to schedule() TSS tss->esp0 Return address to schedule() Old (schedule’s()) EBP Old (schedule’s()) EBP … … esp ESI EDI EBP task_struct thread.eip thread.esp thread.esp0 task_struct $1f thread.eip $1f thread.esp thread.esp0 ©Gabriel Kliot, Technion