x86, fpu: split FPU state from task struct - v5
Split the FPU save area from the task struct. This allows easy migration of FPU context, and it's generally cleaner. It also allows the following two optimizations: 1) only allocate when the application actually uses FPU, so in the first lazy FPU trap. This could save memory for non-fpu using apps. Next patch does this lazy allocation. 2) allocate the right size for the actual cpu rather than 512 bytes always. Patches enabling xsave/xrstor support (coming shortly) will take advantage of this. Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com> Signed-off-by: Arjan van de Ven <arjan@linux.intel.com> Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
This commit is contained in:
committed by
Ingo Molnar
parent
fa5c463941
commit
61c4628b53
@@ -678,7 +678,7 @@ int fpregs_soft_set(struct task_struct *target,
|
||||
unsigned int pos, unsigned int count,
|
||||
const void *kbuf, const void __user *ubuf)
|
||||
{
|
||||
struct i387_soft_struct *s387 = &target->thread.i387.soft;
|
||||
struct i387_soft_struct *s387 = &target->thread.xstate->soft;
|
||||
void *space = s387->st_space;
|
||||
int ret;
|
||||
int offset, other, i, tags, regnr, tag, newtop;
|
||||
@@ -730,7 +730,7 @@ int fpregs_soft_get(struct task_struct *target,
|
||||
unsigned int pos, unsigned int count,
|
||||
void *kbuf, void __user *ubuf)
|
||||
{
|
||||
struct i387_soft_struct *s387 = &target->thread.i387.soft;
|
||||
struct i387_soft_struct *s387 = &target->thread.xstate->soft;
|
||||
const void *space = s387->st_space;
|
||||
int ret;
|
||||
int offset = (S387->ftop & 7) * 10, other = 80 - offset;
|
||||
|
@@ -35,8 +35,8 @@
|
||||
#define SEG_EXPAND_DOWN(s) (((s).b & ((1 << 11) | (1 << 10))) \
|
||||
== (1 << 10))
|
||||
|
||||
#define I387 (current->thread.i387)
|
||||
#define FPU_info (I387.soft.info)
|
||||
#define I387 (current->thread.xstate)
|
||||
#define FPU_info (I387->soft.info)
|
||||
|
||||
#define FPU_CS (*(unsigned short *) &(FPU_info->___cs))
|
||||
#define FPU_SS (*(unsigned short *) &(FPU_info->___ss))
|
||||
@@ -46,25 +46,25 @@
|
||||
#define FPU_EIP (FPU_info->___eip)
|
||||
#define FPU_ORIG_EIP (FPU_info->___orig_eip)
|
||||
|
||||
#define FPU_lookahead (I387.soft.lookahead)
|
||||
#define FPU_lookahead (I387->soft.lookahead)
|
||||
|
||||
/* nz if ip_offset and cs_selector are not to be set for the current
|
||||
instruction. */
|
||||
#define no_ip_update (*(u_char *)&(I387.soft.no_update))
|
||||
#define FPU_rm (*(u_char *)&(I387.soft.rm))
|
||||
#define no_ip_update (*(u_char *)&(I387->soft.no_update))
|
||||
#define FPU_rm (*(u_char *)&(I387->soft.rm))
|
||||
|
||||
/* Number of bytes of data which can be legally accessed by the current
|
||||
instruction. This only needs to hold a number <= 108, so a byte will do. */
|
||||
#define access_limit (*(u_char *)&(I387.soft.alimit))
|
||||
#define access_limit (*(u_char *)&(I387->soft.alimit))
|
||||
|
||||
#define partial_status (I387.soft.swd)
|
||||
#define control_word (I387.soft.cwd)
|
||||
#define fpu_tag_word (I387.soft.twd)
|
||||
#define registers (I387.soft.st_space)
|
||||
#define top (I387.soft.ftop)
|
||||
#define partial_status (I387->soft.swd)
|
||||
#define control_word (I387->soft.cwd)
|
||||
#define fpu_tag_word (I387->soft.twd)
|
||||
#define registers (I387->soft.st_space)
|
||||
#define top (I387->soft.ftop)
|
||||
|
||||
#define instruction_address (*(struct address *)&I387.soft.fip)
|
||||
#define operand_address (*(struct address *)&I387.soft.foo)
|
||||
#define instruction_address (*(struct address *)&I387->soft.fip)
|
||||
#define operand_address (*(struct address *)&I387->soft.foo)
|
||||
|
||||
#define FPU_access_ok(x,y,z) if ( !access_ok(x,y,z) ) \
|
||||
math_abort(FPU_info,SIGSEGV)
|
||||
|
@@ -1180,8 +1180,8 @@ u_char __user *fstenv(fpu_addr_modes addr_modes, u_char __user *d)
|
||||
control_word |= 0xffff0040;
|
||||
partial_status = status_word() | 0xffff0000;
|
||||
fpu_tag_word |= 0xffff0000;
|
||||
I387.soft.fcs &= ~0xf8000000;
|
||||
I387.soft.fos |= 0xffff0000;
|
||||
I387->soft.fcs &= ~0xf8000000;
|
||||
I387->soft.fos |= 0xffff0000;
|
||||
#endif /* PECULIAR_486 */
|
||||
if (__copy_to_user(d, &control_word, 7 * 4))
|
||||
FPU_abort;
|
||||
|
Reference in New Issue
Block a user