Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

x86: save/restore eflags in context switch

(And reset it on new thread creation)

It turns out that eflags is important to save and restore not just
because of iopl, but due to the magic bits like the NT bit, which we
don't want leaking between different threads.

Tested-by: Mike Galbraith <efault@gmx.de>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

+11 -1
+4
arch/i386/kernel/entry.S
··· 209 209 GET_THREAD_INFO(%ebp) 210 210 popl %eax 211 211 CFI_ADJUST_CFA_OFFSET -4 212 + pushl $0x0202 # Reset kernel eflags 213 + CFI_ADJUST_CFA_OFFSET 4 214 + popfl 215 + CFI_ADJUST_CFA_OFFSET -4 212 216 jmp syscall_exit 213 217 CFI_ENDPROC 214 218
+7 -1
include/asm-i386/system.h
··· 11 11 struct task_struct; /* one of the stranger aspects of C forward declarations.. */ 12 12 extern struct task_struct * FASTCALL(__switch_to(struct task_struct *prev, struct task_struct *next)); 13 13 14 + /* 15 + * Saving eflags is important. It switches not only IOPL between tasks, 16 + * it also protects other tasks from NT leaking through sysenter etc. 17 + */ 14 18 #define switch_to(prev,next,last) do { \ 15 19 unsigned long esi,edi; \ 16 - asm volatile("pushl %%ebp\n\t" \ 20 + asm volatile("pushfl\n\t" /* Save flags */ \ 21 + "pushl %%ebp\n\t" \ 17 22 "movl %%esp,%0\n\t" /* save ESP */ \ 18 23 "movl %5,%%esp\n\t" /* restore ESP */ \ 19 24 "movl $1f,%1\n\t" /* save EIP */ \ ··· 26 21 "jmp __switch_to\n" \ 27 22 "1:\t" \ 28 23 "popl %%ebp\n\t" \ 24 + "popfl" \ 29 25 :"=m" (prev->thread.esp),"=m" (prev->thread.eip), \ 30 26 "=a" (last),"=S" (esi),"=D" (edi) \ 31 27 :"m" (next->thread.esp),"m" (next->thread.eip), \