aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-x86/system.h
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2008-03-05 04:24:37 -0500
committerIngo Molnar <mingo@elte.hu>2008-04-17 11:40:52 -0400
commit23b55bd9f33a1812a664e548803db34c9bec56e8 (patch)
tree0559906e87b50567941f983560017671de13f9b3 /include/asm-x86/system.h
parentecd94c0809eb0ff50b628fa061c531a6fbf2fbbc (diff)
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>
Diffstat (limited to 'include/asm-x86/system.h')
-rw-r--r--include/asm-x86/system.h46
1 files changed, 31 insertions, 15 deletions
diff --git a/include/asm-x86/system.h b/include/asm-x86/system.h
index 428d9471497f..299ae9605cb1 100644
--- a/include/asm-x86/system.h
+++ b/include/asm-x86/system.h
@@ -27,22 +27,38 @@ struct task_struct *__switch_to(struct task_struct *prev,
27 * Saving eflags is important. It switches not only IOPL between tasks, 27 * Saving eflags is important. It switches not only IOPL between tasks,
28 * it also protects other tasks from NT leaking through sysenter etc. 28 * it also protects other tasks from NT leaking through sysenter etc.
29 */ 29 */
30#define switch_to(prev, next, last) do { \ 30#define switch_to(prev, next, last) \
31do { \
31 unsigned long esi, edi; \ 32 unsigned long esi, edi; \
32 asm volatile("pushfl\n\t" /* Save flags */ \ 33 \
33 "pushl %%ebp\n\t" \ 34 asm volatile( \
34 "movl %%esp,%0\n\t" /* save ESP */ \ 35 "pushfl \n\t" /* save flags */ \
35 "movl %5,%%esp\n\t" /* restore ESP */ \ 36 "pushl %%ebp \n\t" /* save EBP */ \
36 "movl $1f,%1\n\t" /* save EIP */ \ 37 "movl %%esp,%[prev_sp] \n\t" /* save ESP */ \
37 "pushl %6\n\t" /* restore EIP */ \ 38 "movl %[next_sp],%%esp \n\t" /* restore ESP */ \
38 "jmp __switch_to\n" \ 39 "movl $1f,%[prev_ip] \n\t" /* save EIP */ \
39 "1:\t" \ 40 "pushl %[next_ip] \n\t" /* restore EIP */ \
40 "popl %%ebp\n\t" \ 41 "jmp __switch_to \n" /* regparm call */ \
41 "popfl" \ 42 "1: \t" \
42 :"=m" (prev->thread.sp), "=m" (prev->thread.ip), \ 43 "popl %%ebp \n\t" /* restore EBP */ \
43 "=a" (last), "=S" (esi), "=D" (edi) \ 44 "popfl \n" /* restore flags */ \
44 :"m" (next->thread.sp), "m" (next->thread.ip), \ 45 \
45 "2" (prev), "d" (next)); \ 46 /* output parameters */ \
47 : [prev_sp] "=m" (prev->thread.sp), \
48 [prev_ip] "=m" (prev->thread.ip), \
49 "=a" (last), \
50 \
51 /* clobbered output registers: */ \
52 "=S" (esi), "=D" (edi) \
53 \
54 /* input parameters: */ \
55 : [next_sp] "m" (next->thread.sp), \
56 [next_ip] "m" (next->thread.ip), \
57 \
58 /* regparm parameters for __switch_to(): */ \
59 [prev] "a" (prev), \
60 [next] "d" (next) \
61 ); \
46} while (0) 62} while (0)
47 63
48/* 64/*