Commit 448ba078 authored by Linus Torvalds's avatar Linus Torvalds

v2.4.0.2 -> v2.4.0.3

  - me: clean up XMM support
parent 3192b2dc
......@@ -33,7 +33,7 @@
void init_fpu(void)
{
__asm__("fninit");
if ( HAVE_XMM )
if ( cpu_has_xmm )
load_mxcsr(0x1f80);
current->used_math = 1;
......@@ -43,9 +43,9 @@ void init_fpu(void)
* FPU lazy state save handling.
*/
void save_init_fpu( struct task_struct *tsk )
static inline void __save_init_fpu( struct task_struct *tsk )
{
if ( HAVE_FXSR ) {
if ( cpu_has_fxsr ) {
asm volatile( "fxsave %0 ; fnclex"
: "=m" (tsk->thread.i387.fxsave) );
} else {
......@@ -53,12 +53,28 @@ void save_init_fpu( struct task_struct *tsk )
: "=m" (tsk->thread.i387.fsave) );
}
tsk->flags &= ~PF_USEDFPU;
}
void save_init_fpu( struct task_struct *tsk )
{
__save_init_fpu(tsk);
stts();
}
void kernel_fpu_begin(void)
{
struct task_struct *tsk = current;
if (tsk->flags & PF_USEDFPU) {
__save_init_fpu(tsk);
return;
}
clts();
}
void restore_fpu( struct task_struct *tsk )
{
if ( HAVE_FXSR ) {
if ( cpu_has_fxsr ) {
asm volatile( "fxrstor %0"
: : "m" (tsk->thread.i387.fxsave) );
} else {
......@@ -136,7 +152,7 @@ static inline unsigned long twd_fxsr_to_i387( struct i387_fxsave_struct *fxsave
unsigned short get_fpu_cwd( struct task_struct *tsk )
{
if ( HAVE_FXSR ) {
if ( cpu_has_fxsr ) {
return tsk->thread.i387.fxsave.cwd;
} else {
return (unsigned short)tsk->thread.i387.fsave.cwd;
......@@ -145,7 +161,7 @@ unsigned short get_fpu_cwd( struct task_struct *tsk )
unsigned short get_fpu_swd( struct task_struct *tsk )
{
if ( HAVE_FXSR ) {
if ( cpu_has_fxsr ) {
return tsk->thread.i387.fxsave.swd;
} else {
return (unsigned short)tsk->thread.i387.fsave.swd;
......@@ -154,7 +170,7 @@ unsigned short get_fpu_swd( struct task_struct *tsk )
unsigned short get_fpu_twd( struct task_struct *tsk )
{
if ( HAVE_FXSR ) {
if ( cpu_has_fxsr ) {
return tsk->thread.i387.fxsave.twd;
} else {
return (unsigned short)tsk->thread.i387.fsave.twd;
......@@ -163,7 +179,7 @@ unsigned short get_fpu_twd( struct task_struct *tsk )
unsigned short get_fpu_mxcsr( struct task_struct *tsk )
{
if ( HAVE_FXSR ) {
if ( cpu_has_fxsr ) {
return tsk->thread.i387.fxsave.mxcsr;
} else {
return 0x1f80;
......@@ -172,7 +188,7 @@ unsigned short get_fpu_mxcsr( struct task_struct *tsk )
void set_fpu_cwd( struct task_struct *tsk, unsigned short cwd )
{
if ( HAVE_FXSR ) {
if ( cpu_has_fxsr ) {
tsk->thread.i387.fxsave.cwd = cwd;
} else {
tsk->thread.i387.fsave.cwd = ((long)cwd | 0xffff0000);
......@@ -181,7 +197,7 @@ void set_fpu_cwd( struct task_struct *tsk, unsigned short cwd )
void set_fpu_swd( struct task_struct *tsk, unsigned short swd )
{
if ( HAVE_FXSR ) {
if ( cpu_has_fxsr ) {
tsk->thread.i387.fxsave.swd = swd;
} else {
tsk->thread.i387.fsave.swd = ((long)swd | 0xffff0000);
......@@ -190,7 +206,7 @@ void set_fpu_swd( struct task_struct *tsk, unsigned short swd )
void set_fpu_twd( struct task_struct *tsk, unsigned short twd )
{
if ( HAVE_FXSR ) {
if ( cpu_has_fxsr ) {
tsk->thread.i387.fxsave.twd = twd_i387_to_fxsr(twd);
} else {
tsk->thread.i387.fsave.twd = ((long)twd | 0xffff0000);
......@@ -199,7 +215,7 @@ void set_fpu_twd( struct task_struct *tsk, unsigned short twd )
void set_fpu_mxcsr( struct task_struct *tsk, unsigned short mxcsr )
{
if ( HAVE_XMM ) {
if ( cpu_has_xmm ) {
tsk->thread.i387.fxsave.mxcsr = mxcsr;
}
}
......@@ -313,7 +329,7 @@ int save_i387( struct _fpstate *buf )
current->used_math = 0;
if ( HAVE_HWFP ) {
if ( HAVE_FXSR ) {
if ( cpu_has_fxsr ) {
return save_i387_fxsave( buf );
} else {
return save_i387_fsave( buf );
......@@ -346,7 +362,7 @@ int restore_i387( struct _fpstate *buf )
int err;
if ( HAVE_HWFP ) {
if ( HAVE_FXSR ) {
if ( cpu_has_fxsr ) {
err = restore_i387_fxsave( buf );
} else {
err = restore_i387_fsave( buf );
......@@ -379,7 +395,7 @@ static inline int get_fpregs_fxsave( struct user_i387_struct *buf,
int get_fpregs( struct user_i387_struct *buf, struct task_struct *tsk )
{
if ( HAVE_HWFP ) {
if ( HAVE_FXSR ) {
if ( cpu_has_fxsr ) {
return get_fpregs_fxsave( buf, tsk );
} else {
return get_fpregs_fsave( buf, tsk );
......@@ -407,7 +423,7 @@ static inline int set_fpregs_fxsave( struct task_struct *tsk,
int set_fpregs( struct task_struct *tsk, struct user_i387_struct *buf )
{
if ( HAVE_HWFP ) {
if ( HAVE_FXSR ) {
if ( cpu_has_fxsr ) {
return set_fpregs_fxsave( tsk, buf );
} else {
return set_fpregs_fsave( tsk, buf );
......@@ -420,7 +436,7 @@ int set_fpregs( struct task_struct *tsk, struct user_i387_struct *buf )
int get_fpxregs( struct user_fxsr_struct *buf, struct task_struct *tsk )
{
if ( HAVE_FXSR ) {
if ( cpu_has_fxsr ) {
if (__copy_to_user( (void *)buf, &tsk->thread.i387.fxsave,
sizeof(struct user_fxsr_struct) ))
return -EFAULT;
......@@ -432,7 +448,7 @@ int get_fpxregs( struct user_fxsr_struct *buf, struct task_struct *tsk )
int set_fpxregs( struct task_struct *tsk, struct user_fxsr_struct *buf )
{
if ( HAVE_FXSR ) {
if ( cpu_has_fxsr ) {
__copy_from_user( &tsk->thread.i387.fxsave, (void *)buf,
sizeof(struct user_fxsr_struct) );
/* mxcsr bit 6 and 31-16 must be zero for security reasons */
......@@ -478,7 +494,7 @@ int dump_fpu( struct pt_regs *regs, struct user_i387_struct *fpu )
fpvalid = tsk->used_math;
if ( fpvalid ) {
unlazy_fpu( tsk );
if ( HAVE_FXSR ) {
if ( cpu_has_fxsr ) {
copy_fpu_fxsave( tsk, fpu );
} else {
copy_fpu_fsave( tsk, fpu );
......@@ -493,7 +509,7 @@ int dump_extended_fpu( struct pt_regs *regs, struct user_fxsr_struct *fpu )
int fpvalid;
struct task_struct *tsk = current;
fpvalid = tsk->used_math && HAVE_FXSR;
fpvalid = tsk->used_math && cpu_has_fxsr;
if ( fpvalid ) {
unlazy_fpu( tsk );
memcpy( fpu, &tsk->thread.i387.fxsave,
......
......@@ -147,7 +147,7 @@ extern char _text, _etext, _edata, _end;
extern unsigned long cpu_khz;
static int disable_x86_serial_nr __initdata = 1;
int disable_x86_fxsr __initdata = 0;
static int disable_x86_fxsr __initdata = 0;
/*
* This is set up by the setup-routine at boot-time
......@@ -2013,6 +2013,12 @@ void __init identify_cpu(struct cpuinfo_x86 *c)
clear_bit(X86_FEATURE_TSC, &c->x86_capability);
#endif
/* FXSR disabled? */
if (disable_x86_fxsr) {
clear_bit(X86_FEATURE_FXSR, &c->x86_capability);
clear_bit(X86_FEATURE_XMM, &c->x86_capability);
}
/* Disable the PN if appropriate */
squash_the_stupid_serial_number(c);
......
......@@ -2,6 +2,8 @@
#include <linux/string.h>
#include <linux/sched.h>
#include <asm/i387.h>
/*
* MMX 3DNow! library helper functions
*
......@@ -26,13 +28,7 @@ void *_mmx_memcpy(void *to, const void *from, size_t len)
void *p=to;
int i= len >> 6; /* len/64 */
if (!(current->flags & PF_USEDFPU))
clts();
else
{
__asm__ __volatile__ ( " fnsave %0; fwait\n"::"m"(current->thread.i387));
current->flags &= ~PF_USEDFPU;
}
kernel_fpu_begin();
__asm__ __volatile__ (
"1: prefetch (%0)\n" /* This set is 28 bytes */
......@@ -88,20 +84,15 @@ void *_mmx_memcpy(void *to, const void *from, size_t len)
* Now do the tail of the block
*/
__memcpy(to, from, len&63);
stts();
kernel_fpu_end();
return p;
}
static void fast_clear_page(void *page)
{
int i;
if (!(current->flags & PF_USEDFPU))
clts();
else
{
__asm__ __volatile__ ( " fnsave %0; fwait\n"::"m"(current->thread.i387));
current->flags &= ~PF_USEDFPU;
}
kernel_fpu_begin();
__asm__ __volatile__ (
" pxor %%mm0, %%mm0\n" : :
......@@ -127,19 +118,14 @@ static void fast_clear_page(void *page)
__asm__ __volatile__ (
" sfence \n" : :
);
stts();
kernel_fpu_end();
}
static void fast_copy_page(void *to, void *from)
{
int i;
if (!(current->flags & PF_USEDFPU))
clts();
else
{
__asm__ __volatile__ ( " fnsave %0; fwait\n"::"m"(current->thread.i387));
current->flags &= ~PF_USEDFPU;
}
kernel_fpu_begin();
/* maybe the prefetch stuff can go before the expensive fnsave...
* but that is for later. -AV
......@@ -199,7 +185,7 @@ static void fast_copy_page(void *to, void *from)
__asm__ __volatile__ (
" sfence \n" : :
);
stts();
kernel_fpu_end();
}
/*
......
......@@ -66,8 +66,6 @@ static double __initdata y = 3145727.0;
*/
static void __init check_fpu(void)
{
extern int disable_x86_fxsr;
if (!boot_cpu_data.hard_math) {
#ifndef CONFIG_MATH_EMULATION
printk(KERN_EMERG "No coprocessor found and no math emulation present.\n");
......@@ -85,19 +83,16 @@ static void __init check_fpu(void)
extern void __buggy_fxsr_alignment(void);
__buggy_fxsr_alignment();
}
if (!disable_x86_fxsr) {
if (cpu_has_fxsr) {
printk(KERN_INFO "Enabling fast FPU save and restore... ");
set_in_cr4(X86_CR4_OSFXSR);
printk("done.\n");
}
if (cpu_has_xmm) {
printk(KERN_INFO "Enabling unmasked SIMD FPU exception support... ");
set_in_cr4(X86_CR4_OSXMMEXCPT);
printk("done.\n");
}
} else
printk(KERN_INFO "Disabling fast FPU save and restore.\n");
if (cpu_has_fxsr) {
printk(KERN_INFO "Enabling fast FPU save and restore... ");
set_in_cr4(X86_CR4_OSFXSR);
printk("done.\n");
}
if (cpu_has_xmm) {
printk(KERN_INFO "Enabling unmasked SIMD FPU exception support... ");
set_in_cr4(X86_CR4_OSXMMEXCPT);
printk("done.\n");
}
/* Test for the divl bug.. */
__asm__("fninit\n\t"
......
......@@ -23,6 +23,10 @@ extern void init_fpu(void);
extern void save_init_fpu( struct task_struct *tsk );
extern void restore_fpu( struct task_struct *tsk );
extern void kernel_fpu_begin(void);
#define kernel_fpu_end() stts()
#define unlazy_fpu( tsk ) do { \
if ( tsk->flags & PF_USEDFPU ) \
save_init_fpu( tsk ); \
......
......@@ -88,8 +88,6 @@ extern struct cpuinfo_x86 cpu_data[];
#define cpu_has_fxsr (test_bit(X86_FEATURE_FXSR, boot_cpu_data.x86_capability))
#define cpu_has_xmm (test_bit(X86_FEATURE_XMM, boot_cpu_data.x86_capability))
#define cpu_has_fpu (test_bit(X86_FEATURE_FPU, boot_cpu_data.x86_capability))
#define HAVE_FXSR (mmu_cr4_features & X86_CR4_OSFXSR)
#define HAVE_XMM (mmu_cr4_features & X86_CR4_OSXMMEXCPT)
extern char ignore_irq13;
......
......@@ -542,14 +542,8 @@ void __free_pages(struct page *page, unsigned long order)
void free_pages(unsigned long addr, unsigned long order)
{
struct page *fpage;
#ifdef CONFIG_DISCONTIGMEM
if (addr == 0) return;
#endif
fpage = virt_to_page(addr);
if (VALID_PAGE(fpage))
__free_pages(fpage, order);
if (addr != 0)
__free_pages(virt_to_page(addr), order);
}
/*
......
......@@ -36,6 +36,7 @@ EXPORT_SYMBOL(rpciod_down);
EXPORT_SYMBOL(rpciod_up);
EXPORT_SYMBOL(rpc_new_task);
EXPORT_SYMBOL(rpc_wake_up_status);
EXPORT_SYMBOL(rpc_release_task);
/* RPC client functions */
EXPORT_SYMBOL(rpc_create_client);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment