alistair23-linux/arch/x86
Suresh Siddha 75118a82e2 x86: fix NULL pointer deref in __switch_to
Patrick McHardy reported a crash:

> > I get this oops once a day, its apparently triggered by something
> > run by cron, but the process is a different one each time.
> >
> > Kernel is -git from yesterday shortly before the -rc6 release
> > (last commit is the usb-2.6 merge, the x86 patches are missing),
> > .config is attached.
> >
> > I'll retry with current -git, but the patches that have gone in
> > since I last updated don't look related.
> >
> > [62060.043009] BUG: unable to handle kernel NULL pointer dereference at
> > 000001ff
> > [62060.043009] IP: [<c0102a9b>] __switch_to+0x2f/0x118
> > [62060.043009] *pde = 00000000
> > [62060.043009] Oops: 0002 [#1] PREEMPT

Vegard Nossum analyzed it:

> This decodes to
>
>    0:   0f ae 00                fxsave (%eax)
>
> so it's related to the floating-point context. This is the exact
> location of the crash:
>
> $ addr2line -e arch/x86/kernel/process_32.o -i ab0
> include/asm/i387.h:232
> include/asm/i387.h:262
> arch/x86/kernel/process_32.c:595
>
> ...so it looks like prev_task->thread.xstate->fxsave has become NULL.
> Or maybe it never had any other value.

Somehow (as described below) TS_USEDFPU is set but the fpu is not
allocated or freed.

Another possible FPU pre-emption issue with the sleazy FPU optimization
which was benign before but not so anymore, with the dynamic FPU allocation
patch.

New task is getting exec'd and it is prempted at the below point.

flush_thread() {
	...
	/*
	* Forget coprocessor state..
	*/
	clear_fpu(tsk);
		<----- Preemption point
	clear_used_math();
	...
}

Now when it context switches in again, as the used_math() is still set
and fpu_counter can be > 5, we will do a math_state_restore() which sets
the task's TS_USEDFPU. After it continues from the above preemption point
it does clear_used_math() and much later free_thread_xstate().

Now, at the next context switch, it is quite possible that xstate is
null, used_math() is not set and TS_USEDFPU is still set. This will
trigger unlazy_fpu() causing kernel oops.

Fix this  by clearing tsk's fpu_counter before clearing task's fpu.

Reported-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2008-06-19 10:08:45 +02:00
..
boot x86: fix unused variable 'loops' warning in arch/x86/boot/a20.c 2008-06-12 21:27:05 +02:00
configs
crypto
ia32 signals: x86 TS_RESTORE_SIGMASK 2008-04-30 08:29:37 -07:00
kernel x86: fix NULL pointer deref in __switch_to 2008-06-19 10:08:45 +02:00
kvm KVM: MMU: Fix is_empty_shadow_page() check 2008-06-06 21:36:33 +03:00
lguest lguest: fix ugly <NULL> in /proc/interrupts 2008-05-30 15:09:43 +10:00
lib x86-64: Fix "bytes left to copy" return value for copy_from_user() 2008-06-17 17:47:50 -07:00
mach-default
mach-es7000
mach-generic
mach-rdc321x
mach-visws
mach-voyager x86, voyager: fix ioremap_nocache() 2008-04-30 23:15:34 +02:00
math-emu x86: fix broken math-emu with lazy allocation of fpu area 2008-06-04 13:11:46 +02:00
mm Merge branch 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip 2008-06-12 12:55:32 -07:00
oprofile
pci Merge branch 'pci-for-jesse' of git://git.kernel.org/pub/scm/linux/kernel/git/x86/linux-2.6-tip into for-linus 2008-06-12 13:51:05 -07:00
power
vdso x86: use explicit copy in vdso_gettimeofday() 2008-05-23 14:08:06 +02:00
video x86: video/fbdev.c: add MODULE_LICENSE 2008-05-04 20:04:46 +02:00
xen common implementation of iterative div/mod 2008-06-12 10:47:56 +02:00
Kconfig PCI/x86: fix up PCI stuff so that PCI_GOANY supports OLPC 2008-06-05 14:29:25 -07:00
Kconfig.cpu x86: CONFIG_X86_ELAN fix 2008-04-30 23:15:35 +02:00
Kconfig.debug x86: fix CONFIG_NONPROMISC_DEVMEM prompt and help text 2008-06-05 14:21:45 -07:00
Makefile
Makefile_32.cpu