* [PATCH] mxcsr patch for i386 & x86-64
@ 2004-05-04 18:50 Kamble, Nitin A
2004-05-04 19:10 ` Linus Torvalds
0 siblings, 1 reply; 12+ messages in thread
From: Kamble, Nitin A @ 2004-05-04 18:50 UTC (permalink / raw)
To: Andrew Morton, Linus Torvalds
Cc: linux-kernel, Nakajima, Jun, Mallick, Asit K, Saxena, Sunil
[-- Attachment #1: Type: text/plain, Size: 312 bytes --]
Hi Andrew, Linus,
Attached is the patch to enable proper mxcsr register masking in
the Linux Kernel.
Please refer to IA32 Software Developer's Manual, Volume 1, Section
11.6.6 for more details.
Thanks & Regards,
Nitin
------------------------------------------------------------------------
-
[-- Attachment #2: mxcsr_i386_x86-64_2.6.6-rc3.patch --]
[-- Type: application/octet-stream, Size: 6253 bytes --]
--- 2.6.6-rc3/arch/i386/kernel/cpu/common.c.orig 2004-05-03 18:00:03.000000000 -0700
+++ 2.6.6-rc3/arch/i386/kernel/cpu/common.c 2004-05-04 11:45:07.000000000 -0700
@@ -536,5 +536,7 @@
*/
current_thread_info()->status = 0;
current->used_math = 0;
+ clts();
+ mxcsr_mask_init();
stts();
}
--- 2.6.6-rc3/arch/i386/kernel/i387.c.orig 2004-05-03 18:02:16.000000000 -0700
+++ 2.6.6-rc3/arch/i386/kernel/i387.c 2004-05-04 11:27:49.000000000 -0700
@@ -10,6 +10,7 @@
#include <linux/config.h>
#include <linux/sched.h>
+#include <linux/init.h>
#include <asm/processor.h>
#include <asm/i387.h>
#include <asm/math_emu.h>
@@ -24,6 +25,22 @@
#define HAVE_HWFP 1
#endif
+static unsigned long common_mxcsr_mask = 0xffffffff;
+
+void mxcsr_mask_init(void)
+{
+ unsigned long mask;
+ if (!cpu_has_fxsr)
+ mask = 0x0;
+ else {
+ memset(¤t->thread.i387.fxsave, 0, sizeof(struct i387_fxsave_struct));
+ asm volatile("fxsave %0" : : "m" (current->thread.i387.fxsave));
+ mask = current->thread.i387.fxsave.mxcsr_mask;
+ if (mask == 0UL) mask = 0x0000ffbf;
+ }
+ common_mxcsr_mask &= mask;
+}
+
/*
* The _current_ task is using the FPU for the first time
* so initialize it and set the mxcsr to its default
@@ -207,7 +224,7 @@
void set_fpu_mxcsr( struct task_struct *tsk, unsigned short mxcsr )
{
if ( cpu_has_xmm ) {
- tsk->thread.i387.fxsave.mxcsr = (mxcsr & 0xffbf);
+ tsk->thread.i387.fxsave.mxcsr = (mxcsr & common_mxcsr_mask);
}
}
@@ -355,8 +372,7 @@
clear_fpu( tsk );
err = __copy_from_user( &tsk->thread.i387.fxsave, &buf->_fxsr_env[0],
sizeof(struct i387_fxsave_struct) );
- /* mxcsr bit 6 and 31-16 must be zero for security reasons */
- tsk->thread.i387.fxsave.mxcsr &= 0xffbf;
+ set_fpu_mxcsr(tsk, tsk->thread.i387.fxsave.mxcsr);
return err ? 1 : convert_fxsr_from_user( &tsk->thread.i387.fxsave, buf );
}
@@ -457,8 +473,7 @@
if (__copy_from_user( &tsk->thread.i387.fxsave, buf,
sizeof(struct user_fxsr_struct) ))
ret = -EFAULT;
- /* mxcsr bit 6 and 31-16 must be zero for security reasons */
- tsk->thread.i387.fxsave.mxcsr &= 0xffbf;
+ set_fpu_mxcsr(tsk, tsk->thread.i387.fxsave.mxcsr);
} else {
ret = -EIO;
}
--- 2.6.6-rc3/arch/x86_64/kernel/i387.c.orig 2004-05-03 18:00:31.000000000 -0700
+++ 2.6.6-rc3/arch/x86_64/kernel/i387.c 2004-05-04 11:27:29.000000000 -0700
@@ -24,6 +24,23 @@
#include <asm/ptrace.h>
#include <asm/uaccess.h>
+static unsigned long common_mxcsr_mask = 0xffffffff;
+
+void set_fpu_mxcsr(struct task_struct *tsk, unsigned short mxcsr)
+{
+ tsk->thread.i387.fxsave.mxcsr = (mxcsr & common_mxcsr_mask);
+}
+
+void mxcsr_mask_init(void)
+{
+ unsigned long mask;
+ memset(¤t->thread.i387.fxsave, 0, sizeof(struct i387_fxsave_struct));
+ asm volatile("fxsave %0" : : "m" (current->thread.i387.fxsave));
+ mask = current->thread.i387.fxsave.mxcsr_mask;
+ if (mask == 0UL) mask = 0x0000ffbf;
+ common_mxcsr_mask &= mask;
+}
+
/*
* Called at bootup to set up the initial FPU state that is later cloned
* into all processes.
@@ -40,6 +57,8 @@
write_cr0(oldcr0 & ~((1UL<<3)|(1UL<<2))); /* clear TS and EM */
+ clts();
+ mxcsr_mask_init();
/* clean state in init */
stts();
current_thread_info()->status = 0;
--- 2.6.6-rc3/arch/x86_64/ia32/fpu32.c.orig 2004-05-03 18:00:02.000000000 -0700
+++ 2.6.6-rc3/arch/x86_64/ia32/fpu32.c 2004-05-03 18:05:10.000000000 -0700
@@ -155,7 +155,7 @@
&buf->_fxsr_env[0],
sizeof(struct i387_fxsave_struct)))
return -1;
- tsk->thread.i387.fxsave.mxcsr &= 0xffbf;
+ set_fpu_mxcsr(tsk, tsk->thread.i387.fxsave.mxcsr);
tsk->used_math = 1;
}
return convert_fxsr_from_user(&tsk->thread.i387.fxsave, buf);
--- 2.6.6-rc3/arch/x86_64/ia32/ptrace32.c.orig 2004-05-03 18:00:31.000000000 -0700
+++ 2.6.6-rc3/arch/x86_64/ia32/ptrace32.c 2004-05-03 18:05:10.000000000 -0700
@@ -357,7 +357,7 @@
/* no checking to be bug-to-bug compatible with i386 */
__copy_from_user(&child->thread.i387.fxsave, u, sizeof(*u));
child->used_math = 1;
- child->thread.i387.fxsave.mxcsr &= 0xffbf;
+ set_fpu_mxcsr(child, child->thread.i387.fxsave.mxcsr);
ret = 0;
break;
}
--- 2.6.6-rc3/include/asm-x86_64/i387.h.orig 2004-05-03 18:01:02.000000000 -0700
+++ 2.6.6-rc3/include/asm-x86_64/i387.h 2004-05-04 11:45:58.000000000 -0700
@@ -52,8 +52,8 @@
} \
} while (0)
-#define load_mxcsr(val) do { \
- unsigned long __mxcsr = ((unsigned long)(val) & 0xffbf); \
+#define load_mxcsr(val, mask) do { \
+ unsigned long __mxcsr = ((unsigned long)(val) & (mask)); \
asm volatile("ldmxcsr %0" : : "m" (__mxcsr)); \
} while (0)
@@ -75,7 +75,7 @@
#define set_fpu_cwd(t,val) ((t)->thread.i387.fxsave.cwd = (val))
#define set_fpu_swd(t,val) ((t)->thread.i387.fxsave.swd = (val))
#define set_fpu_fxsr_twd(t,val) ((t)->thread.i387.fxsave.twd = (val))
-#define set_fpu_mxcsr(t,val) ((t)->thread.i387.fxsave.mxcsr = (val)&0xffbf)
+extern void set_fpu_mxcsr(struct task_struct *tsk, unsigned short mxcsr);
static inline int restore_fpu_checking(struct i387_fxsave_struct *fx)
{
--- 2.6.6-rc3/include/asm-i386/i387.h.orig 2004-05-03 18:01:31.000000000 -0700
+++ 2.6.6-rc3/include/asm-i386/i387.h 2004-05-04 11:42:05.000000000 -0700
@@ -16,6 +16,7 @@
#include <asm/sigcontext.h>
#include <asm/user.h>
+extern void mxcsr_mask_init(void);
extern void init_fpu(struct task_struct *);
/*
* FPU lazy state save handling...
@@ -91,8 +92,8 @@
extern void set_fpu_twd( struct task_struct *tsk, unsigned short twd );
extern void set_fpu_mxcsr( struct task_struct *tsk, unsigned short mxcsr );
-#define load_mxcsr( val ) do { \
- unsigned long __mxcsr = ((unsigned long)(val) & 0xffbf); \
+#define load_mxcsr(val, mask) do { \
+ unsigned long __mxcsr = ((unsigned long)(val) & (mask)); \
asm volatile( "ldmxcsr %0" : : "m" (__mxcsr) ); \
} while (0)
--- 2.6.6-rc3/include/asm-i386/processor.h.orig 2004-05-03 18:00:03.000000000 -0700
+++ 2.6.6-rc3/include/asm-i386/processor.h 2004-05-03 18:05:10.000000000 -0700
@@ -332,7 +332,7 @@
long foo;
long fos;
long mxcsr;
- long reserved;
+ long mxcsr_mask;
long st_space[32]; /* 8*16 bytes for each FP-reg = 128 bytes */
long xmm_space[32]; /* 8*16 bytes for each XMM-reg = 128 bytes */
long padding[56];
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] mxcsr patch for i386 & x86-64
2004-05-04 18:50 [PATCH] mxcsr patch for i386 & x86-64 Kamble, Nitin A
@ 2004-05-04 19:10 ` Linus Torvalds
2004-05-04 19:26 ` Linus Torvalds
0 siblings, 1 reply; 12+ messages in thread
From: Linus Torvalds @ 2004-05-04 19:10 UTC (permalink / raw)
To: Kamble, Nitin A
Cc: Andrew Morton, linux-kernel, Nakajima, Jun, Mallick, Asit K,
Saxena, Sunil
On Tue, 4 May 2004, Kamble, Nitin A wrote:
>
> Attached is the patch to enable proper mxcsr register masking in
> the Linux Kernel.
>
> Please refer to IA32 Software Developer's Manual, Volume 1, Section
> 11.6.6 for more details.
Ahh. Have we verified that the new semantics of that MXCSR_MASK field
works on non-intel CPU's too?
It would also (in my opinion) make sense to just export the
"common_mxcsr_mask" (and probably just rename it as "mxcsr_feature_mask"
or something - where does that "common" come from? Is it just to imply
that it's the bits that all CPU's support "in common", or what?
Right now you export a function that does just a simple mask operation,
and quite frankly, that just seems to make it less clear what the code is
doing. So who not get rid of that "set_fpu_mxcsr()" function, and just
replace all the "0xffbf" uses with "mxcsr_feature_mask"?
Hmm?
Linus
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] mxcsr patch for i386 & x86-64
2004-05-04 19:10 ` Linus Torvalds
@ 2004-05-04 19:26 ` Linus Torvalds
2004-05-04 20:24 ` Linus Torvalds
0 siblings, 1 reply; 12+ messages in thread
From: Linus Torvalds @ 2004-05-04 19:26 UTC (permalink / raw)
To: Kamble, Nitin A
Cc: Andrew Morton, linux-kernel, Nakajima, Jun, Mallick, Asit K,
Saxena, Sunil
On Tue, 4 May 2004, Linus Torvalds wrote:
>
> Right now you export a function that does just a simple mask operation,
> and quite frankly, that just seems to make it less clear what the code is
> doing. So who not get rid of that "set_fpu_mxcsr()" function, and just
> replace all the "0xffbf" uses with "mxcsr_feature_mask"?
I also note that the x86-64 version of has "mxcsr" as "unsigned short" in
set_fpu_mxcsr(). I'd have expected these changes to make it possible to
have feature bits in the high 16 bits too, no?
Linus
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] mxcsr patch for i386 & x86-64
2004-05-04 19:26 ` Linus Torvalds
@ 2004-05-04 20:24 ` Linus Torvalds
2004-05-04 21:07 ` Jeff Garzik
2004-05-05 13:51 ` Pavel Machek
0 siblings, 2 replies; 12+ messages in thread
From: Linus Torvalds @ 2004-05-04 20:24 UTC (permalink / raw)
To: Kamble, Nitin A
Cc: Andrew Morton, linux-kernel, Nakajima, Jun, Mallick, Asit K,
Saxena, Sunil
Ok,
this is my counter-suggestion, based on your patch.
Does this work for you guys? Please re-submit if it passes testing and
otherwise looks good. I can't test it in any sane way..
Linus
----
===== arch/i386/kernel/i387.c 1.19 vs edited =====
--- 1.19/arch/i386/kernel/i387.c Tue Feb 3 21:30:39 2004
+++ edited/arch/i386/kernel/i387.c Tue May 4 13:15:10 2004
@@ -10,6 +10,7 @@
#include <linux/config.h>
#include <linux/sched.h>
+#include <linux/init.h>
#include <asm/processor.h>
#include <asm/i387.h>
#include <asm/math_emu.h>
@@ -24,6 +25,21 @@
#define HAVE_HWFP 1
#endif
+static unsigned long mxcsr_feature_mask = 0xffffffff;
+
+static void __init mxcsr_feature_mask_init(void)
+{
+ unsigned long mask = 0;
+
+ if (cpu_has_fxsr) {
+ memset(¤t->thread.i387.fxsave, 0, sizeof(struct i387_fxsave_struct));
+ asm volatile("fxsave %0" : : "m" (current->thread.i387.fxsave));
+ mask = current->thread.i387.fxsave.mxcsr_mask;
+ if (mask == 0UL) mask = 0x0000ffbf;
+ }
+ mxcsr_feature_mask &= mask;
+}
+
/*
* The _current_ task is using the FPU for the first time
* so initialize it and set the mxcsr to its default
@@ -204,13 +220,6 @@
}
}
-void set_fpu_mxcsr( struct task_struct *tsk, unsigned short mxcsr )
-{
- if ( cpu_has_xmm ) {
- tsk->thread.i387.fxsave.mxcsr = (mxcsr & 0xffbf);
- }
-}
-
/*
* FXSR floating point environment conversions.
*/
@@ -355,8 +364,8 @@
clear_fpu( tsk );
err = __copy_from_user( &tsk->thread.i387.fxsave, &buf->_fxsr_env[0],
sizeof(struct i387_fxsave_struct) );
- /* mxcsr bit 6 and 31-16 must be zero for security reasons */
- tsk->thread.i387.fxsave.mxcsr &= 0xffbf;
+ /* mxcsr reserved bits must be masked to zero for security reasons */
+ tsk->thread.i387.fxsave.mxcsr &= mxcsr_feature_mask;
return err ? 1 : convert_fxsr_from_user( &tsk->thread.i387.fxsave, buf );
}
@@ -457,8 +466,8 @@
if (__copy_from_user( &tsk->thread.i387.fxsave, buf,
sizeof(struct user_fxsr_struct) ))
ret = -EFAULT;
- /* mxcsr bit 6 and 31-16 must be zero for security reasons */
- tsk->thread.i387.fxsave.mxcsr &= 0xffbf;
+ /* mxcsr reserved bits must be masked to zero for security reasons */
+ tsk->thread.i387.fxsave.mxcsr &= mxcsr_feature_mask;
} else {
ret = -EIO;
}
@@ -550,4 +559,11 @@
memcpy(fpu, &tsk->thread.i387.fxsave, sizeof(*fpu));
}
return fpvalid;
+}
+
+void __init fpu_init(void)
+{
+ clts();
+ mxcsr_feature_mask_init();
+ stts();
}
===== arch/i386/kernel/cpu/common.c 1.26 vs edited =====
--- 1.26/arch/i386/kernel/cpu/common.c Mon Dec 29 13:37:31 2003
+++ edited/arch/i386/kernel/cpu/common.c Tue May 4 13:14:44 2004
@@ -536,5 +536,5 @@
*/
current_thread_info()->status = 0;
current->used_math = 0;
- stts();
+ fpu_init();
}
===== arch/x86_64/ia32/fpu32.c 1.6 vs edited =====
--- 1.6/arch/x86_64/ia32/fpu32.c Sat Mar 22 11:41:26 2003
+++ edited/arch/x86_64/ia32/fpu32.c Tue May 4 13:06:43 2004
@@ -155,7 +155,7 @@
&buf->_fxsr_env[0],
sizeof(struct i387_fxsave_struct)))
return -1;
- tsk->thread.i387.fxsave.mxcsr &= 0xffbf;
+ tsk->thread.i387.fxsave.mxcsr &= mxcsr_feature_mask;
tsk->used_math = 1;
}
return convert_fxsr_from_user(&tsk->thread.i387.fxsave, buf);
===== arch/x86_64/ia32/ptrace32.c 1.10 vs edited =====
--- 1.10/arch/x86_64/ia32/ptrace32.c Wed Feb 25 02:31:13 2004
+++ edited/arch/x86_64/ia32/ptrace32.c Tue May 4 13:05:27 2004
@@ -357,10 +357,10 @@
/* no checking to be bug-to-bug compatible with i386 */
__copy_from_user(&child->thread.i387.fxsave, u, sizeof(*u));
child->used_math = 1;
- child->thread.i387.fxsave.mxcsr &= 0xffbf;
+ child->thread.i387.fxsave.mxcsr &= mxcsr_feature_mask;
ret = 0;
- break;
- }
+ break;
+ }
default:
ret = -EINVAL;
===== arch/x86_64/kernel/i387.c 1.10 vs edited =====
--- 1.10/arch/x86_64/kernel/i387.c Fri Jan 23 12:17:58 2004
+++ edited/arch/x86_64/kernel/i387.c Tue May 4 13:07:35 2004
@@ -24,6 +24,18 @@
#include <asm/ptrace.h>
#include <asm/uaccess.h>
+unsigned long mxcsr_feature_mask = 0xffffffff;
+
+static void mxcsr_feature_mask_init(void)
+{
+ unsigned long mask;
+ memset(¤t->thread.i387.fxsave, 0, sizeof(struct i387_fxsave_struct));
+ asm volatile("fxsave %0" : : "m" (current->thread.i387.fxsave));
+ mask = current->thread.i387.fxsave.mxcsr_mask;
+ if (mask == 0UL) mask = 0x0000ffbf;
+ mxcsr_feature_mask &= mask;
+}
+
/*
* Called at bootup to set up the initial FPU state that is later cloned
* into all processes.
@@ -40,6 +52,8 @@
write_cr0(oldcr0 & ~((1UL<<3)|(1UL<<2))); /* clear TS and EM */
+ clts();
+ mxcsr_feature_mask_init();
/* clean state in init */
stts();
current_thread_info()->status = 0;
===== include/asm-i386/i387.h 1.14 vs edited =====
--- 1.14/include/asm-i386/i387.h Sat Oct 4 23:51:00 2003
+++ edited/include/asm-i386/i387.h Tue May 4 13:17:09 2004
@@ -12,10 +12,13 @@
#define __ASM_I386_I387_H
#include <linux/sched.h>
+#include <linux/init.h>
+
#include <asm/processor.h>
#include <asm/sigcontext.h>
#include <asm/user.h>
+extern void __init fpu_init(void);
extern void init_fpu(struct task_struct *);
/*
* FPU lazy state save handling...
@@ -89,12 +92,6 @@
extern void set_fpu_cwd( struct task_struct *tsk, unsigned short cwd );
extern void set_fpu_swd( struct task_struct *tsk, unsigned short swd );
extern void set_fpu_twd( struct task_struct *tsk, unsigned short twd );
-extern void set_fpu_mxcsr( struct task_struct *tsk, unsigned short mxcsr );
-
-#define load_mxcsr( val ) do { \
- unsigned long __mxcsr = ((unsigned long)(val) & 0xffbf); \
- asm volatile( "ldmxcsr %0" : : "m" (__mxcsr) ); \
-} while (0)
/*
* Signal frame handlers...
===== include/asm-i386/processor.h 1.60 vs edited =====
--- 1.60/include/asm-i386/processor.h Mon Apr 12 10:54:21 2004
+++ edited/include/asm-i386/processor.h Tue May 4 12:37:44 2004
@@ -332,7 +332,7 @@
long foo;
long fos;
long mxcsr;
- long reserved;
+ long mxcsr_mask;
long st_space[32]; /* 8*16 bytes for each FP-reg = 128 bytes */
long xmm_space[32]; /* 8*16 bytes for each XMM-reg = 128 bytes */
long padding[56];
===== include/asm-x86_64/i387.h 1.9 vs edited =====
--- 1.9/include/asm-x86_64/i387.h Fri May 23 03:22:07 2003
+++ edited/include/asm-x86_64/i387.h Tue May 4 13:07:48 2004
@@ -23,6 +23,8 @@
extern void init_fpu(struct task_struct *child);
extern int save_i387(struct _fpstate *buf);
+extern unsigned int mxcsr_feature_mask;
+
static inline int need_signal_i387(struct task_struct *me)
{
if (!me->used_math)
@@ -52,11 +54,6 @@
} \
} while (0)
-#define load_mxcsr(val) do { \
- unsigned long __mxcsr = ((unsigned long)(val) & 0xffbf); \
- asm volatile("ldmxcsr %0" : : "m" (__mxcsr)); \
-} while (0)
-
/*
* ptrace request handers...
*/
@@ -75,7 +72,6 @@
#define set_fpu_cwd(t,val) ((t)->thread.i387.fxsave.cwd = (val))
#define set_fpu_swd(t,val) ((t)->thread.i387.fxsave.swd = (val))
#define set_fpu_fxsr_twd(t,val) ((t)->thread.i387.fxsave.twd = (val))
-#define set_fpu_mxcsr(t,val) ((t)->thread.i387.fxsave.mxcsr = (val)&0xffbf)
static inline int restore_fpu_checking(struct i387_fxsave_struct *fx)
{
^ permalink raw reply [flat|nested] 12+ messages in thread
* RE: [PATCH] mxcsr patch for i386 & x86-64
@ 2004-05-04 20:25 Kamble, Nitin A
0 siblings, 0 replies; 12+ messages in thread
From: Kamble, Nitin A @ 2004-05-04 20:25 UTC (permalink / raw)
To: Linus Torvalds
Cc: Andrew Morton, linux-kernel, Nakajima, Jun, Mallick, Asit K,
Saxena, Sunil
>Ahh. Have we verified that the new semantics of that MXCSR_MASK field
>works on non-intel CPU's too?
Yes, this semantics is same for AMD and Intel. And we have verified that
it also works AMD.
>
>It would also (in my opinion) make sense to just export the
>"common_mxcsr_mask" (and probably just rename it as
"mxcsr_feature_mask"
>or something - where does that "common" come from? Is it just to imply
>that it's the bits that all CPU's support "in common", or what?
Yes, The "common" word is for the common set of bit-mask between all the
SMP processors, in case they are not same. Renaming the
mxcsr_common_mask to mxcsr_feature_mask is ok.
>
>Right now you export a function that does just a simple mask operation,
>and quite frankly, that just seems to make it less clear what the code
is
>doing. So who not get rid of that "set_fpu_mxcsr()" function, and just
>replace all the "0xffbf" uses with "mxcsr_feature_mask"?
>
>Hmm?
I agree that it will be cleaner to read. The idea of the set_fpu_mxcsr()
was to export access to the static mxcsr_common_mask variable. We can
get rid of the function by making the mask a global variable, or through
a new function exporting the static variable.
>
> Linus
^ permalink raw reply [flat|nested] 12+ messages in thread
* RE: [PATCH] mxcsr patch for i386 & x86-64
@ 2004-05-04 21:06 Kamble, Nitin A
0 siblings, 0 replies; 12+ messages in thread
From: Kamble, Nitin A @ 2004-05-04 21:06 UTC (permalink / raw)
To: Linus Torvalds
Cc: Andrew Morton, linux-kernel, Nakajima, Jun, Mallick, Asit K,
Saxena, Sunil
[-- Attachment #1: Type: text/plain, Size: 464 bytes --]
>Ok,
> this is my counter-suggestion, based on your patch.
>
>Does this work for you guys? Please re-submit if it passes testing and
>otherwise looks good. I can't test it in any sane way..
>
> Linus
Yes it works. Only changes from your version of the patch are, mxcsr is
made int for x86-64, and added a prototype for fpu_init to avoid a
compile time warning.
The new patch is attached. Thanks a lot for the quick comments.
Regards,
Nitin
[-- Attachment #2: mxcsr_i386_x86-64_2.6.6-rc3_new.patch --]
[-- Type: application/octet-stream, Size: 6998 bytes --]
--- 2.6.6-rc3/arch/i386/kernel/cpu/common.c.orig 2004-05-03 18:00:03.000000000 -0700
+++ 2.6.6-rc3/arch/i386/kernel/cpu/common.c 2004-05-04 13:39:31.000000000 -0700
@@ -458,6 +458,9 @@
* and IDT. We reload them nevertheless, this function acts as a
* 'CPU state barrier', nothing should get across.
*/
+
+extern void fpu_init(void);
+
void __init cpu_init (void)
{
int cpu = smp_processor_id();
@@ -536,5 +539,5 @@
*/
current_thread_info()->status = 0;
current->used_math = 0;
- stts();
+ fpu_init();
}
--- 2.6.6-rc3/arch/i386/kernel/i387.c.orig 2004-05-03 18:02:16.000000000 -0700
+++ 2.6.6-rc3/arch/i386/kernel/i387.c 2004-05-04 13:29:35.000000000 -0700
@@ -10,6 +10,7 @@
#include <linux/config.h>
#include <linux/sched.h>
+#include <linux/init.h>
#include <asm/processor.h>
#include <asm/i387.h>
#include <asm/math_emu.h>
@@ -24,6 +25,21 @@
#define HAVE_HWFP 1
#endif
+static unsigned long mxcsr_feature_mask = 0xffffffff;
+
+static void __init mxcsr_feature_mask_init(void)
+{
+ unsigned long mask = 0;
+
+ if (cpu_has_fxsr) {
+ memset(¤t->thread.i387.fxsave, 0, sizeof(struct i387_fxsave_struct));
+ asm volatile("fxsave %0" : : "m" (current->thread.i387.fxsave));
+ mask = current->thread.i387.fxsave.mxcsr_mask;
+ if (mask == 0UL) mask = 0x0000ffbf;
+ }
+ mxcsr_feature_mask &= mask;
+}
+
/*
* The _current_ task is using the FPU for the first time
* so initialize it and set the mxcsr to its default
@@ -204,13 +220,6 @@
}
}
-void set_fpu_mxcsr( struct task_struct *tsk, unsigned short mxcsr )
-{
- if ( cpu_has_xmm ) {
- tsk->thread.i387.fxsave.mxcsr = (mxcsr & 0xffbf);
- }
-}
-
/*
* FXSR floating point environment conversions.
*/
@@ -355,8 +364,8 @@
clear_fpu( tsk );
err = __copy_from_user( &tsk->thread.i387.fxsave, &buf->_fxsr_env[0],
sizeof(struct i387_fxsave_struct) );
- /* mxcsr bit 6 and 31-16 must be zero for security reasons */
- tsk->thread.i387.fxsave.mxcsr &= 0xffbf;
+ /* mxcsr reserved bits must be masked to zero for security reasons */
+ tsk->thread.i387.fxsave.mxcsr &= mxcsr_feature_mask;
return err ? 1 : convert_fxsr_from_user( &tsk->thread.i387.fxsave, buf );
}
@@ -457,8 +466,8 @@
if (__copy_from_user( &tsk->thread.i387.fxsave, buf,
sizeof(struct user_fxsr_struct) ))
ret = -EFAULT;
- /* mxcsr bit 6 and 31-16 must be zero for security reasons */
- tsk->thread.i387.fxsave.mxcsr &= 0xffbf;
+ /* mxcsr reserved bits must be masked to zero for security reasons */
+ tsk->thread.i387.fxsave.mxcsr &= mxcsr_feature_mask;
} else {
ret = -EIO;
}
@@ -551,3 +560,10 @@
}
return fpvalid;
}
+
+void __init fpu_init(void)
+{
+ clts();
+ mxcsr_feature_mask_init();
+ stts();
+}
--- 2.6.6-rc3/arch/x86_64/kernel/i387.c.orig 2004-05-03 18:00:31.000000000 -0700
+++ 2.6.6-rc3/arch/x86_64/kernel/i387.c 2004-05-04 13:44:35.000000000 -0700
@@ -24,6 +24,18 @@
#include <asm/ptrace.h>
#include <asm/uaccess.h>
+unsigned int mxcsr_feature_mask = 0xffffffff;
+
+static void mxcsr_feature_mask_init(void)
+{
+ unsigned long mask;
+ memset(¤t->thread.i387.fxsave, 0, sizeof(struct i387_fxsave_struct));
+ asm volatile("fxsave %0" : : "m" (current->thread.i387.fxsave));
+ mask = current->thread.i387.fxsave.mxcsr_mask;
+ if (mask == 0UL) mask = 0x0000ffbf;
+ mxcsr_feature_mask &= mask;
+}
+
/*
* Called at bootup to set up the initial FPU state that is later cloned
* into all processes.
@@ -40,6 +52,8 @@
write_cr0(oldcr0 & ~((1UL<<3)|(1UL<<2))); /* clear TS and EM */
+ clts();
+ mxcsr_feature_mask_init();
/* clean state in init */
stts();
current_thread_info()->status = 0;
--- 2.6.6-rc3/arch/x86_64/ia32/fpu32.c.orig 2004-05-03 18:00:02.000000000 -0700
+++ 2.6.6-rc3/arch/x86_64/ia32/fpu32.c 2004-05-04 13:29:35.000000000 -0700
@@ -155,7 +155,7 @@
&buf->_fxsr_env[0],
sizeof(struct i387_fxsave_struct)))
return -1;
- tsk->thread.i387.fxsave.mxcsr &= 0xffbf;
+ tsk->thread.i387.fxsave.mxcsr &= mxcsr_feature_mask;
tsk->used_math = 1;
}
return convert_fxsr_from_user(&tsk->thread.i387.fxsave, buf);
--- 2.6.6-rc3/arch/x86_64/ia32/ptrace32.c.orig 2004-05-03 18:00:31.000000000 -0700
+++ 2.6.6-rc3/arch/x86_64/ia32/ptrace32.c 2004-05-04 13:29:35.000000000 -0700
@@ -357,10 +357,10 @@
/* no checking to be bug-to-bug compatible with i386 */
__copy_from_user(&child->thread.i387.fxsave, u, sizeof(*u));
child->used_math = 1;
- child->thread.i387.fxsave.mxcsr &= 0xffbf;
+ child->thread.i387.fxsave.mxcsr &= mxcsr_feature_mask;
ret = 0;
- break;
- }
+ break;
+ }
default:
ret = -EINVAL;
--- 2.6.6-rc3/include/asm-x86_64/i387.h.orig 2004-05-03 18:01:02.000000000 -0700
+++ 2.6.6-rc3/include/asm-x86_64/i387.h 2004-05-04 13:44:10.000000000 -0700
@@ -23,6 +23,8 @@
extern void init_fpu(struct task_struct *child);
extern int save_i387(struct _fpstate *buf);
+extern unsigned int mxcsr_feature_mask;
+
static inline int need_signal_i387(struct task_struct *me)
{
if (!me->used_math)
@@ -52,11 +54,6 @@
} \
} while (0)
-#define load_mxcsr(val) do { \
- unsigned long __mxcsr = ((unsigned long)(val) & 0xffbf); \
- asm volatile("ldmxcsr %0" : : "m" (__mxcsr)); \
-} while (0)
-
/*
* ptrace request handers...
*/
@@ -75,7 +72,6 @@
#define set_fpu_cwd(t,val) ((t)->thread.i387.fxsave.cwd = (val))
#define set_fpu_swd(t,val) ((t)->thread.i387.fxsave.swd = (val))
#define set_fpu_fxsr_twd(t,val) ((t)->thread.i387.fxsave.twd = (val))
-#define set_fpu_mxcsr(t,val) ((t)->thread.i387.fxsave.mxcsr = (val)&0xffbf)
static inline int restore_fpu_checking(struct i387_fxsave_struct *fx)
{
--- 2.6.6-rc3/include/asm-i386/i387.h.orig 2004-05-03 18:01:31.000000000 -0700
+++ 2.6.6-rc3/include/asm-i386/i387.h 2004-05-04 13:29:35.000000000 -0700
@@ -12,10 +12,13 @@
#define __ASM_I386_I387_H
#include <linux/sched.h>
+#include <linux/init.h>
+
#include <asm/processor.h>
#include <asm/sigcontext.h>
#include <asm/user.h>
+extern void __init fpu_init(void);
extern void init_fpu(struct task_struct *);
/*
* FPU lazy state save handling...
@@ -89,12 +92,6 @@
extern void set_fpu_cwd( struct task_struct *tsk, unsigned short cwd );
extern void set_fpu_swd( struct task_struct *tsk, unsigned short swd );
extern void set_fpu_twd( struct task_struct *tsk, unsigned short twd );
-extern void set_fpu_mxcsr( struct task_struct *tsk, unsigned short mxcsr );
-
-#define load_mxcsr( val ) do { \
- unsigned long __mxcsr = ((unsigned long)(val) & 0xffbf); \
- asm volatile( "ldmxcsr %0" : : "m" (__mxcsr) ); \
-} while (0)
/*
* Signal frame handlers...
--- 2.6.6-rc3/include/asm-i386/processor.h.orig 2004-05-03 18:00:03.000000000 -0700
+++ 2.6.6-rc3/include/asm-i386/processor.h 2004-05-04 13:29:35.000000000 -0700
@@ -332,7 +332,7 @@
long foo;
long fos;
long mxcsr;
- long reserved;
+ long mxcsr_mask;
long st_space[32]; /* 8*16 bytes for each FP-reg = 128 bytes */
long xmm_space[32]; /* 8*16 bytes for each XMM-reg = 128 bytes */
long padding[56];
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] mxcsr patch for i386 & x86-64
2004-05-04 20:24 ` Linus Torvalds
@ 2004-05-04 21:07 ` Jeff Garzik
2004-05-05 13:51 ` Pavel Machek
1 sibling, 0 replies; 12+ messages in thread
From: Jeff Garzik @ 2004-05-04 21:07 UTC (permalink / raw)
To: Linus Torvalds
Cc: Kamble, Nitin A, Andrew Morton, linux-kernel, Nakajima, Jun,
Mallick, Asit K, Saxena, Sunil
Linus Torvalds wrote:
> --- 1.19/arch/i386/kernel/i387.c Tue Feb 3 21:30:39 2004
> +++ edited/arch/i386/kernel/i387.c Tue May 4 13:15:10 2004
> @@ -24,6 +25,21 @@
> #define HAVE_HWFP 1
> #endif
>
> +static unsigned long mxcsr_feature_mask = 0xffffffff;
> --- 1.10/arch/x86_64/kernel/i387.c Fri Jan 23 12:17:58 2004
> +++ edited/arch/x86_64/kernel/i387.c Tue May 4 13:07:35 2004
> @@ -24,6 +24,18 @@
> #include <asm/ptrace.h>
> #include <asm/uaccess.h>
>
> +unsigned long mxcsr_feature_mask = 0xffffffff;
> +
Minor/dumb question: Is the above intentional?
Would be nice to have them the same for consistency if nothing else.
i386 and x86-64 common code gets pasted and #include'd all the time.
Jeff
^ permalink raw reply [flat|nested] 12+ messages in thread
* RE: [PATCH] mxcsr patch for i386 & x86-64
@ 2004-05-04 21:47 Nakajima, Jun
0 siblings, 0 replies; 12+ messages in thread
From: Nakajima, Jun @ 2004-05-04 21:47 UTC (permalink / raw)
To: Jeff Garzik, Linus Torvalds
Cc: Kamble, Nitin A, Andrew Morton, linux-kernel, Mallick, Asit K,
Saxena, Sunil
>From: Jeff Garzik [mailto:jgarzik@pobox.com]
>Sent: Tuesday, May 04, 2004 2:08 PM
>Linus Torvalds wrote:
>> --- 1.19/arch/i386/kernel/i387.c Tue Feb 3 21:30:39 2004
>> +++ edited/arch/i386/kernel/i387.c Tue May 4 13:15:10 2004
>> @@ -24,6 +25,21 @@
>> #define HAVE_HWFP 1
>> #endif
>>
>> +static unsigned long mxcsr_feature_mask = 0xffffffff;
>
>> --- 1.10/arch/x86_64/kernel/i387.c Fri Jan 23 12:17:58 2004
>> +++ edited/arch/x86_64/kernel/i387.c Tue May 4 13:07:35 2004
>> @@ -24,6 +24,18 @@
>> #include <asm/ptrace.h>
>> #include <asm/uaccess.h>
>>
>> +unsigned long mxcsr_feature_mask = 0xffffffff;
>> +
>
>
>Minor/dumb question: Is the above intentional?
>
>Would be nice to have them the same for consistency if nothing else.
>i386 and x86-64 common code gets pasted and #include'd all the time.
If we look at set/get_fpu_xxx in i386 and x86-64, their codes are not
consistent; functions vs. macros. This is mainly because x86-64 can
assume the modern CPU features are available, and thus those are
simplified.
It's not required to make mxcsr_feature_mask global on i386 because
nobody else is using it in other files, but I agree that it would be
better to make it global to avoid potential confusion/mistakes in the
future.
> ===== arch/i386/kernel/i387.c 1.19 vs edited =====
> --- 1.19/arch/i386/kernel/i387.c Tue Feb 3 21:30:39 2004
> +++ edited/arch/i386/kernel/i387.c Tue May 4 13:15:10 2004
> @@ -10,6 +10,7 @@
> ...
> -void set_fpu_mxcsr( struct task_struct *tsk, unsigned short mxcsr )
> -{
> - if ( cpu_has_xmm ) {
> - tsk->thread.i387.fxsave.mxcsr = (mxcsr & 0xffbf);
> - }
> -}
If we do this, then we should check if we can remove other (unused)
set/get_fpu_xxx to make i386 and x86-64 more consistent. For example,
set/get_fpu_fwd() are not used as far as I checked.
Jun
>
> Jeff
>
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] mxcsr patch for i386 & x86-64
2004-05-04 20:24 ` Linus Torvalds
2004-05-04 21:07 ` Jeff Garzik
@ 2004-05-05 13:51 ` Pavel Machek
1 sibling, 0 replies; 12+ messages in thread
From: Pavel Machek @ 2004-05-05 13:51 UTC (permalink / raw)
To: Linus Torvalds
Cc: Kamble, Nitin A, Andrew Morton, linux-kernel, Nakajima, Jun,
Mallick, Asit K, Saxena, Sunil
Hi!
> @@ -550,4 +559,11 @@
> memcpy(fpu, &tsk->thread.i387.fxsave, sizeof(*fpu));
> }
> return fpvalid;
> +}
> +
> +void __init fpu_init(void)
> +{
> + clts();
> + mxcsr_feature_mask_init();
> + stts();
> }
i386/kernel/power/cpu.c now probably wants fpu_init, too...
--
64 bytes from 195.113.31.123: icmp_seq=28 ttl=51 time=448769.1 ms
^ permalink raw reply [flat|nested] 12+ messages in thread
* RE: [PATCH] mxcsr patch for i386 & x86-64
@ 2004-05-06 21:00 Kamble, Nitin A
2004-05-07 14:23 ` Pavel Machek
0 siblings, 1 reply; 12+ messages in thread
From: Kamble, Nitin A @ 2004-05-06 21:00 UTC (permalink / raw)
To: Pavel Machek, Linus Torvalds
Cc: Andrew Morton, linux-kernel, Nakajima, Jun, Mallick, Asit K,
Saxena, Sunil
[-- Attachment #1: Type: text/plain, Size: 618 bytes --]
>i386/kernel/power/cpu.c now probably wants fpu_init, too...
Hi Pavel,
I have updated the mxcsr patch to also enable it at the time of
resume. Please find the patch attached.
fpu_init() is needed in the resume path, only if the user want to
change the cpu between suspend and resume. Otherwise the
mxcsr_features_mask calculated earlier will still be valid.
Also for changing the cpu, the user will need to shutdown the
system, so it is useful for S4 (suspend to disk) state.
I am testing the patch. Meanwhile please let me know if these changes
are ok for you?
Thanks & Regards,
Nitin
[-- Attachment #2: mxcsr_i386_x86-64_2.6.6-rc3_new2.patch --]
[-- Type: application/octet-stream, Size: 7538 bytes --]
--- 2.6.6-rc3/arch/i386/kernel/cpu/common.c.orig 2004-05-03 18:00:03.000000000 -0700
+++ 2.6.6-rc3/arch/i386/kernel/cpu/common.c 2004-05-06 13:51:18.000000000 -0700
@@ -4,6 +4,7 @@
#include <linux/smp.h>
#include <asm/semaphore.h>
#include <asm/processor.h>
+#include <asm/i387.h>
#include <asm/msr.h>
#include <asm/io.h>
#include <asm/mmu_context.h>
@@ -536,5 +537,5 @@
*/
current_thread_info()->status = 0;
current->used_math = 0;
- stts();
+ mxcsr_feature_mask_init();
}
--- 2.6.6-rc3/arch/i386/kernel/i387.c.orig 2004-05-03 18:02:16.000000000 -0700
+++ 2.6.6-rc3/arch/i386/kernel/i387.c 2004-05-06 12:26:55.000000000 -0700
@@ -24,6 +24,22 @@
#define HAVE_HWFP 1
#endif
+unsigned long mxcsr_feature_mask = 0xffffffff;
+
+void mxcsr_feature_mask_init(void)
+{
+ unsigned long mask = 0;
+ clts();
+ if (cpu_has_fxsr) {
+ memset(¤t->thread.i387.fxsave, 0, sizeof(struct i387_fxsave_struct));
+ asm volatile("fxsave %0" : : "m" (current->thread.i387.fxsave));
+ mask = current->thread.i387.fxsave.mxcsr_mask;
+ if (mask == 0) mask = 0x0000ffbf;
+ }
+ mxcsr_feature_mask &= mask;
+ stts();
+}
+
/*
* The _current_ task is using the FPU for the first time
* so initialize it and set the mxcsr to its default
@@ -204,13 +220,6 @@
}
}
-void set_fpu_mxcsr( struct task_struct *tsk, unsigned short mxcsr )
-{
- if ( cpu_has_xmm ) {
- tsk->thread.i387.fxsave.mxcsr = (mxcsr & 0xffbf);
- }
-}
-
/*
* FXSR floating point environment conversions.
*/
@@ -355,8 +364,8 @@
clear_fpu( tsk );
err = __copy_from_user( &tsk->thread.i387.fxsave, &buf->_fxsr_env[0],
sizeof(struct i387_fxsave_struct) );
- /* mxcsr bit 6 and 31-16 must be zero for security reasons */
- tsk->thread.i387.fxsave.mxcsr &= 0xffbf;
+ /* mxcsr reserved bits must be masked to zero for security reasons */
+ tsk->thread.i387.fxsave.mxcsr &= mxcsr_feature_mask;
return err ? 1 : convert_fxsr_from_user( &tsk->thread.i387.fxsave, buf );
}
@@ -457,8 +466,8 @@
if (__copy_from_user( &tsk->thread.i387.fxsave, buf,
sizeof(struct user_fxsr_struct) ))
ret = -EFAULT;
- /* mxcsr bit 6 and 31-16 must be zero for security reasons */
- tsk->thread.i387.fxsave.mxcsr &= 0xffbf;
+ /* mxcsr reserved bits must be masked to zero for security reasons */
+ tsk->thread.i387.fxsave.mxcsr &= mxcsr_feature_mask;
} else {
ret = -EIO;
}
--- 2.6.6-rc3/arch/i386/power/cpu.c.orig 2004-05-03 18:01:32.000000000 -0700
+++ 2.6.6-rc3/arch/i386/power/cpu.c 2004-05-06 12:14:28.000000000 -0700
@@ -72,6 +72,7 @@
/* restore FPU regs if necessary */
/* Do it out of line so that gcc does not move cr0 load to some stupid place */
kernel_fpu_end();
+ mxcsr_feature_mask_init();
}
void restore_processor_state(void)
--- 2.6.6-rc3/arch/x86_64/kernel/i387.c.orig 2004-05-03 18:00:31.000000000 -0700
+++ 2.6.6-rc3/arch/x86_64/kernel/i387.c 2004-05-06 12:09:37.000000000 -0700
@@ -24,6 +24,20 @@
#include <asm/ptrace.h>
#include <asm/uaccess.h>
+unsigned int mxcsr_feature_mask = 0xffffffff;
+
+void mxcsr_feature_mask_init(void)
+{
+ unsigned int mask;
+ clts();
+ memset(¤t->thread.i387.fxsave, 0, sizeof(struct i387_fxsave_struct));
+ asm volatile("fxsave %0" : : "m" (current->thread.i387.fxsave));
+ mask = current->thread.i387.fxsave.mxcsr_mask;
+ if (mask == 0) mask = 0x0000ffbf;
+ mxcsr_feature_mask &= mask;
+ stts();
+}
+
/*
* Called at bootup to set up the initial FPU state that is later cloned
* into all processes.
@@ -40,8 +54,8 @@
write_cr0(oldcr0 & ~((1UL<<3)|(1UL<<2))); /* clear TS and EM */
+ mxcsr_feature_mask_init();
/* clean state in init */
- stts();
current_thread_info()->status = 0;
current->used_math = 0;
}
--- 2.6.6-rc3/arch/x86_64/kernel/suspend.c.orig 2004-05-03 18:01:00.000000000 -0700
+++ 2.6.6-rc3/arch/x86_64/kernel/suspend.c 2004-05-06 12:23:59.000000000 -0700
@@ -77,6 +77,7 @@
/* restore FPU regs if necessary */
/* Do it out of line so that gcc does not move cr0 load to some stupid place */
kernel_fpu_end();
+ mxcsr_feature_mask_init();
}
void restore_processor_state(void)
--- 2.6.6-rc3/arch/x86_64/ia32/fpu32.c.orig 2004-05-03 18:00:02.000000000 -0700
+++ 2.6.6-rc3/arch/x86_64/ia32/fpu32.c 2004-05-04 13:29:35.000000000 -0700
@@ -155,7 +155,7 @@
&buf->_fxsr_env[0],
sizeof(struct i387_fxsave_struct)))
return -1;
- tsk->thread.i387.fxsave.mxcsr &= 0xffbf;
+ tsk->thread.i387.fxsave.mxcsr &= mxcsr_feature_mask;
tsk->used_math = 1;
}
return convert_fxsr_from_user(&tsk->thread.i387.fxsave, buf);
--- 2.6.6-rc3/arch/x86_64/ia32/ptrace32.c.orig 2004-05-03 18:00:31.000000000 -0700
+++ 2.6.6-rc3/arch/x86_64/ia32/ptrace32.c 2004-05-04 13:29:35.000000000 -0700
@@ -357,10 +357,10 @@
/* no checking to be bug-to-bug compatible with i386 */
__copy_from_user(&child->thread.i387.fxsave, u, sizeof(*u));
child->used_math = 1;
- child->thread.i387.fxsave.mxcsr &= 0xffbf;
+ child->thread.i387.fxsave.mxcsr &= mxcsr_feature_mask;
ret = 0;
- break;
- }
+ break;
+ }
default:
ret = -EINVAL;
--- 2.6.6-rc3/include/asm-x86_64/i387.h.orig 2004-05-03 18:01:02.000000000 -0700
+++ 2.6.6-rc3/include/asm-x86_64/i387.h 2004-05-06 13:35:39.000000000 -0700
@@ -20,6 +20,8 @@
#include <asm/uaccess.h>
extern void fpu_init(void);
+extern unsigned int mxcsr_feature_mask;
+extern void mxcsr_feature_mask_init(void);
extern void init_fpu(struct task_struct *child);
extern int save_i387(struct _fpstate *buf);
@@ -52,11 +54,6 @@
} \
} while (0)
-#define load_mxcsr(val) do { \
- unsigned long __mxcsr = ((unsigned long)(val) & 0xffbf); \
- asm volatile("ldmxcsr %0" : : "m" (__mxcsr)); \
-} while (0)
-
/*
* ptrace request handers...
*/
@@ -75,7 +72,6 @@
#define set_fpu_cwd(t,val) ((t)->thread.i387.fxsave.cwd = (val))
#define set_fpu_swd(t,val) ((t)->thread.i387.fxsave.swd = (val))
#define set_fpu_fxsr_twd(t,val) ((t)->thread.i387.fxsave.twd = (val))
-#define set_fpu_mxcsr(t,val) ((t)->thread.i387.fxsave.mxcsr = (val)&0xffbf)
static inline int restore_fpu_checking(struct i387_fxsave_struct *fx)
{
--- 2.6.6-rc3/include/asm-i386/i387.h.orig 2004-05-03 18:01:31.000000000 -0700
+++ 2.6.6-rc3/include/asm-i386/i387.h 2004-05-06 12:26:10.000000000 -0700
@@ -12,10 +12,13 @@
#define __ASM_I386_I387_H
#include <linux/sched.h>
+#include <linux/init.h>
#include <asm/processor.h>
#include <asm/sigcontext.h>
#include <asm/user.h>
+extern unsigned long mxcsr_feature_mask;
+extern void mxcsr_feature_mask_init(void);
extern void init_fpu(struct task_struct *);
/*
* FPU lazy state save handling...
@@ -89,12 +92,6 @@
extern void set_fpu_cwd( struct task_struct *tsk, unsigned short cwd );
extern void set_fpu_swd( struct task_struct *tsk, unsigned short swd );
extern void set_fpu_twd( struct task_struct *tsk, unsigned short twd );
-extern void set_fpu_mxcsr( struct task_struct *tsk, unsigned short mxcsr );
-
-#define load_mxcsr( val ) do { \
- unsigned long __mxcsr = ((unsigned long)(val) & 0xffbf); \
- asm volatile( "ldmxcsr %0" : : "m" (__mxcsr) ); \
-} while (0)
/*
* Signal frame handlers...
--- 2.6.6-rc3/include/asm-i386/processor.h.orig 2004-05-03 18:00:03.000000000 -0700
+++ 2.6.6-rc3/include/asm-i386/processor.h 2004-05-04 13:29:35.000000000 -0700
@@ -332,7 +332,7 @@
long foo;
long fos;
long mxcsr;
- long reserved;
+ long mxcsr_mask;
long st_space[32]; /* 8*16 bytes for each FP-reg = 128 bytes */
long xmm_space[32]; /* 8*16 bytes for each XMM-reg = 128 bytes */
long padding[56];
^ permalink raw reply [flat|nested] 12+ messages in thread
* RE: [PATCH] mxcsr patch for i386 & x86-64
@ 2004-05-07 1:40 Kamble, Nitin A
0 siblings, 0 replies; 12+ messages in thread
From: Kamble, Nitin A @ 2004-05-07 1:40 UTC (permalink / raw)
To: Kamble, Nitin A, Pavel Machek, Linus Torvalds, Andrew Morton,
Jeff Garzik
Cc: linux-kernel, Nakajima, Jun, Mallick, Asit K, Saxena, Sunil
[-- Attachment #1: Type: text/plain, Size: 1210 bytes --]
Pavel,
The test for suspend & resume has passed.
One more patch to be applied on top of the previous patch is attached.
It cleans up the duplicate code, as per Jeff's suggestion.
Thanks & Regards,
Nitin
------------------------------------------------------------------------
-
>-----Original Message-----
>From: Kamble, Nitin A
>Sent: Thursday, May 06, 2004 2:01 PM
>To: 'Pavel Machek'; Linus Torvalds
>Cc: Andrew Morton; linux-kernel@vger.kernel.org; Nakajima, Jun;
Mallick,
>Asit K; Saxena, Sunil
>Subject: RE: [PATCH] mxcsr patch for i386 & x86-64
>
>>i386/kernel/power/cpu.c now probably wants fpu_init, too...
>
>Hi Pavel,
> I have updated the mxcsr patch to also enable it at the time of
resume.
>Please find the patch attached.
> fpu_init() is needed in the resume path, only if the user want to
change
>the cpu between suspend and resume. Otherwise the mxcsr_features_mask
>calculated earlier will still be valid.
> Also for changing the cpu, the user will need to shutdown the
system,
>so it is useful for S4 (suspend to disk) state.
> I am testing the patch. Meanwhile please let me know if these changes
are
>ok for you?
>
>Thanks & Regards,
>Nitin
[-- Attachment #2: mxcsr_shared.patch --]
[-- Type: application/octet-stream, Size: 3706 bytes --]
--- 2.6.6-rc3/arch/i386/kernel/Makefile.orig 2004-05-06 17:57:10.000000000 -0700
+++ 2.6.6-rc3/arch/i386/kernel/Makefile 2004-05-06 18:06:30.000000000 -0700
@@ -6,8 +6,8 @@
obj-y := process.o semaphore.o signal.o entry.o traps.o irq.o vm86.o \
ptrace.o i8259.o ioport.o ldt.o setup.o time.o sys_i386.o \
- pci-dma.o i386_ksyms.o i387.o dmi_scan.o bootflag.o \
- doublefault.o
+ pci-dma.o i386_ksyms.o i387.o i387_shared.o dmi_scan.o \
+ bootflag.o doublefault.o
obj-y += cpu/
obj-y += timers/
--- /dev/null 2003-09-23 15:19:32.000000000 -0700
+++ 2.6.6-rc3/arch/i386/kernel/i387_shared.c 2004-05-06 18:12:09.000000000 -0700
@@ -0,0 +1,29 @@
+/*
+ * linux/arch/i386/kernel/i387_shared.c
+ *
+ * Taking the archicture shared mxcsr functionality out from i387.c
+ * to this i387_shared.c.(6th May 2004)
+ * Nitin Kamble <nitin.a.kamble@intel.com>
+ */
+
+#include <asm/types.h>
+#include <asm/system.h>
+#include <asm/processor.h>
+#include <asm/string.h>
+#include <linux/sched.h>
+
+u32 mxcsr_feature_mask = 0xffffffff;
+
+void mxcsr_feature_mask_init(void)
+{
+ u32 mask = 0;
+ clts();
+ if (cpu_has_fxsr) {
+ memset(¤t->thread.i387.fxsave, 0, sizeof(struct i387_fxsave_struct));
+ asm volatile("fxsave %0" : : "m" (current->thread.i387.fxsave));
+ mask = current->thread.i387.fxsave.mxcsr_mask;
+ if (mask == 0) mask = 0x0000ffbf;
+ }
+ mxcsr_feature_mask &= mask;
+ stts();
+}
--- 2.6.6-rc3/arch/i386/kernel/i387.c.orig 2004-05-06 17:57:16.000000000 -0700
+++ 2.6.6-rc3/arch/i386/kernel/i387.c 2004-05-06 18:06:30.000000000 -0700
@@ -24,22 +24,6 @@
#define HAVE_HWFP 1
#endif
-unsigned long mxcsr_feature_mask = 0xffffffff;
-
-void mxcsr_feature_mask_init(void)
-{
- unsigned long mask = 0;
- clts();
- if (cpu_has_fxsr) {
- memset(¤t->thread.i387.fxsave, 0, sizeof(struct i387_fxsave_struct));
- asm volatile("fxsave %0" : : "m" (current->thread.i387.fxsave));
- mask = current->thread.i387.fxsave.mxcsr_mask;
- if (mask == 0) mask = 0x0000ffbf;
- }
- mxcsr_feature_mask &= mask;
- stts();
-}
-
/*
* The _current_ task is using the FPU for the first time
* so initialize it and set the mxcsr to its default
--- 2.6.6-rc3/arch/x86_64/kernel/Makefile.orig 2004-05-06 17:57:18.000000000 -0700
+++ 2.6.6-rc3/arch/x86_64/kernel/Makefile 2004-05-06 18:06:30.000000000 -0700
@@ -6,7 +6,7 @@
EXTRA_AFLAGS := -traditional
obj-y := process.o semaphore.o signal.o entry.o traps.o irq.o \
ptrace.o i8259.o ioport.o ldt.o setup.o time.o sys_x86_64.o \
- x8664_ksyms.o i387.o syscall.o vsyscall.o \
+ x8664_ksyms.o i387.o i387_shared.o syscall.o vsyscall.o \
setup64.o bootflag.o e820.o reboot.o warmreboot.o
obj-y += mce.o acpi/
@@ -35,3 +35,4 @@
topology-y += ../../i386/mach-default/topology.o
swiotlb-$(CONFIG_SWIOTLB) += ../../ia64/lib/swiotlb.o
microcode-$(subst m,y,$(CONFIG_MICROCODE)) += ../../i386/kernel/microcode.o
+i387_shared-y += ../../i386/kernel/i387_shared.o
--- 2.6.6-rc3/arch/x86_64/kernel/i387.c.orig 2004-05-06 17:57:19.000000000 -0700
+++ 2.6.6-rc3/arch/x86_64/kernel/i387.c 2004-05-06 18:06:30.000000000 -0700
@@ -24,20 +24,6 @@
#include <asm/ptrace.h>
#include <asm/uaccess.h>
-unsigned int mxcsr_feature_mask = 0xffffffff;
-
-void mxcsr_feature_mask_init(void)
-{
- unsigned int mask;
- clts();
- memset(¤t->thread.i387.fxsave, 0, sizeof(struct i387_fxsave_struct));
- asm volatile("fxsave %0" : : "m" (current->thread.i387.fxsave));
- mask = current->thread.i387.fxsave.mxcsr_mask;
- if (mask == 0) mask = 0x0000ffbf;
- mxcsr_feature_mask &= mask;
- stts();
-}
-
/*
* Called at bootup to set up the initial FPU state that is later cloned
* into all processes.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] mxcsr patch for i386 & x86-64
2004-05-06 21:00 Kamble, Nitin A
@ 2004-05-07 14:23 ` Pavel Machek
0 siblings, 0 replies; 12+ messages in thread
From: Pavel Machek @ 2004-05-07 14:23 UTC (permalink / raw)
To: Kamble, Nitin A
Cc: Linus Torvalds, Andrew Morton, linux-kernel, Nakajima, Jun,
Mallick, Asit K, Saxena, Sunil
Hi!
> I have updated the mxcsr patch to also enable it at the time of
> resume. Please find the patch attached.
> fpu_init() is needed in the resume path, only if the user want to
> change the cpu between suspend and resume. Otherwise the
> mxcsr_features_mask calculated earlier will still be valid.
> Also for changing the cpu, the user will need to shutdown the
> system, so it is useful for S4 (suspend to disk) state.
> I am testing the patch. Meanwhile please let me know if these changes
> are ok for you?
Noone should exchange CPUs while we are in S4 suspend; but handling it
can not hurt.
Patch looks okay, thanks.
Pavel
--
Horseback riding is like software...
...vgf orggre jura vgf serr.
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2004-05-07 14:23 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-05-04 18:50 [PATCH] mxcsr patch for i386 & x86-64 Kamble, Nitin A
2004-05-04 19:10 ` Linus Torvalds
2004-05-04 19:26 ` Linus Torvalds
2004-05-04 20:24 ` Linus Torvalds
2004-05-04 21:07 ` Jeff Garzik
2004-05-05 13:51 ` Pavel Machek
-- strict thread matches above, loose matches on Subject: below --
2004-05-04 20:25 Kamble, Nitin A
2004-05-04 21:06 Kamble, Nitin A
2004-05-04 21:47 Nakajima, Jun
2004-05-06 21:00 Kamble, Nitin A
2004-05-07 14:23 ` Pavel Machek
2004-05-07 1:40 Kamble, Nitin A
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox