mirror of
https://github.com/tbsdtv/linux_media.git
synced 2025-07-23 20:51:03 +02:00
x86/fpu: Harmonize FPU register state types
Use these consistent names: struct fregs_state # was: i387_fsave_struct struct fxregs_state # was: i387_fxsave_struct struct swregs_state # was: i387_soft_struct struct xregs_state # was: xsave_struct union fpregs_state # was: thread_xstate Cc: Andy Lutomirski <luto@amacapital.net> Cc: Borislav Petkov <bp@alien8.de> Cc: Dave Hansen <dave.hansen@linux.intel.com> Cc: Fenghua Yu <fenghua.yu@intel.com> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Oleg Nesterov <oleg@redhat.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
@@ -22,20 +22,20 @@
|
|||||||
|
|
||||||
extern unsigned int mxcsr_feature_mask;
|
extern unsigned int mxcsr_feature_mask;
|
||||||
|
|
||||||
extern union thread_xstate init_fpstate;
|
extern union fpregs_state init_fpstate;
|
||||||
|
|
||||||
extern void fpu__init_cpu(void);
|
extern void fpu__init_cpu(void);
|
||||||
extern void fpu__init_system_xstate(void);
|
extern void fpu__init_system_xstate(void);
|
||||||
extern void fpu__init_cpu_xstate(void);
|
extern void fpu__init_cpu_xstate(void);
|
||||||
extern void fpu__init_system(struct cpuinfo_x86 *c);
|
extern void fpu__init_system(struct cpuinfo_x86 *c);
|
||||||
|
|
||||||
extern void fpstate_init(union thread_xstate *state);
|
extern void fpstate_init(union fpregs_state *state);
|
||||||
#ifdef CONFIG_MATH_EMULATION
|
#ifdef CONFIG_MATH_EMULATION
|
||||||
extern void fpstate_init_soft(struct i387_soft_struct *soft);
|
extern void fpstate_init_soft(struct swregs_state *soft);
|
||||||
#else
|
#else
|
||||||
static inline void fpstate_init_soft(struct i387_soft_struct *soft) {}
|
static inline void fpstate_init_soft(struct swregs_state *soft) {}
|
||||||
#endif
|
#endif
|
||||||
static inline void fpstate_init_fxstate(struct i387_fxsave_struct *fx)
|
static inline void fpstate_init_fxstate(struct fxregs_state *fx)
|
||||||
{
|
{
|
||||||
fx->cwd = 0x37f;
|
fx->cwd = 0x37f;
|
||||||
fx->mxcsr = MXCSR_DEFAULT;
|
fx->mxcsr = MXCSR_DEFAULT;
|
||||||
@@ -133,12 +133,12 @@ extern void fpstate_sanitize_xstate(struct fpu *fpu);
|
|||||||
err; \
|
err; \
|
||||||
})
|
})
|
||||||
|
|
||||||
static inline int copy_fregs_to_user(struct i387_fsave_struct __user *fx)
|
static inline int copy_fregs_to_user(struct fregs_state __user *fx)
|
||||||
{
|
{
|
||||||
return user_insn(fnsave %[fx]; fwait, [fx] "=m" (*fx), "m" (*fx));
|
return user_insn(fnsave %[fx]; fwait, [fx] "=m" (*fx), "m" (*fx));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int copy_fxregs_to_user(struct i387_fxsave_struct __user *fx)
|
static inline int copy_fxregs_to_user(struct fxregs_state __user *fx)
|
||||||
{
|
{
|
||||||
if (config_enabled(CONFIG_X86_32))
|
if (config_enabled(CONFIG_X86_32))
|
||||||
return user_insn(fxsave %[fx], [fx] "=m" (*fx), "m" (*fx));
|
return user_insn(fxsave %[fx], [fx] "=m" (*fx), "m" (*fx));
|
||||||
@@ -149,7 +149,7 @@ static inline int copy_fxregs_to_user(struct i387_fxsave_struct __user *fx)
|
|||||||
return user_insn(rex64/fxsave (%[fx]), "=m" (*fx), [fx] "R" (fx));
|
return user_insn(rex64/fxsave (%[fx]), "=m" (*fx), [fx] "R" (fx));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int copy_kernel_to_fxregs(struct i387_fxsave_struct *fx)
|
static inline int copy_kernel_to_fxregs(struct fxregs_state *fx)
|
||||||
{
|
{
|
||||||
if (config_enabled(CONFIG_X86_32))
|
if (config_enabled(CONFIG_X86_32))
|
||||||
return check_insn(fxrstor %[fx], "=m" (*fx), [fx] "m" (*fx));
|
return check_insn(fxrstor %[fx], "=m" (*fx), [fx] "m" (*fx));
|
||||||
@@ -161,7 +161,7 @@ static inline int copy_kernel_to_fxregs(struct i387_fxsave_struct *fx)
|
|||||||
"m" (*fx));
|
"m" (*fx));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int copy_user_to_fxregs(struct i387_fxsave_struct __user *fx)
|
static inline int copy_user_to_fxregs(struct fxregs_state __user *fx)
|
||||||
{
|
{
|
||||||
if (config_enabled(CONFIG_X86_32))
|
if (config_enabled(CONFIG_X86_32))
|
||||||
return user_insn(fxrstor %[fx], "=m" (*fx), [fx] "m" (*fx));
|
return user_insn(fxrstor %[fx], "=m" (*fx), [fx] "m" (*fx));
|
||||||
@@ -173,12 +173,12 @@ static inline int copy_user_to_fxregs(struct i387_fxsave_struct __user *fx)
|
|||||||
"m" (*fx));
|
"m" (*fx));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int copy_kernel_to_fregs(struct i387_fsave_struct *fx)
|
static inline int copy_kernel_to_fregs(struct fregs_state *fx)
|
||||||
{
|
{
|
||||||
return check_insn(frstor %[fx], "=m" (*fx), [fx] "m" (*fx));
|
return check_insn(frstor %[fx], "=m" (*fx), [fx] "m" (*fx));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int copy_user_to_fregs(struct i387_fsave_struct __user *fx)
|
static inline int copy_user_to_fregs(struct fregs_state __user *fx)
|
||||||
{
|
{
|
||||||
return user_insn(frstor %[fx], "=m" (*fx), [fx] "m" (*fx));
|
return user_insn(frstor %[fx], "=m" (*fx), [fx] "m" (*fx));
|
||||||
}
|
}
|
||||||
|
@@ -4,7 +4,7 @@
|
|||||||
#ifndef _ASM_X86_FPU_H
|
#ifndef _ASM_X86_FPU_H
|
||||||
#define _ASM_X86_FPU_H
|
#define _ASM_X86_FPU_H
|
||||||
|
|
||||||
struct i387_fsave_struct {
|
struct fregs_state {
|
||||||
u32 cwd; /* FPU Control Word */
|
u32 cwd; /* FPU Control Word */
|
||||||
u32 swd; /* FPU Status Word */
|
u32 swd; /* FPU Status Word */
|
||||||
u32 twd; /* FPU Tag Word */
|
u32 twd; /* FPU Tag Word */
|
||||||
@@ -20,7 +20,7 @@ struct i387_fsave_struct {
|
|||||||
u32 status;
|
u32 status;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct i387_fxsave_struct {
|
struct fxregs_state {
|
||||||
u16 cwd; /* Control Word */
|
u16 cwd; /* Control Word */
|
||||||
u16 swd; /* Status Word */
|
u16 swd; /* Status Word */
|
||||||
u16 twd; /* Tag Word */
|
u16 twd; /* Tag Word */
|
||||||
@@ -58,7 +58,7 @@ struct i387_fxsave_struct {
|
|||||||
/*
|
/*
|
||||||
* Software based FPU emulation state:
|
* Software based FPU emulation state:
|
||||||
*/
|
*/
|
||||||
struct i387_soft_struct {
|
struct swregs_state {
|
||||||
u32 cwd;
|
u32 cwd;
|
||||||
u32 swd;
|
u32 swd;
|
||||||
u32 twd;
|
u32 twd;
|
||||||
@@ -109,7 +109,7 @@ enum xfeature_bit {
|
|||||||
/*
|
/*
|
||||||
* There are 16x 256-bit AVX registers named YMM0-YMM15.
|
* There are 16x 256-bit AVX registers named YMM0-YMM15.
|
||||||
* The low 128 bits are aliased to the 16 SSE registers (XMM0-XMM15)
|
* The low 128 bits are aliased to the 16 SSE registers (XMM0-XMM15)
|
||||||
* and are stored in 'struct i387_fxsave_struct::xmm_space[]'.
|
* and are stored in 'struct fxregs_state::xmm_space[]'.
|
||||||
*
|
*
|
||||||
* The high 128 bits are stored here:
|
* The high 128 bits are stored here:
|
||||||
* 16x 128 bits == 256 bytes.
|
* 16x 128 bits == 256 bytes.
|
||||||
@@ -140,8 +140,8 @@ struct xstate_header {
|
|||||||
u64 reserved[6];
|
u64 reserved[6];
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
struct xsave_struct {
|
struct xregs_state {
|
||||||
struct i387_fxsave_struct i387;
|
struct fxregs_state i387;
|
||||||
struct xstate_header header;
|
struct xstate_header header;
|
||||||
struct ymmh_struct ymmh;
|
struct ymmh_struct ymmh;
|
||||||
struct lwp_struct lwp;
|
struct lwp_struct lwp;
|
||||||
@@ -150,11 +150,11 @@ struct xsave_struct {
|
|||||||
/* New processor state extensions will go here. */
|
/* New processor state extensions will go here. */
|
||||||
} __attribute__ ((packed, aligned (64)));
|
} __attribute__ ((packed, aligned (64)));
|
||||||
|
|
||||||
union thread_xstate {
|
union fpregs_state {
|
||||||
struct i387_fsave_struct fsave;
|
struct fregs_state fsave;
|
||||||
struct i387_fxsave_struct fxsave;
|
struct fxregs_state fxsave;
|
||||||
struct i387_soft_struct soft;
|
struct swregs_state soft;
|
||||||
struct xsave_struct xsave;
|
struct xregs_state xsave;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct fpu {
|
struct fpu {
|
||||||
@@ -171,7 +171,7 @@ struct fpu {
|
|||||||
unsigned int last_cpu;
|
unsigned int last_cpu;
|
||||||
|
|
||||||
unsigned int fpregs_active;
|
unsigned int fpregs_active;
|
||||||
union thread_xstate state;
|
union fpregs_state state;
|
||||||
/*
|
/*
|
||||||
* This counter contains the number of consecutive context switches
|
* This counter contains the number of consecutive context switches
|
||||||
* during which the FPU stays used. If this is over a threshold, the
|
* during which the FPU stays used. If this is over a threshold, the
|
||||||
|
@@ -58,7 +58,7 @@ extern void update_regset_xstate_info(unsigned int size, u64 xstate_mask);
|
|||||||
* This function is called only during boot time when x86 caps are not set
|
* This function is called only during boot time when x86 caps are not set
|
||||||
* up and alternative can not be used yet.
|
* up and alternative can not be used yet.
|
||||||
*/
|
*/
|
||||||
static inline int copy_xregs_to_kernel_booting(struct xsave_struct *fx)
|
static inline int copy_xregs_to_kernel_booting(struct xregs_state *fx)
|
||||||
{
|
{
|
||||||
u64 mask = -1;
|
u64 mask = -1;
|
||||||
u32 lmask = mask;
|
u32 lmask = mask;
|
||||||
@@ -86,7 +86,7 @@ static inline int copy_xregs_to_kernel_booting(struct xsave_struct *fx)
|
|||||||
* This function is called only during boot time when x86 caps are not set
|
* This function is called only during boot time when x86 caps are not set
|
||||||
* up and alternative can not be used yet.
|
* up and alternative can not be used yet.
|
||||||
*/
|
*/
|
||||||
static inline int copy_kernel_to_xregs_booting(struct xsave_struct *fx, u64 mask)
|
static inline int copy_kernel_to_xregs_booting(struct xregs_state *fx, u64 mask)
|
||||||
{
|
{
|
||||||
u32 lmask = mask;
|
u32 lmask = mask;
|
||||||
u32 hmask = mask >> 32;
|
u32 hmask = mask >> 32;
|
||||||
@@ -112,7 +112,7 @@ static inline int copy_kernel_to_xregs_booting(struct xsave_struct *fx, u64 mask
|
|||||||
/*
|
/*
|
||||||
* Save processor xstate to xsave area.
|
* Save processor xstate to xsave area.
|
||||||
*/
|
*/
|
||||||
static inline int copy_xregs_to_kernel(struct xsave_struct *fx)
|
static inline int copy_xregs_to_kernel(struct xregs_state *fx)
|
||||||
{
|
{
|
||||||
u64 mask = -1;
|
u64 mask = -1;
|
||||||
u32 lmask = mask;
|
u32 lmask = mask;
|
||||||
@@ -151,7 +151,7 @@ static inline int copy_xregs_to_kernel(struct xsave_struct *fx)
|
|||||||
/*
|
/*
|
||||||
* Restore processor xstate from xsave area.
|
* Restore processor xstate from xsave area.
|
||||||
*/
|
*/
|
||||||
static inline int copy_kernel_to_xregs(struct xsave_struct *fx, u64 mask)
|
static inline int copy_kernel_to_xregs(struct xregs_state *fx, u64 mask)
|
||||||
{
|
{
|
||||||
int err = 0;
|
int err = 0;
|
||||||
u32 lmask = mask;
|
u32 lmask = mask;
|
||||||
@@ -186,7 +186,7 @@ static inline int copy_kernel_to_xregs(struct xsave_struct *fx, u64 mask)
|
|||||||
* backward compatibility for old applications which don't understand
|
* backward compatibility for old applications which don't understand
|
||||||
* compacted format of xsave area.
|
* compacted format of xsave area.
|
||||||
*/
|
*/
|
||||||
static inline int copy_xregs_to_user(struct xsave_struct __user *buf)
|
static inline int copy_xregs_to_user(struct xregs_state __user *buf)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
@@ -210,10 +210,10 @@ static inline int copy_xregs_to_user(struct xsave_struct __user *buf)
|
|||||||
/*
|
/*
|
||||||
* Restore xstate from user space xsave area.
|
* Restore xstate from user space xsave area.
|
||||||
*/
|
*/
|
||||||
static inline int copy_user_to_xregs(struct xsave_struct __user *buf, u64 mask)
|
static inline int copy_user_to_xregs(struct xregs_state __user *buf, u64 mask)
|
||||||
{
|
{
|
||||||
int err = 0;
|
int err = 0;
|
||||||
struct xsave_struct *xstate = ((__force struct xsave_struct *)buf);
|
struct xregs_state *xstate = ((__force struct xregs_state *)buf);
|
||||||
u32 lmask = mask;
|
u32 lmask = mask;
|
||||||
u32 hmask = mask >> 32;
|
u32 hmask = mask >> 32;
|
||||||
|
|
||||||
@@ -226,7 +226,7 @@ static inline int copy_user_to_xregs(struct xsave_struct __user *buf, u64 mask)
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *get_xsave_addr(struct xsave_struct *xsave, int xstate);
|
void *get_xsave_addr(struct xregs_state *xsave, int xstate);
|
||||||
void setup_xstate_comp(void);
|
void setup_xstate_comp(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -60,8 +60,8 @@
|
|||||||
|
|
||||||
#ifdef CONFIG_X86_INTEL_MPX
|
#ifdef CONFIG_X86_INTEL_MPX
|
||||||
siginfo_t *mpx_generate_siginfo(struct pt_regs *regs,
|
siginfo_t *mpx_generate_siginfo(struct pt_regs *regs,
|
||||||
struct xsave_struct *xsave_buf);
|
struct xregs_state *xsave_buf);
|
||||||
int mpx_handle_bd_fault(struct xsave_struct *xsave_buf);
|
int mpx_handle_bd_fault(struct xregs_state *xsave_buf);
|
||||||
static inline int kernel_managing_mpx_tables(struct mm_struct *mm)
|
static inline int kernel_managing_mpx_tables(struct mm_struct *mm)
|
||||||
{
|
{
|
||||||
return (mm->bd_addr != MPX_INVALID_BOUNDS_DIR);
|
return (mm->bd_addr != MPX_INVALID_BOUNDS_DIR);
|
||||||
@@ -78,11 +78,11 @@ void mpx_notify_unmap(struct mm_struct *mm, struct vm_area_struct *vma,
|
|||||||
unsigned long start, unsigned long end);
|
unsigned long start, unsigned long end);
|
||||||
#else
|
#else
|
||||||
static inline siginfo_t *mpx_generate_siginfo(struct pt_regs *regs,
|
static inline siginfo_t *mpx_generate_siginfo(struct pt_regs *regs,
|
||||||
struct xsave_struct *xsave_buf)
|
struct xregs_state *xsave_buf)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
static inline int mpx_handle_bd_fault(struct xsave_struct *xsave_buf)
|
static inline int mpx_handle_bd_fault(struct xregs_state *xsave_buf)
|
||||||
{
|
{
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
@@ -16,7 +16,7 @@
|
|||||||
* Represents the initial FPU state. It's mostly (but not completely) zeroes,
|
* Represents the initial FPU state. It's mostly (but not completely) zeroes,
|
||||||
* depending on the FPU hardware format:
|
* depending on the FPU hardware format:
|
||||||
*/
|
*/
|
||||||
union thread_xstate init_fpstate __read_mostly;
|
union fpregs_state init_fpstate __read_mostly;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Track whether the kernel is using the FPU state
|
* Track whether the kernel is using the FPU state
|
||||||
@@ -200,7 +200,7 @@ EXPORT_SYMBOL_GPL(fpu__save);
|
|||||||
/*
|
/*
|
||||||
* Legacy x87 fpstate state init:
|
* Legacy x87 fpstate state init:
|
||||||
*/
|
*/
|
||||||
static inline void fpstate_init_fstate(struct i387_fsave_struct *fp)
|
static inline void fpstate_init_fstate(struct fregs_state *fp)
|
||||||
{
|
{
|
||||||
fp->cwd = 0xffff037fu;
|
fp->cwd = 0xffff037fu;
|
||||||
fp->swd = 0xffff0000u;
|
fp->swd = 0xffff0000u;
|
||||||
@@ -208,7 +208,7 @@ static inline void fpstate_init_fstate(struct i387_fsave_struct *fp)
|
|||||||
fp->fos = 0xffff0000u;
|
fp->fos = 0xffff0000u;
|
||||||
}
|
}
|
||||||
|
|
||||||
void fpstate_init(union thread_xstate *state)
|
void fpstate_init(union fpregs_state *state)
|
||||||
{
|
{
|
||||||
if (!cpu_has_fpu) {
|
if (!cpu_has_fpu) {
|
||||||
fpstate_init_soft(&state->soft);
|
fpstate_init_soft(&state->soft);
|
||||||
|
@@ -95,7 +95,7 @@ static void fpu__init_system_mxcsr(void)
|
|||||||
unsigned int mask = 0;
|
unsigned int mask = 0;
|
||||||
|
|
||||||
if (cpu_has_fxsr) {
|
if (cpu_has_fxsr) {
|
||||||
struct i387_fxsave_struct fx_tmp __aligned(32) = { };
|
struct fxregs_state fx_tmp __aligned(32) = { };
|
||||||
|
|
||||||
asm volatile("fxsave %0" : "+m" (fx_tmp));
|
asm volatile("fxsave %0" : "+m" (fx_tmp));
|
||||||
|
|
||||||
@@ -155,12 +155,12 @@ static void fpu__init_system_xstate_size_legacy(void)
|
|||||||
*/
|
*/
|
||||||
setup_clear_cpu_cap(X86_FEATURE_XSAVE);
|
setup_clear_cpu_cap(X86_FEATURE_XSAVE);
|
||||||
setup_clear_cpu_cap(X86_FEATURE_XSAVEOPT);
|
setup_clear_cpu_cap(X86_FEATURE_XSAVEOPT);
|
||||||
xstate_size = sizeof(struct i387_soft_struct);
|
xstate_size = sizeof(struct swregs_state);
|
||||||
} else {
|
} else {
|
||||||
if (cpu_has_fxsr)
|
if (cpu_has_fxsr)
|
||||||
xstate_size = sizeof(struct i387_fxsave_struct);
|
xstate_size = sizeof(struct fxregs_state);
|
||||||
else
|
else
|
||||||
xstate_size = sizeof(struct i387_fsave_struct);
|
xstate_size = sizeof(struct fregs_state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -76,7 +76,7 @@ int xstateregs_get(struct task_struct *target, const struct user_regset *regset,
|
|||||||
void *kbuf, void __user *ubuf)
|
void *kbuf, void __user *ubuf)
|
||||||
{
|
{
|
||||||
struct fpu *fpu = &target->thread.fpu;
|
struct fpu *fpu = &target->thread.fpu;
|
||||||
struct xsave_struct *xsave;
|
struct xregs_state *xsave;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!cpu_has_xsave)
|
if (!cpu_has_xsave)
|
||||||
@@ -105,7 +105,7 @@ int xstateregs_set(struct task_struct *target, const struct user_regset *regset,
|
|||||||
const void *kbuf, const void __user *ubuf)
|
const void *kbuf, const void __user *ubuf)
|
||||||
{
|
{
|
||||||
struct fpu *fpu = &target->thread.fpu;
|
struct fpu *fpu = &target->thread.fpu;
|
||||||
struct xsave_struct *xsave;
|
struct xregs_state *xsave;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!cpu_has_xsave)
|
if (!cpu_has_xsave)
|
||||||
@@ -156,7 +156,7 @@ static inline unsigned short twd_i387_to_fxsr(unsigned short twd)
|
|||||||
#define FP_EXP_TAG_SPECIAL 2
|
#define FP_EXP_TAG_SPECIAL 2
|
||||||
#define FP_EXP_TAG_EMPTY 3
|
#define FP_EXP_TAG_EMPTY 3
|
||||||
|
|
||||||
static inline u32 twd_fxsr_to_i387(struct i387_fxsave_struct *fxsave)
|
static inline u32 twd_fxsr_to_i387(struct fxregs_state *fxsave)
|
||||||
{
|
{
|
||||||
struct _fpxreg *st;
|
struct _fpxreg *st;
|
||||||
u32 tos = (fxsave->swd >> 11) & 7;
|
u32 tos = (fxsave->swd >> 11) & 7;
|
||||||
@@ -204,7 +204,7 @@ static inline u32 twd_fxsr_to_i387(struct i387_fxsave_struct *fxsave)
|
|||||||
void
|
void
|
||||||
convert_from_fxsr(struct user_i387_ia32_struct *env, struct task_struct *tsk)
|
convert_from_fxsr(struct user_i387_ia32_struct *env, struct task_struct *tsk)
|
||||||
{
|
{
|
||||||
struct i387_fxsave_struct *fxsave = &tsk->thread.fpu.state.fxsave;
|
struct fxregs_state *fxsave = &tsk->thread.fpu.state.fxsave;
|
||||||
struct _fpreg *to = (struct _fpreg *) &env->st_space[0];
|
struct _fpreg *to = (struct _fpreg *) &env->st_space[0];
|
||||||
struct _fpxreg *from = (struct _fpxreg *) &fxsave->st_space[0];
|
struct _fpxreg *from = (struct _fpxreg *) &fxsave->st_space[0];
|
||||||
int i;
|
int i;
|
||||||
@@ -242,7 +242,7 @@ void convert_to_fxsr(struct task_struct *tsk,
|
|||||||
const struct user_i387_ia32_struct *env)
|
const struct user_i387_ia32_struct *env)
|
||||||
|
|
||||||
{
|
{
|
||||||
struct i387_fxsave_struct *fxsave = &tsk->thread.fpu.state.fxsave;
|
struct fxregs_state *fxsave = &tsk->thread.fpu.state.fxsave;
|
||||||
struct _fpreg *from = (struct _fpreg *) &env->st_space[0];
|
struct _fpreg *from = (struct _fpreg *) &env->st_space[0];
|
||||||
struct _fpxreg *to = (struct _fpxreg *) &fxsave->st_space[0];
|
struct _fpxreg *to = (struct _fpxreg *) &fxsave->st_space[0];
|
||||||
int i;
|
int i;
|
||||||
|
@@ -17,11 +17,11 @@ static struct _fpx_sw_bytes fx_sw_reserved, fx_sw_reserved_ia32;
|
|||||||
* Check for the presence of extended state information in the
|
* Check for the presence of extended state information in the
|
||||||
* user fpstate pointer in the sigcontext.
|
* user fpstate pointer in the sigcontext.
|
||||||
*/
|
*/
|
||||||
static inline int check_for_xstate(struct i387_fxsave_struct __user *buf,
|
static inline int check_for_xstate(struct fxregs_state __user *buf,
|
||||||
void __user *fpstate,
|
void __user *fpstate,
|
||||||
struct _fpx_sw_bytes *fx_sw)
|
struct _fpx_sw_bytes *fx_sw)
|
||||||
{
|
{
|
||||||
int min_xstate_size = sizeof(struct i387_fxsave_struct) +
|
int min_xstate_size = sizeof(struct fxregs_state) +
|
||||||
sizeof(struct xstate_header);
|
sizeof(struct xstate_header);
|
||||||
unsigned int magic2;
|
unsigned int magic2;
|
||||||
|
|
||||||
@@ -54,7 +54,7 @@ static inline int check_for_xstate(struct i387_fxsave_struct __user *buf,
|
|||||||
static inline int save_fsave_header(struct task_struct *tsk, void __user *buf)
|
static inline int save_fsave_header(struct task_struct *tsk, void __user *buf)
|
||||||
{
|
{
|
||||||
if (use_fxsr()) {
|
if (use_fxsr()) {
|
||||||
struct xsave_struct *xsave = &tsk->thread.fpu.state.xsave;
|
struct xregs_state *xsave = &tsk->thread.fpu.state.xsave;
|
||||||
struct user_i387_ia32_struct env;
|
struct user_i387_ia32_struct env;
|
||||||
struct _fpstate_ia32 __user *fp = buf;
|
struct _fpstate_ia32 __user *fp = buf;
|
||||||
|
|
||||||
@@ -65,7 +65,7 @@ static inline int save_fsave_header(struct task_struct *tsk, void __user *buf)
|
|||||||
__put_user(X86_FXSR_MAGIC, &fp->magic))
|
__put_user(X86_FXSR_MAGIC, &fp->magic))
|
||||||
return -1;
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
struct i387_fsave_struct __user *fp = buf;
|
struct fregs_state __user *fp = buf;
|
||||||
u32 swd;
|
u32 swd;
|
||||||
if (__get_user(swd, &fp->swd) || __put_user(swd, &fp->status))
|
if (__get_user(swd, &fp->swd) || __put_user(swd, &fp->status))
|
||||||
return -1;
|
return -1;
|
||||||
@@ -76,7 +76,7 @@ static inline int save_fsave_header(struct task_struct *tsk, void __user *buf)
|
|||||||
|
|
||||||
static inline int save_xstate_epilog(void __user *buf, int ia32_frame)
|
static inline int save_xstate_epilog(void __user *buf, int ia32_frame)
|
||||||
{
|
{
|
||||||
struct xsave_struct __user *x = buf;
|
struct xregs_state __user *x = buf;
|
||||||
struct _fpx_sw_bytes *sw_bytes;
|
struct _fpx_sw_bytes *sw_bytes;
|
||||||
u32 xfeatures;
|
u32 xfeatures;
|
||||||
int err;
|
int err;
|
||||||
@@ -114,16 +114,16 @@ static inline int save_xstate_epilog(void __user *buf, int ia32_frame)
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int copy_fpregs_to_sigframe(struct xsave_struct __user *buf)
|
static inline int copy_fpregs_to_sigframe(struct xregs_state __user *buf)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (use_xsave())
|
if (use_xsave())
|
||||||
err = copy_xregs_to_user(buf);
|
err = copy_xregs_to_user(buf);
|
||||||
else if (use_fxsr())
|
else if (use_fxsr())
|
||||||
err = copy_fxregs_to_user((struct i387_fxsave_struct __user *) buf);
|
err = copy_fxregs_to_user((struct fxregs_state __user *) buf);
|
||||||
else
|
else
|
||||||
err = copy_fregs_to_user((struct i387_fsave_struct __user *) buf);
|
err = copy_fregs_to_user((struct fregs_state __user *) buf);
|
||||||
|
|
||||||
if (unlikely(err) && __clear_user(buf, xstate_size))
|
if (unlikely(err) && __clear_user(buf, xstate_size))
|
||||||
err = -EFAULT;
|
err = -EFAULT;
|
||||||
@@ -152,7 +152,7 @@ static inline int copy_fpregs_to_sigframe(struct xsave_struct __user *buf)
|
|||||||
*/
|
*/
|
||||||
int copy_fpstate_to_sigframe(void __user *buf, void __user *buf_fx, int size)
|
int copy_fpstate_to_sigframe(void __user *buf, void __user *buf_fx, int size)
|
||||||
{
|
{
|
||||||
struct xsave_struct *xsave = ¤t->thread.fpu.state.xsave;
|
struct xregs_state *xsave = ¤t->thread.fpu.state.xsave;
|
||||||
struct task_struct *tsk = current;
|
struct task_struct *tsk = current;
|
||||||
int ia32_fxstate = (buf != buf_fx);
|
int ia32_fxstate = (buf != buf_fx);
|
||||||
|
|
||||||
@@ -195,7 +195,7 @@ sanitize_restored_xstate(struct task_struct *tsk,
|
|||||||
struct user_i387_ia32_struct *ia32_env,
|
struct user_i387_ia32_struct *ia32_env,
|
||||||
u64 xfeatures, int fx_only)
|
u64 xfeatures, int fx_only)
|
||||||
{
|
{
|
||||||
struct xsave_struct *xsave = &tsk->thread.fpu.state.xsave;
|
struct xregs_state *xsave = &tsk->thread.fpu.state.xsave;
|
||||||
struct xstate_header *header = &xsave->header;
|
struct xstate_header *header = &xsave->header;
|
||||||
|
|
||||||
if (use_xsave()) {
|
if (use_xsave()) {
|
||||||
@@ -280,7 +280,7 @@ static int __fpu__restore_sig(void __user *buf, void __user *buf_fx, int size)
|
|||||||
* memory layout. Restore just the FP/SSE and init all
|
* memory layout. Restore just the FP/SSE and init all
|
||||||
* the other extended state.
|
* the other extended state.
|
||||||
*/
|
*/
|
||||||
state_size = sizeof(struct i387_fxsave_struct);
|
state_size = sizeof(struct fxregs_state);
|
||||||
fx_only = 1;
|
fx_only = 1;
|
||||||
} else {
|
} else {
|
||||||
state_size = fx_sw_user.xstate_size;
|
state_size = fx_sw_user.xstate_size;
|
||||||
@@ -353,8 +353,8 @@ int fpu__restore_sig(void __user *buf, int ia32_frame)
|
|||||||
int size = xstate_sigframe_size();
|
int size = xstate_sigframe_size();
|
||||||
|
|
||||||
if (ia32_frame && use_fxsr()) {
|
if (ia32_frame && use_fxsr()) {
|
||||||
buf_fx = buf + sizeof(struct i387_fsave_struct);
|
buf_fx = buf + sizeof(struct fregs_state);
|
||||||
size += sizeof(struct i387_fsave_struct);
|
size += sizeof(struct fregs_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
return __fpu__restore_sig(buf, buf_fx, size);
|
return __fpu__restore_sig(buf, buf_fx, size);
|
||||||
@@ -368,8 +368,8 @@ fpu__alloc_mathframe(unsigned long sp, int ia32_frame,
|
|||||||
|
|
||||||
*buf_fx = sp = round_down(sp - frame_size, 64);
|
*buf_fx = sp = round_down(sp - frame_size, 64);
|
||||||
if (ia32_frame && use_fxsr()) {
|
if (ia32_frame && use_fxsr()) {
|
||||||
frame_size += sizeof(struct i387_fsave_struct);
|
frame_size += sizeof(struct fregs_state);
|
||||||
sp -= sizeof(struct i387_fsave_struct);
|
sp -= sizeof(struct fregs_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
*size = frame_size;
|
*size = frame_size;
|
||||||
@@ -385,7 +385,7 @@ fpu__alloc_mathframe(unsigned long sp, int ia32_frame,
|
|||||||
*/
|
*/
|
||||||
void fpu__init_prepare_fx_sw_frame(void)
|
void fpu__init_prepare_fx_sw_frame(void)
|
||||||
{
|
{
|
||||||
int fsave_header_size = sizeof(struct i387_fsave_struct);
|
int fsave_header_size = sizeof(struct fregs_state);
|
||||||
int size = xstate_size + FP_XSTATE_MAGIC2_SIZE;
|
int size = xstate_size + FP_XSTATE_MAGIC2_SIZE;
|
||||||
|
|
||||||
if (config_enabled(CONFIG_X86_32))
|
if (config_enabled(CONFIG_X86_32))
|
||||||
|
@@ -91,7 +91,7 @@ EXPORT_SYMBOL_GPL(cpu_has_xfeatures);
|
|||||||
*/
|
*/
|
||||||
void fpstate_sanitize_xstate(struct fpu *fpu)
|
void fpstate_sanitize_xstate(struct fpu *fpu)
|
||||||
{
|
{
|
||||||
struct i387_fxsave_struct *fx = &fpu->state.fxsave;
|
struct fxregs_state *fx = &fpu->state.fxsave;
|
||||||
int feature_bit;
|
int feature_bit;
|
||||||
u64 xfeatures;
|
u64 xfeatures;
|
||||||
|
|
||||||
@@ -231,7 +231,7 @@ void setup_xstate_comp(void)
|
|||||||
* or standard form.
|
* or standard form.
|
||||||
*/
|
*/
|
||||||
xstate_comp_offsets[0] = 0;
|
xstate_comp_offsets[0] = 0;
|
||||||
xstate_comp_offsets[1] = offsetof(struct i387_fxsave_struct, xmm_space);
|
xstate_comp_offsets[1] = offsetof(struct fxregs_state, xmm_space);
|
||||||
|
|
||||||
if (!cpu_has_xsaves) {
|
if (!cpu_has_xsaves) {
|
||||||
for (i = 2; i < xfeatures_nr; i++) {
|
for (i = 2; i < xfeatures_nr; i++) {
|
||||||
@@ -386,7 +386,7 @@ void fpu__resume_cpu(void)
|
|||||||
* Output:
|
* Output:
|
||||||
* address of the state in the xsave area.
|
* address of the state in the xsave area.
|
||||||
*/
|
*/
|
||||||
void *get_xsave_addr(struct xsave_struct *xsave, int xstate)
|
void *get_xsave_addr(struct xregs_state *xsave, int xstate)
|
||||||
{
|
{
|
||||||
int feature = fls64(xstate) - 1;
|
int feature = fls64(xstate) - 1;
|
||||||
if (!test_bit(feature, (unsigned long *)&xfeatures_mask))
|
if (!test_bit(feature, (unsigned long *)&xfeatures_mask))
|
||||||
|
@@ -371,7 +371,7 @@ dotraplinkage void do_double_fault(struct pt_regs *regs, long error_code)
|
|||||||
dotraplinkage void do_bounds(struct pt_regs *regs, long error_code)
|
dotraplinkage void do_bounds(struct pt_regs *regs, long error_code)
|
||||||
{
|
{
|
||||||
struct task_struct *tsk = current;
|
struct task_struct *tsk = current;
|
||||||
struct xsave_struct *xsave_buf;
|
struct xregs_state *xsave_buf;
|
||||||
enum ctx_state prev_state;
|
enum ctx_state prev_state;
|
||||||
struct bndcsr *bndcsr;
|
struct bndcsr *bndcsr;
|
||||||
siginfo_t *info;
|
siginfo_t *info;
|
||||||
|
@@ -3195,7 +3195,7 @@ static int kvm_vcpu_ioctl_x86_set_debugregs(struct kvm_vcpu *vcpu,
|
|||||||
|
|
||||||
static void fill_xsave(u8 *dest, struct kvm_vcpu *vcpu)
|
static void fill_xsave(u8 *dest, struct kvm_vcpu *vcpu)
|
||||||
{
|
{
|
||||||
struct xsave_struct *xsave = &vcpu->arch.guest_fpu.state.xsave;
|
struct xregs_state *xsave = &vcpu->arch.guest_fpu.state.xsave;
|
||||||
u64 xstate_bv = xsave->header.xfeatures;
|
u64 xstate_bv = xsave->header.xfeatures;
|
||||||
u64 valid;
|
u64 valid;
|
||||||
|
|
||||||
@@ -3231,7 +3231,7 @@ static void fill_xsave(u8 *dest, struct kvm_vcpu *vcpu)
|
|||||||
|
|
||||||
static void load_xsave(struct kvm_vcpu *vcpu, u8 *src)
|
static void load_xsave(struct kvm_vcpu *vcpu, u8 *src)
|
||||||
{
|
{
|
||||||
struct xsave_struct *xsave = &vcpu->arch.guest_fpu.state.xsave;
|
struct xregs_state *xsave = &vcpu->arch.guest_fpu.state.xsave;
|
||||||
u64 xstate_bv = *(u64 *)(src + XSAVE_HDR_OFFSET);
|
u64 xstate_bv = *(u64 *)(src + XSAVE_HDR_OFFSET);
|
||||||
u64 valid;
|
u64 valid;
|
||||||
|
|
||||||
@@ -3277,7 +3277,7 @@ static void kvm_vcpu_ioctl_x86_get_xsave(struct kvm_vcpu *vcpu,
|
|||||||
} else {
|
} else {
|
||||||
memcpy(guest_xsave->region,
|
memcpy(guest_xsave->region,
|
||||||
&vcpu->arch.guest_fpu.state.fxsave,
|
&vcpu->arch.guest_fpu.state.fxsave,
|
||||||
sizeof(struct i387_fxsave_struct));
|
sizeof(struct fxregs_state));
|
||||||
*(u64 *)&guest_xsave->region[XSAVE_HDR_OFFSET / sizeof(u32)] =
|
*(u64 *)&guest_xsave->region[XSAVE_HDR_OFFSET / sizeof(u32)] =
|
||||||
XSTATE_FPSSE;
|
XSTATE_FPSSE;
|
||||||
}
|
}
|
||||||
@@ -3302,7 +3302,7 @@ static int kvm_vcpu_ioctl_x86_set_xsave(struct kvm_vcpu *vcpu,
|
|||||||
if (xstate_bv & ~XSTATE_FPSSE)
|
if (xstate_bv & ~XSTATE_FPSSE)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
memcpy(&vcpu->arch.guest_fpu.state.fxsave,
|
memcpy(&vcpu->arch.guest_fpu.state.fxsave,
|
||||||
guest_xsave->region, sizeof(struct i387_fxsave_struct));
|
guest_xsave->region, sizeof(struct fxregs_state));
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -6970,7 +6970,7 @@ int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
|
|||||||
|
|
||||||
int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
|
int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
|
||||||
{
|
{
|
||||||
struct i387_fxsave_struct *fxsave =
|
struct fxregs_state *fxsave =
|
||||||
&vcpu->arch.guest_fpu.state.fxsave;
|
&vcpu->arch.guest_fpu.state.fxsave;
|
||||||
|
|
||||||
memcpy(fpu->fpr, fxsave->st_space, 128);
|
memcpy(fpu->fpr, fxsave->st_space, 128);
|
||||||
@@ -6987,7 +6987,7 @@ int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
|
|||||||
|
|
||||||
int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
|
int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
|
||||||
{
|
{
|
||||||
struct i387_fxsave_struct *fxsave =
|
struct fxregs_state *fxsave =
|
||||||
&vcpu->arch.guest_fpu.state.fxsave;
|
&vcpu->arch.guest_fpu.state.fxsave;
|
||||||
|
|
||||||
memcpy(fxsave->st_space, fpu->fpr, 128);
|
memcpy(fxsave->st_space, fpu->fpr, 128);
|
||||||
|
@@ -30,7 +30,7 @@ static void fclex(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Needs to be externally visible */
|
/* Needs to be externally visible */
|
||||||
void fpstate_init_soft(struct i387_soft_struct *soft)
|
void fpstate_init_soft(struct swregs_state *soft)
|
||||||
{
|
{
|
||||||
struct address *oaddr, *iaddr;
|
struct address *oaddr, *iaddr;
|
||||||
memset(soft, 0, sizeof(*soft));
|
memset(soft, 0, sizeof(*soft));
|
||||||
|
@@ -669,7 +669,7 @@ void math_abort(struct math_emu_info *info, unsigned int signal)
|
|||||||
#endif /* PARANOID */
|
#endif /* PARANOID */
|
||||||
}
|
}
|
||||||
|
|
||||||
#define S387 ((struct i387_soft_struct *)s387)
|
#define S387 ((struct swregs_state *)s387)
|
||||||
#define sstatus_word() \
|
#define sstatus_word() \
|
||||||
((S387->swd & ~SW_Top & 0xffff) | ((S387->ftop << SW_Top_Shift) & SW_Top))
|
((S387->swd & ~SW_Top & 0xffff) | ((S387->ftop << SW_Top_Shift) & SW_Top))
|
||||||
|
|
||||||
@@ -678,14 +678,14 @@ int fpregs_soft_set(struct task_struct *target,
|
|||||||
unsigned int pos, unsigned int count,
|
unsigned int pos, unsigned int count,
|
||||||
const void *kbuf, const void __user *ubuf)
|
const void *kbuf, const void __user *ubuf)
|
||||||
{
|
{
|
||||||
struct i387_soft_struct *s387 = &target->thread.fpu.state.soft;
|
struct swregs_state *s387 = &target->thread.fpu.state.soft;
|
||||||
void *space = s387->st_space;
|
void *space = s387->st_space;
|
||||||
int ret;
|
int ret;
|
||||||
int offset, other, i, tags, regnr, tag, newtop;
|
int offset, other, i, tags, regnr, tag, newtop;
|
||||||
|
|
||||||
RE_ENTRANT_CHECK_OFF;
|
RE_ENTRANT_CHECK_OFF;
|
||||||
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, s387, 0,
|
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, s387, 0,
|
||||||
offsetof(struct i387_soft_struct, st_space));
|
offsetof(struct swregs_state, st_space));
|
||||||
RE_ENTRANT_CHECK_ON;
|
RE_ENTRANT_CHECK_ON;
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
@@ -730,7 +730,7 @@ int fpregs_soft_get(struct task_struct *target,
|
|||||||
unsigned int pos, unsigned int count,
|
unsigned int pos, unsigned int count,
|
||||||
void *kbuf, void __user *ubuf)
|
void *kbuf, void __user *ubuf)
|
||||||
{
|
{
|
||||||
struct i387_soft_struct *s387 = &target->thread.fpu.state.soft;
|
struct swregs_state *s387 = &target->thread.fpu.state.soft;
|
||||||
const void *space = s387->st_space;
|
const void *space = s387->st_space;
|
||||||
int ret;
|
int ret;
|
||||||
int offset = (S387->ftop & 7) * 10, other = 80 - offset;
|
int offset = (S387->ftop & 7) * 10, other = 80 - offset;
|
||||||
@@ -748,7 +748,7 @@ int fpregs_soft_get(struct task_struct *target,
|
|||||||
#endif /* PECULIAR_486 */
|
#endif /* PECULIAR_486 */
|
||||||
|
|
||||||
ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, s387, 0,
|
ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, s387, 0,
|
||||||
offsetof(struct i387_soft_struct, st_space));
|
offsetof(struct swregs_state, st_space));
|
||||||
|
|
||||||
/* Copy all registers in stack order. */
|
/* Copy all registers in stack order. */
|
||||||
if (!ret)
|
if (!ret)
|
||||||
|
@@ -272,7 +272,7 @@ bad_opcode:
|
|||||||
* The caller is expected to kfree() the returned siginfo_t.
|
* The caller is expected to kfree() the returned siginfo_t.
|
||||||
*/
|
*/
|
||||||
siginfo_t *mpx_generate_siginfo(struct pt_regs *regs,
|
siginfo_t *mpx_generate_siginfo(struct pt_regs *regs,
|
||||||
struct xsave_struct *xsave_buf)
|
struct xregs_state *xsave_buf)
|
||||||
{
|
{
|
||||||
struct bndreg *bndregs, *bndreg;
|
struct bndreg *bndregs, *bndreg;
|
||||||
siginfo_t *info = NULL;
|
siginfo_t *info = NULL;
|
||||||
@@ -497,7 +497,7 @@ out_unmap:
|
|||||||
* bound table is 16KB. With 64-bit mode, the size of BD is 2GB,
|
* bound table is 16KB. With 64-bit mode, the size of BD is 2GB,
|
||||||
* and the size of each bound table is 4MB.
|
* and the size of each bound table is 4MB.
|
||||||
*/
|
*/
|
||||||
static int do_mpx_bt_fault(struct xsave_struct *xsave_buf)
|
static int do_mpx_bt_fault(struct xregs_state *xsave_buf)
|
||||||
{
|
{
|
||||||
unsigned long bd_entry, bd_base;
|
unsigned long bd_entry, bd_base;
|
||||||
struct bndcsr *bndcsr;
|
struct bndcsr *bndcsr;
|
||||||
@@ -525,7 +525,7 @@ static int do_mpx_bt_fault(struct xsave_struct *xsave_buf)
|
|||||||
return allocate_bt((long __user *)bd_entry);
|
return allocate_bt((long __user *)bd_entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
int mpx_handle_bd_fault(struct xsave_struct *xsave_buf)
|
int mpx_handle_bd_fault(struct xregs_state *xsave_buf)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Userspace never asked us to manage the bounds tables,
|
* Userspace never asked us to manage the bounds tables,
|
||||||
|
Reference in New Issue
Block a user