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

MIPS: Add definitions for extended context

The context introduced by MSA needs to be saved around signals. However,
we can't increase the size of struct sigcontext because that will change
the offset of the signal mask in struct sigframe or struct ucontext.
This patch instead places the new context immediately after the struct
sigframe for traditional signals, or similarly after struct ucontext for
RT signals. The layout of struct sigframe & struct ucontext is identical
from their sigcontext fields onwards, so the offset from the sigcontext
to the extended context will always be the same regardless of the type
of signal.

Userland will be able to search through the extended context by using
the magic values to detect which types of context are present. Any
unrecognised context can be skipped over using the size field of struct
extcontext. Once the magic value END_EXTCONTEXT_MAGIC is seen it is
known that there are no further extended context structures to examine.

This approach is somewhat similar to that taken by ARM to save VFP &
other context at the end of struct ucontext.

Userland can determine whether extended context is present by checking
for the USED_EXTCONTEXT bit in the sc_used_math field of struct
sigcontext. Whilst this could potentially change the historic semantics
of sc_used_math if further extended context which does not imply FP
context were to be introduced in the future, I have been unable to find
any userland code making use of sc_used_math at all. Using one of the
fields described as unused in struct sigcontext was considered, but the
kernel does not already write to those fields so there would be no
guarantee of the field being clear on older kernels. Other alternatives
would be to have userland check the kernel version, or to have a HWCAP
bit indicating presence of extended context. However there is a desire
to have the context & information required to decode it be self
contained such that, for example, debuggers could decode the saved
context easily.

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

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: Peter Zijlstra <peterz@infradead.org>
Cc: Zubair Lutfullah Kakakhel <Zubair.Kakakhel@imgtec.com>
Cc: Alex Smith <alex@alex-smith.me.uk>
Cc: linux-kernel@vger.kernel.org
Cc: Richard Weinberger <richard@nod.at>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Markos Chandras <markos.chandras@imgtec.com>
Cc: Daniel Borkmann <dborkman@redhat.com>
Cc: Maciej W. Rozycki <macro@codesourcery.com>
Patchwork: https://patchwork.linux-mips.org/patch/10795/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>

authored by

Paul Burton and committed by
Ralf Baechle
f1fe2d21 0d071fa3

+81 -1
-1
arch/mips/include/asm/Kbuild
··· 16 16 generic-y += segment.h 17 17 generic-y += serial.h 18 18 generic-y += trace_clock.h 19 - generic-y += ucontext.h 20 19 generic-y += user.h 21 20 generic-y += xor.h
+3
arch/mips/include/uapi/asm/sigcontext.h
··· 21 21 /* FR=1, but with odd singles in bits 63:32 of preceding even double */ 22 22 #define USED_HYBRID_FPRS (1 << 2) 23 23 24 + /* extended context was used, see struct extcontext for details */ 25 + #define USED_EXTCONTEXT (1 << 3) 26 + 24 27 #if _MIPS_SIM == _MIPS_SIM_ABI32 25 28 26 29 /*
+65
arch/mips/include/uapi/asm/ucontext.h
··· 1 + #ifndef __MIPS_UAPI_ASM_UCONTEXT_H 2 + #define __MIPS_UAPI_ASM_UCONTEXT_H 3 + 4 + /** 5 + * struct extcontext - extended context header structure 6 + * @magic: magic value identifying the type of extended context 7 + * @size: the size in bytes of the enclosing structure 8 + * 9 + * Extended context structures provide context which does not fit within struct 10 + * sigcontext. They are placed sequentially in memory at the end of struct 11 + * ucontext and struct sigframe, with each extended context structure beginning 12 + * with a header defined by this struct. The type of context represented is 13 + * indicated by the magic field. Userland may check each extended context 14 + * structure against magic values that it recognises. The size field allows any 15 + * unrecognised context to be skipped, allowing for future expansion. The end 16 + * of the extended context data is indicated by the magic value 17 + * END_EXTCONTEXT_MAGIC. 18 + */ 19 + struct extcontext { 20 + unsigned int magic; 21 + unsigned int size; 22 + }; 23 + 24 + /** 25 + * struct msa_extcontext - MSA extended context structure 26 + * @ext: the extended context header, with magic == MSA_EXTCONTEXT_MAGIC 27 + * @wr: the most significant 64 bits of each MSA vector register 28 + * @csr: the value of the MSA control & status register 29 + * 30 + * If MSA context is live for a task at the time a signal is delivered to it, 31 + * this structure will hold the MSA context of the task as it was prior to the 32 + * signal delivery. 33 + */ 34 + struct msa_extcontext { 35 + struct extcontext ext; 36 + #define MSA_EXTCONTEXT_MAGIC 0x784d5341 /* xMSA */ 37 + 38 + unsigned long long wr[32]; 39 + unsigned int csr; 40 + }; 41 + 42 + #define END_EXTCONTEXT_MAGIC 0x78454e44 /* xEND */ 43 + 44 + /** 45 + * struct ucontext - user context structure 46 + * @uc_flags: 47 + * @uc_link: 48 + * @uc_stack: 49 + * @uc_mcontext: holds basic processor state 50 + * @uc_sigmask: 51 + * @uc_extcontext: holds extended processor state 52 + */ 53 + struct ucontext { 54 + /* Historic fields matching asm-generic */ 55 + unsigned long uc_flags; 56 + struct ucontext *uc_link; 57 + stack_t uc_stack; 58 + struct sigcontext uc_mcontext; 59 + sigset_t uc_sigmask; 60 + 61 + /* Extended context structures may follow ucontext */ 62 + unsigned long long uc_extcontext[0]; 63 + }; 64 + 65 + #endif /* __MIPS_UAPI_ASM_UCONTEXT_H */
+13
arch/mips/kernel/signal.c
··· 47 47 struct sigframe { 48 48 u32 sf_ass[4]; /* argument save space for o32 */ 49 49 u32 sf_pad[2]; /* Was: signal trampoline */ 50 + 51 + /* Matches struct ucontext from its uc_mcontext field onwards */ 50 52 struct sigcontext sf_sc; 51 53 sigset_t sf_mask; 54 + unsigned long long sf_extcontext[0]; 52 55 }; 53 56 54 57 struct rt_sigframe { ··· 689 686 690 687 static int signal_setup(void) 691 688 { 689 + /* 690 + * The offset from sigcontext to extended context should be the same 691 + * regardless of the type of signal, such that userland can always know 692 + * where to look if it wishes to find the extended context structures. 693 + */ 694 + BUILD_BUG_ON((offsetof(struct sigframe, sf_extcontext) - 695 + offsetof(struct sigframe, sf_sc)) != 696 + (offsetof(struct rt_sigframe, rs_uc.uc_extcontext) - 697 + offsetof(struct rt_sigframe, rs_uc.uc_mcontext))); 698 + 692 699 #ifdef CONFIG_SMP 693 700 /* For now just do the cpu_has_fpu check when the functions are invoked */ 694 701 save_fp_context = smp_save_fp_context;