/* clobbers ebx, edx and ebp */
#define __SWITCH_KERNELSPACE \ cmpl $0xff000000, %esp; \ jb 1f; \ \ /* \ * switch pagetables and load the real stack, \ * keep the stack offset: \ */ \ \ movl $swapper_pg_dir-__PAGE_OFFSET, %edx; \ \ /* GET_THREAD_INFO(%ebp) intermixed */ \ 0: \ ……………………………………. \ 1:
#endif
#define __SWITCH_USERSPACE \ /* interrupted any of the user return paths? */ \ \ movl EIP(%esp), %eax; \ ……………………………………….. \ jb 22f; /* yes - switch to virtual stack */ \ /* return to userspace? */ \ 44: \ movl EFLAGS(%esp),%ecx; \ movb CS(%esp),%cl; \ testl $(VM_MASK | 3),%ecx; \ jz 2f; \ 22: \ /* \ * switch to the virtual stack, then switch to \ * the userspace pagetables. \ */ \ \ GET_THREAD_INFO(%ebp); \ movl TI_virtual_stack(%ebp), %edx; \ movl TI_user_pgd(%ebp), %ecx; \ \ movl %esp, %ebx; \ andl $(THREAD_SIZE-1), %ebx; \ orl %ebx, %edx; \ int80_ret_start_marker: \ movl %edx, %esp; \ movl %ecx, %cr3; \ \ __RESTORE_ALL; \ int80_ret_end_marker: \ 2:
#else /* !CONFIG_X86_HIGH_ENTRY */
#define __SWITCH_KERNELSPACE #define __SWITCH_USERSPACE
#endif
#define __SAVE_ALL \ ……………………………………..
#define __RESTORE_INT_REGS \ ………………………….
#define __RESTORE_REGS \ __RESTORE_INT_REGS; \ 111: popl %ds; \ 222: popl %es; \ .section .fixup,"ax"; \ 444: movl $0,(%esp); \ jmp 111b; \ 555: movl $0,(%esp); \ jmp 222b; \ .previous; \ .section __ex_table,"a";\ .align 4; \ .long 111b,444b;\ .long 222b,555b;\ .previous
#define __RESTORE_ALL \ __RESTORE_REGS \ addl $4, %esp; \ 333: iret; \ .section .fixup,"ax"; \ 666: sti; \ movl $(__USER_DS), %edx; \ movl %edx, %ds; \ movl %edx, %es; \ pushl $11; \ call do_exit; \ .previous; \ .section __ex_table,"a";\ .align 4; \ .long 333b,666b;\ .previous
#define SAVE_ALL \ __SAVE_ALL; \ __SWITCH_KERNELSPACE;
#define RESTORE_ALL \ __SWITCH_USERSPACE; \ __RESTORE_ALL;
|