Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

MIPS: Indicate FP mode in sigcontext sc_used_math

The sc_used_math field of struct sigcontext & its variants has
traditionally been used as a boolean value indicating only whether or
not floating point context is saved within the sigcontext. With various
supported FP modes & the ability to switch between them this information
will no longer be enough to decode the meaning of the data stored in the
sc_fpregs fields of struct sigcontext.

To make that possible 3 bits are defined within sc_used_math:

- Bit 0 (USED_FP) represents whether FP was used, essentially
providing the boolean flag which sc_used_math as a whole provided
previously.

- Bit 1 (USED_FR1) provides the value of the Status.FR bit at the time
the FP context was saved.

- Bit 2 (USED_HYBRID_FPRS) indicates whether the FP context was saved
under the hybrid FPR scheme. Essentially, when set the odd singles
are located in bits 63:32 of the preceding even indexed sc_fpregs
element.

Any userland that tests whether the sc_used_math field is zero or
non-zero will continue to function as expected. Having said that, I
could not find any userland which uses the sc_used_math field at all.

[ralf@linux-mips.org: Fixed rejects.]

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: linux-mips@linux-mips.org
Cc: Guenter Roeck <linux@roeck-us.net>
Cc: Matthew Fortune <matthew.fortune@imgtec.com>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: linux-kernel@vger.kernel.org
Cc: Richard Weinberger <richard@nod.at>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Maciej W. Rozycki <macro@codesourcery.com>
Patchwork: https://patchwork.linux-mips.org/patch/10794/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>

authored by

Paul Burton and committed by
Ralf Baechle
0d071fa3 6a24432c

+20 -4
+9
arch/mips/include/uapi/asm/sigcontext.h
··· 12 12 #include <linux/types.h> 13 13 #include <asm/sgidefs.h> 14 14 15 + /* scalar FP context was used */ 16 + #define USED_FP (1 << 0) 17 + 18 + /* the value of Status.FR when context was saved */ 19 + #define USED_FR1 (1 << 1) 20 + 21 + /* FR=1, but with odd singles in bits 63:32 of preceding even double */ 22 + #define USED_HYBRID_FPRS (1 << 2) 23 + 15 24 #if _MIPS_SIM == _MIPS_SIM_ABI32 16 25 17 26 /*
+11 -4
arch/mips/kernel/signal.c
··· 133 133 unsigned int used; 134 134 int err; 135 135 136 - used = !!used_math(); 136 + used = used_math() ? USED_FP : 0; 137 + if (used) { 138 + if (!test_thread_flag(TIF_32BIT_FPREGS)) 139 + used |= USED_FR1; 140 + if (test_thread_flag(TIF_HYBRID_FPREGS)) 141 + used |= USED_HYBRID_FPRS; 142 + } 143 + 137 144 err = __put_user(used, used_math); 138 - if (err || !used) 145 + if (err || !(used & USED_FP)) 139 146 return err; 140 147 141 148 /* ··· 184 177 int err, sig, tmp __maybe_unused; 185 178 186 179 err = __get_user(used, used_math); 187 - conditional_used_math(used); 180 + conditional_used_math(used & USED_FP); 188 181 189 182 /* 190 183 * The signal handler may have used FPU; give it up if the program 191 184 * doesn't want it following sigreturn. 192 185 */ 193 - if (err || !used) { 186 + if (err || !(used & USED_FP)) { 194 187 lose_fpu(0); 195 188 return err; 196 189 }