Commit 23b55bd9 authored by Ingo Molnar's avatar Ingo Molnar
Browse files

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: default avatarIngo Molnar <mingo@elte.hu>
parent ecd94c08
Loading
Loading
Loading
Loading
+31 −15
Original line number Diff line number Diff line
@@ -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"				\
									\
	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"					\
		     "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));				\
		"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)

/*