x86: clean up switch_to()
Make the code more readable and more hackable: - use symbolic asm parameters - use readable indentation - add comments that explains the details No code changed: kernel/sched.o: text data bss dec hex filename 28626 684 2640 31950 7cce sched.o.before 28626 684 2640 31950 7cce sched.o.after md5: 2823d406c18b781975cdb2e7cfea0059 sched.o.before.asm 2823d406c18b781975cdb2e7cfea0059 sched.o.after.asm Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
parent
ecd94c0809
commit
23b55bd9f3
1 changed files with 31 additions and 15 deletions
|
@ -27,22 +27,38 @@ struct task_struct *__switch_to(struct task_struct *prev,
|
|||
* Saving eflags is important. It switches not only IOPL between tasks,
|
||||
* it also protects other tasks from NT leaking through sysenter etc.
|
||||
*/
|
||||
#define switch_to(prev, next, last) do { \
|
||||
#define switch_to(prev, next, last) \
|
||||
do { \
|
||||
unsigned long esi, edi; \
|
||||
asm volatile("pushfl\n\t" /* Save flags */ \
|
||||
"pushl %%ebp\n\t" \
|
||||
"movl %%esp,%0\n\t" /* save ESP */ \
|
||||
"movl %5,%%esp\n\t" /* restore ESP */ \
|
||||
"movl $1f,%1\n\t" /* save EIP */ \
|
||||
"pushl %6\n\t" /* restore EIP */ \
|
||||
"jmp __switch_to\n" \
|
||||
"1:\t" \
|
||||
"popl %%ebp\n\t" \
|
||||
"popfl" \
|
||||
:"=m" (prev->thread.sp), "=m" (prev->thread.ip), \
|
||||
"=a" (last), "=S" (esi), "=D" (edi) \
|
||||
:"m" (next->thread.sp), "m" (next->thread.ip), \
|
||||
"2" (prev), "d" (next)); \
|
||||
\
|
||||
asm volatile( \
|
||||
"pushfl \n\t" /* save flags */ \
|
||||
"pushl %%ebp \n\t" /* save EBP */ \
|
||||
"movl %%esp,%[prev_sp] \n\t" /* save ESP */ \
|
||||
"movl %[next_sp],%%esp \n\t" /* restore ESP */ \
|
||||
"movl $1f,%[prev_ip] \n\t" /* save EIP */ \
|
||||
"pushl %[next_ip] \n\t" /* restore EIP */ \
|
||||
"jmp __switch_to \n" /* regparm call */ \
|
||||
"1: \t" \
|
||||
"popl %%ebp \n\t" /* restore EBP */ \
|
||||
"popfl \n" /* restore flags */ \
|
||||
\
|
||||
/* output parameters */ \
|
||||
: [prev_sp] "=m" (prev->thread.sp), \
|
||||
[prev_ip] "=m" (prev->thread.ip), \
|
||||
"=a" (last), \
|
||||
\
|
||||
/* clobbered output registers: */ \
|
||||
"=S" (esi), "=D" (edi) \
|
||||
\
|
||||
/* input parameters: */ \
|
||||
: [next_sp] "m" (next->thread.sp), \
|
||||
[next_ip] "m" (next->thread.ip), \
|
||||
\
|
||||
/* regparm parameters for __switch_to(): */ \
|
||||
[prev] "a" (prev), \
|
||||
[next] "d" (next) \
|
||||
); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
|
|
Reference in a new issue