x86/fpu: Move legacy ASM wrappers to core
Nothing outside the core code requires them. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Borislav Petkov <bp@suse.de> Link: https://lkml.kernel.org/r/20211015011539.572439164@linutronix.de
This commit is contained in:
parent
df95b0f1aa
commit
34002571cb
|
@ -60,107 +60,6 @@ extern void fpstate_init_soft(struct swregs_state *soft);
|
|||
static inline void fpstate_init_soft(struct swregs_state *soft) {}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Returns 0 on success or the trap number when the operation raises an
|
||||
* exception.
|
||||
*/
|
||||
#define user_insn(insn, output, input...) \
|
||||
({ \
|
||||
int err; \
|
||||
\
|
||||
might_fault(); \
|
||||
\
|
||||
asm volatile(ASM_STAC "\n" \
|
||||
"1: " #insn "\n" \
|
||||
"2: " ASM_CLAC "\n" \
|
||||
_ASM_EXTABLE_TYPE(1b, 2b, EX_TYPE_FAULT_MCE_SAFE) \
|
||||
: [err] "=a" (err), output \
|
||||
: "0"(0), input); \
|
||||
err; \
|
||||
})
|
||||
|
||||
#define kernel_insn_err(insn, output, input...) \
|
||||
({ \
|
||||
int err; \
|
||||
asm volatile("1:" #insn "\n\t" \
|
||||
"2:\n" \
|
||||
".section .fixup,\"ax\"\n" \
|
||||
"3: movl $-1,%[err]\n" \
|
||||
" jmp 2b\n" \
|
||||
".previous\n" \
|
||||
_ASM_EXTABLE(1b, 3b) \
|
||||
: [err] "=r" (err), output \
|
||||
: "0"(0), input); \
|
||||
err; \
|
||||
})
|
||||
|
||||
#define kernel_insn(insn, output, input...) \
|
||||
asm volatile("1:" #insn "\n\t" \
|
||||
"2:\n" \
|
||||
_ASM_EXTABLE_TYPE(1b, 2b, EX_TYPE_FPU_RESTORE) \
|
||||
: output : input)
|
||||
|
||||
static inline int fnsave_to_user_sigframe(struct fregs_state __user *fx)
|
||||
{
|
||||
return user_insn(fnsave %[fx]; fwait, [fx] "=m" (*fx), "m" (*fx));
|
||||
}
|
||||
|
||||
static inline int fxsave_to_user_sigframe(struct fxregs_state __user *fx)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_X86_32))
|
||||
return user_insn(fxsave %[fx], [fx] "=m" (*fx), "m" (*fx));
|
||||
else
|
||||
return user_insn(fxsaveq %[fx], [fx] "=m" (*fx), "m" (*fx));
|
||||
|
||||
}
|
||||
|
||||
static inline void fxrstor(struct fxregs_state *fx)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_X86_32))
|
||||
kernel_insn(fxrstor %[fx], "=m" (*fx), [fx] "m" (*fx));
|
||||
else
|
||||
kernel_insn(fxrstorq %[fx], "=m" (*fx), [fx] "m" (*fx));
|
||||
}
|
||||
|
||||
static inline int fxrstor_safe(struct fxregs_state *fx)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_X86_32))
|
||||
return kernel_insn_err(fxrstor %[fx], "=m" (*fx), [fx] "m" (*fx));
|
||||
else
|
||||
return kernel_insn_err(fxrstorq %[fx], "=m" (*fx), [fx] "m" (*fx));
|
||||
}
|
||||
|
||||
static inline int fxrstor_from_user_sigframe(struct fxregs_state __user *fx)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_X86_32))
|
||||
return user_insn(fxrstor %[fx], "=m" (*fx), [fx] "m" (*fx));
|
||||
else
|
||||
return user_insn(fxrstorq %[fx], "=m" (*fx), [fx] "m" (*fx));
|
||||
}
|
||||
|
||||
static inline void frstor(struct fregs_state *fx)
|
||||
{
|
||||
kernel_insn(frstor %[fx], "=m" (*fx), [fx] "m" (*fx));
|
||||
}
|
||||
|
||||
static inline int frstor_safe(struct fregs_state *fx)
|
||||
{
|
||||
return kernel_insn_err(frstor %[fx], "=m" (*fx), [fx] "m" (*fx));
|
||||
}
|
||||
|
||||
static inline int frstor_from_user_sigframe(struct fregs_state __user *fx)
|
||||
{
|
||||
return user_insn(frstor %[fx], "=m" (*fx), [fx] "m" (*fx));
|
||||
}
|
||||
|
||||
static inline void fxsave(struct fxregs_state *fx)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_X86_32))
|
||||
asm volatile( "fxsave %[fx]" : [fx] "=m" (*fx));
|
||||
else
|
||||
asm volatile("fxsaveq %[fx]" : [fx] "=m" (*fx));
|
||||
}
|
||||
|
||||
extern void restore_fpregs_from_fpstate(union fpregs_state *fpstate, u64 mask);
|
||||
|
||||
extern bool copy_fpstate_to_sigframe(void __user *buf, void __user *fp, int size);
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include <linux/pkeys.h>
|
||||
|
||||
#include "internal.h"
|
||||
#include "legacy.h"
|
||||
#include "xstate.h"
|
||||
|
||||
#define CREATE_TRACE_POINTS
|
||||
|
|
|
@ -0,0 +1,108 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __X86_KERNEL_FPU_LEGACY_H
|
||||
#define __X86_KERNEL_FPU_LEGACY_H
|
||||
|
||||
#include <asm/fpu/types.h>
|
||||
|
||||
/*
|
||||
* Returns 0 on success or the trap number when the operation raises an
|
||||
* exception.
|
||||
*/
|
||||
#define user_insn(insn, output, input...) \
|
||||
({ \
|
||||
int err; \
|
||||
\
|
||||
might_fault(); \
|
||||
\
|
||||
asm volatile(ASM_STAC "\n" \
|
||||
"1: " #insn "\n" \
|
||||
"2: " ASM_CLAC "\n" \
|
||||
_ASM_EXTABLE_TYPE(1b, 2b, EX_TYPE_FAULT_MCE_SAFE) \
|
||||
: [err] "=a" (err), output \
|
||||
: "0"(0), input); \
|
||||
err; \
|
||||
})
|
||||
|
||||
#define kernel_insn_err(insn, output, input...) \
|
||||
({ \
|
||||
int err; \
|
||||
asm volatile("1:" #insn "\n\t" \
|
||||
"2:\n" \
|
||||
".section .fixup,\"ax\"\n" \
|
||||
"3: movl $-1,%[err]\n" \
|
||||
" jmp 2b\n" \
|
||||
".previous\n" \
|
||||
_ASM_EXTABLE(1b, 3b) \
|
||||
: [err] "=r" (err), output \
|
||||
: "0"(0), input); \
|
||||
err; \
|
||||
})
|
||||
|
||||
#define kernel_insn(insn, output, input...) \
|
||||
asm volatile("1:" #insn "\n\t" \
|
||||
"2:\n" \
|
||||
_ASM_EXTABLE_TYPE(1b, 2b, EX_TYPE_FPU_RESTORE) \
|
||||
: output : input)
|
||||
|
||||
static inline int fnsave_to_user_sigframe(struct fregs_state __user *fx)
|
||||
{
|
||||
return user_insn(fnsave %[fx]; fwait, [fx] "=m" (*fx), "m" (*fx));
|
||||
}
|
||||
|
||||
static inline int fxsave_to_user_sigframe(struct fxregs_state __user *fx)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_X86_32))
|
||||
return user_insn(fxsave %[fx], [fx] "=m" (*fx), "m" (*fx));
|
||||
else
|
||||
return user_insn(fxsaveq %[fx], [fx] "=m" (*fx), "m" (*fx));
|
||||
|
||||
}
|
||||
|
||||
static inline void fxrstor(struct fxregs_state *fx)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_X86_32))
|
||||
kernel_insn(fxrstor %[fx], "=m" (*fx), [fx] "m" (*fx));
|
||||
else
|
||||
kernel_insn(fxrstorq %[fx], "=m" (*fx), [fx] "m" (*fx));
|
||||
}
|
||||
|
||||
static inline int fxrstor_safe(struct fxregs_state *fx)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_X86_32))
|
||||
return kernel_insn_err(fxrstor %[fx], "=m" (*fx), [fx] "m" (*fx));
|
||||
else
|
||||
return kernel_insn_err(fxrstorq %[fx], "=m" (*fx), [fx] "m" (*fx));
|
||||
}
|
||||
|
||||
static inline int fxrstor_from_user_sigframe(struct fxregs_state __user *fx)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_X86_32))
|
||||
return user_insn(fxrstor %[fx], "=m" (*fx), [fx] "m" (*fx));
|
||||
else
|
||||
return user_insn(fxrstorq %[fx], "=m" (*fx), [fx] "m" (*fx));
|
||||
}
|
||||
|
||||
static inline void frstor(struct fregs_state *fx)
|
||||
{
|
||||
kernel_insn(frstor %[fx], "=m" (*fx), [fx] "m" (*fx));
|
||||
}
|
||||
|
||||
static inline int frstor_safe(struct fregs_state *fx)
|
||||
{
|
||||
return kernel_insn_err(frstor %[fx], "=m" (*fx), [fx] "m" (*fx));
|
||||
}
|
||||
|
||||
static inline int frstor_from_user_sigframe(struct fregs_state __user *fx)
|
||||
{
|
||||
return user_insn(frstor %[fx], "=m" (*fx), [fx] "m" (*fx));
|
||||
}
|
||||
|
||||
static inline void fxsave(struct fxregs_state *fx)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_X86_32))
|
||||
asm volatile( "fxsave %[fx]" : [fx] "=m" (*fx));
|
||||
else
|
||||
asm volatile("fxsaveq %[fx]" : [fx] "=m" (*fx));
|
||||
}
|
||||
|
||||
#endif
|
|
@ -17,6 +17,7 @@
|
|||
#include <asm/trace/fpu.h>
|
||||
|
||||
#include "internal.h"
|
||||
#include "legacy.h"
|
||||
#include "xstate.h"
|
||||
|
||||
static struct _fpx_sw_bytes fx_sw_reserved __ro_after_init;
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <asm/tlbflush.h>
|
||||
|
||||
#include "internal.h"
|
||||
#include "legacy.h"
|
||||
#include "xstate.h"
|
||||
|
||||
#define for_each_extended_xfeature(bit, mask) \
|
||||
|
|
Loading…
Reference in New Issue