]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
s390/fpu: Add fpc exception handler / remove fixup section again
authorHeiko Carstens <hca@linux.ibm.com>
Fri, 10 Jan 2025 10:52:17 +0000 (11:52 +0100)
committerAlexander Gordeev <agordeev@linux.ibm.com>
Sun, 26 Jan 2025 16:24:04 +0000 (17:24 +0100)
The fixup section was added again by mistake when test_fp_ctl() was
removed. The reason for the removal of the fixup section is described in
commit 484a8ed8b7d1 ("s390/extable: add dedicated uaccess handler").
Remove it again for the same reason.

Add an exception handler which handles exceptions when the floating point
control register is attempted to be set to invalid values. The exception
handler sets the floating point control register to zero and continues
execution at the specified address.

The new sfpc inline assembly is open-coded to make back porting a bit
easier.

Fixes: 702644249d3e ("s390/fpu: get rid of test_fp_ctl()")
Cc: stable@vger.kernel.org
Reviewed-by: Alexander Gordeev <agordeev@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
arch/s390/include/asm/asm-extable.h
arch/s390/include/asm/fpu-insn.h
arch/s390/kernel/vmlinux.lds.S
arch/s390/mm/extable.c

index 4a6b0a8b6412f1f933c34a4003d5f32e9636618f..00a67464c44534ca931a46f9253e612bfb76151e 100644 (file)
@@ -14,6 +14,7 @@
 #define EX_TYPE_UA_LOAD_REG    5
 #define EX_TYPE_UA_LOAD_REGPAIR        6
 #define EX_TYPE_ZEROPAD                7
+#define EX_TYPE_FPC            8
 
 #define EX_DATA_REG_ERR_SHIFT  0
 #define EX_DATA_REG_ERR                GENMASK(3, 0)
@@ -84,4 +85,7 @@
 #define EX_TABLE_ZEROPAD(_fault, _target, _regdata, _regaddr)          \
        __EX_TABLE(__ex_table, _fault, _target, EX_TYPE_ZEROPAD, _regdata, _regaddr, 0)
 
+#define EX_TABLE_FPC(_fault, _target)                                  \
+       __EX_TABLE(__ex_table, _fault, _target, EX_TYPE_FPC, __stringify(%%r0), __stringify(%%r0), 0)
+
 #endif /* __ASM_EXTABLE_H */
index de510c9f6efa94994fb9b97a7da08ef2720d7bb3..0f1b59eb4c5ae5fe64b6daedbf72ae18054c4270 100644 (file)
@@ -100,19 +100,12 @@ static __always_inline void fpu_lfpc(unsigned int *fpc)
  */
 static inline void fpu_lfpc_safe(unsigned int *fpc)
 {
-       u32 tmp;
-
        instrument_read(fpc, sizeof(*fpc));
        asm_inline volatile(
-               "0:     lfpc    %[fpc]\n"
-               "1:     nopr    %%r7\n"
-               ".pushsection .fixup, \"ax\"\n"
-               "2:     lghi    %[tmp],0\n"
-               "       sfpc    %[tmp]\n"
-               "       jg      1b\n"
-               ".popsection\n"
-               EX_TABLE(1b, 2b)
-               : [tmp] "=d" (tmp)
+               "       lfpc    %[fpc]\n"
+               "0:     nopr    %%r7\n"
+               EX_TABLE_FPC(0b, 0b)
+               :
                : [fpc] "Q" (*fpc)
                : "memory");
 }
index 377b9aaf8c9248d8c2d806fd68b8ff068fdd4c2e..ff1ddba96352a1eaf77096dc58d2f65f465e650c 100644 (file)
@@ -52,7 +52,6 @@ SECTIONS
                SOFTIRQENTRY_TEXT
                FTRACE_HOTPATCH_TRAMPOLINES_TEXT
                *(.text.*_indirect_*)
-               *(.fixup)
                *(.gnu.warning)
                . = ALIGN(PAGE_SIZE);
                _etext = .;             /* End of text section */
index 0a0738a473af05e3149ebf2500ea0a79a3da5d73..812ec5be1291697262aea07d4262175e4346ed29 100644 (file)
@@ -77,6 +77,13 @@ static bool ex_handler_zeropad(const struct exception_table_entry *ex, struct pt
        return true;
 }
 
+static bool ex_handler_fpc(const struct exception_table_entry *ex, struct pt_regs *regs)
+{
+       asm volatile("sfpc      %[val]\n" : : [val] "d" (0));
+       regs->psw.addr = extable_fixup(ex);
+       return true;
+}
+
 bool fixup_exception(struct pt_regs *regs)
 {
        const struct exception_table_entry *ex;
@@ -99,6 +106,8 @@ bool fixup_exception(struct pt_regs *regs)
                return ex_handler_ua_load_reg(ex, true, regs);
        case EX_TYPE_ZEROPAD:
                return ex_handler_zeropad(ex, regs);
+       case EX_TYPE_FPC:
+               return ex_handler_fpc(ex, regs);
        }
        panic("invalid exception table entry");
 }