Merge branch 'x86-fpu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'x86-fpu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: x86, fpu: Merge fpu_save_init() x86-32, fpu: Rewrite fpu_save_init() x86, fpu: Remove PSHUFB_XMM5_* macros x86, fpu: Remove unnecessary ifdefs from i387 code. x86-32, fpu: Remove math_emulate stub x86-64, fpu: Simplify constraints for fxsave/fxtstor x86-64, fpu: Fix %cs value in convert_from_fxsr() x86-64, fpu: Disable preemption when using TS_USEDFPU x86, fpu: Merge __save_init_fpu() x86, fpu: Merge tolerant_fwait() x86, fpu: Merge fpu_init() x86: Use correct type for %cr4 x86, xsave: Disable xsave in i387 emulation mode Fixed up fxsaveq-induced conflict in arch/x86/include/asm/i387.h
This commit is contained in:
@ -68,19 +68,22 @@ static void __cpuinit init_thread_xstate(void)
|
||||
*/
|
||||
|
||||
if (!HAVE_HWFP) {
|
||||
/*
|
||||
* Disable xsave as we do not support it if i387
|
||||
* emulation is enabled.
|
||||
*/
|
||||
setup_clear_cpu_cap(X86_FEATURE_XSAVE);
|
||||
setup_clear_cpu_cap(X86_FEATURE_XSAVEOPT);
|
||||
xstate_size = sizeof(struct i387_soft_struct);
|
||||
return;
|
||||
}
|
||||
|
||||
if (cpu_has_fxsr)
|
||||
xstate_size = sizeof(struct i387_fxsave_struct);
|
||||
#ifdef CONFIG_X86_32
|
||||
else
|
||||
xstate_size = sizeof(struct i387_fsave_struct);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
/*
|
||||
* Called at bootup to set up the initial FPU state that is later cloned
|
||||
* into all processes.
|
||||
@ -88,12 +91,21 @@ static void __cpuinit init_thread_xstate(void)
|
||||
|
||||
void __cpuinit fpu_init(void)
|
||||
{
|
||||
unsigned long oldcr0 = read_cr0();
|
||||
unsigned long cr0;
|
||||
unsigned long cr4_mask = 0;
|
||||
|
||||
set_in_cr4(X86_CR4_OSFXSR);
|
||||
set_in_cr4(X86_CR4_OSXMMEXCPT);
|
||||
if (cpu_has_fxsr)
|
||||
cr4_mask |= X86_CR4_OSFXSR;
|
||||
if (cpu_has_xmm)
|
||||
cr4_mask |= X86_CR4_OSXMMEXCPT;
|
||||
if (cr4_mask)
|
||||
set_in_cr4(cr4_mask);
|
||||
|
||||
write_cr0(oldcr0 & ~(X86_CR0_TS|X86_CR0_EM)); /* clear TS and EM */
|
||||
cr0 = read_cr0();
|
||||
cr0 &= ~(X86_CR0_TS|X86_CR0_EM); /* clear TS and EM */
|
||||
if (!HAVE_HWFP)
|
||||
cr0 |= X86_CR0_EM;
|
||||
write_cr0(cr0);
|
||||
|
||||
if (!smp_processor_id())
|
||||
init_thread_xstate();
|
||||
@ -104,24 +116,12 @@ void __cpuinit fpu_init(void)
|
||||
clear_used_math();
|
||||
}
|
||||
|
||||
#else /* CONFIG_X86_64 */
|
||||
|
||||
void __cpuinit fpu_init(void)
|
||||
{
|
||||
if (!smp_processor_id())
|
||||
init_thread_xstate();
|
||||
}
|
||||
|
||||
#endif /* CONFIG_X86_32 */
|
||||
|
||||
void fpu_finit(struct fpu *fpu)
|
||||
{
|
||||
#ifdef CONFIG_X86_32
|
||||
if (!HAVE_HWFP) {
|
||||
finit_soft_fpu(&fpu->state->soft);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (cpu_has_fxsr) {
|
||||
struct i387_fxsave_struct *fx = &fpu->state->fxsave;
|
||||
@ -386,19 +386,17 @@ convert_from_fxsr(struct user_i387_ia32_struct *env, struct task_struct *tsk)
|
||||
#ifdef CONFIG_X86_64
|
||||
env->fip = fxsave->rip;
|
||||
env->foo = fxsave->rdp;
|
||||
/*
|
||||
* should be actually ds/cs at fpu exception time, but
|
||||
* that information is not available in 64bit mode.
|
||||
*/
|
||||
env->fcs = task_pt_regs(tsk)->cs;
|
||||
if (tsk == current) {
|
||||
/*
|
||||
* should be actually ds/cs at fpu exception time, but
|
||||
* that information is not available in 64bit mode.
|
||||
*/
|
||||
asm("mov %%ds, %[fos]" : [fos] "=r" (env->fos));
|
||||
asm("mov %%cs, %[fcs]" : [fcs] "=r" (env->fcs));
|
||||
savesegment(ds, env->fos);
|
||||
} else {
|
||||
struct pt_regs *regs = task_pt_regs(tsk);
|
||||
|
||||
env->fos = 0xffff0000 | tsk->thread.ds;
|
||||
env->fcs = regs->cs;
|
||||
env->fos = tsk->thread.ds;
|
||||
}
|
||||
env->fos |= 0xffff0000;
|
||||
#else
|
||||
env->fip = fxsave->fip;
|
||||
env->fcs = (u16) fxsave->fcs | ((u32) fxsave->fop << 16);
|
||||
|
Reference in New Issue
Block a user