#ifndef __ASSEMBLY__
+#include <linux/instrumented.h>
#include <asm/asm-extable.h>
asm(".include \"asm/fpu-insn-asm.h\"\n");
*/
/**
- * sfpc_safe - Set floating point control register safely.
+ * fpu_lfpc_safe - Load floating point control register safely.
* @fpc: new value for floating point control register
*
- * Set floating point control register. This may lead to an exception,
+ * Load floating point control register. This may lead to an exception,
* since a saved value may have been modified by user space (ptrace,
* signal return, kvm registers) to an invalid value. In such a case
* set the floating point control register to zero.
*/
-static inline void sfpc_safe(u32 fpc)
+static inline void fpu_lfpc_safe(unsigned int *fpc)
{
+ u32 tmp;
+
+ instrument_read(fpc, sizeof(*fpc));
asm volatile("\n"
- "0: sfpc %[fpc]\n"
+ "0: lfpc %[fpc]\n"
"1: nopr %%r7\n"
".pushsection .fixup, \"ax\"\n"
- "2: lghi %[fpc],0\n"
- " jg 0b\n"
+ "2: lghi %[tmp],0\n"
+ " sfpc %[tmp]\n"
+ " jg 1b\n"
".popsection\n"
EX_TABLE(1b, 2b)
- : [fpc] "+d" (fpc)
- : : "memory");
+ : [tmp] "=d" (tmp)
+ : [fpc] "Q" (*fpc)
+ : "memory");
}
#endif /* __ASSEMBLY__ */
unsigned long *regs = current->thread.fpu.regs;
struct fpu *state = ¤t->thread.fpu;
- sfpc_safe(state->fpc);
+ fpu_lfpc_safe(&state->fpc);
if (likely(cpu_has_vx())) {
asm volatile("lgr 1,%0\n"
"VLM 0,15,0,1\n"