aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHeiko Carstens <[email protected]>2024-02-03 11:45:04 +0100
committerHeiko Carstens <[email protected]>2024-02-16 14:30:14 +0100
commit13a8a519cacf04e970907687dcb1e85c03073ba8 (patch)
treea327df1545add441848db10677c063e665a00ced
parent045bad0800cec6098c30148e2873e20db742c750 (diff)
s390/fpu: use lfpc instead of sfpc instruction
The only user of sfpc_safe() needs to read the new fpc register value from memory before it is set with sfpc. Avoid this indirection and use lfpc, which reads the new value from memory. Also add the "fpu_" prefix to have a common name space for fpu related inline assemblies, and provide memory access instrumentation. Reviewed-by: Claudio Imbrenda <[email protected]> Signed-off-by: Heiko Carstens <[email protected]>
-rw-r--r--arch/s390/include/asm/fpu-insn.h22
-rw-r--r--arch/s390/kernel/fpu.c2
2 files changed, 15 insertions, 9 deletions
diff --git a/arch/s390/include/asm/fpu-insn.h b/arch/s390/include/asm/fpu-insn.h
index ccdaacdeaa97..64ba3d9bcd14 100644
--- a/arch/s390/include/asm/fpu-insn.h
+++ b/arch/s390/include/asm/fpu-insn.h
@@ -11,6 +11,7 @@
#ifndef __ASSEMBLY__
+#include <linux/instrumented.h>
#include <asm/asm-extable.h>
asm(".include \"asm/fpu-insn-asm.h\"\n");
@@ -36,26 +37,31 @@ 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__ */
diff --git a/arch/s390/kernel/fpu.c b/arch/s390/kernel/fpu.c
index 5d6a2339db40..98dc9f593a14 100644
--- a/arch/s390/kernel/fpu.c
+++ b/arch/s390/kernel/fpu.c
@@ -174,7 +174,7 @@ void __load_fpu_regs(void)
unsigned long *regs = current->thread.fpu.regs;
struct fpu *state = &current->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"