Commit cbf5f4fb authored by Ingo Molnar's avatar Ingo Molnar

x86/headers: Clean up and better document uapi/asm/sigcontext.h

Clean up sigcontext.h:

 - the explanations were full of typos and were hard to read in general
 - use consistent and readable vertical spacing
 - fix, harmonize and extend comments

No field name has been changed, user-space might be relying on
them.
Acked-by: default avatarMikko Rapeli <mikko.rapeli@iki.fi>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-kernel@vger.kernel.org
Link: http://lkml.kernel.org/r/1441438363-9999-4-git-send-email-mingo@kernel.orgSigned-off-by: default avatarIngo Molnar <mingo@kernel.org>
parent c3f4986f
#ifndef _UAPI_ASM_X86_SIGCONTEXT_H #ifndef _UAPI_ASM_X86_SIGCONTEXT_H
#define _UAPI_ASM_X86_SIGCONTEXT_H #define _UAPI_ASM_X86_SIGCONTEXT_H
/*
* Linux signal context definitions. The sigcontext includes a complex hierarchy of CPU
* and FPU state, available to user-space (on the stack) when a signal handler is
* executed.
*
* As over the years this ABI grew from its very simple roots towards supporting more and
* more CPU state organically, some of the details (which were rather clever hacks back
* in the days) became a bit quirky by today.
*
* The current ABI includes flexible provisions for future extensions, so we won't have
* to grow new quirks for quite some time. Promise!
*/
#include <linux/compiler.h> #include <linux/compiler.h>
#include <linux/types.h> #include <linux/types.h>
...@@ -9,67 +22,82 @@ ...@@ -9,67 +22,82 @@
#define FP_XSTATE_MAGIC2_SIZE sizeof(FP_XSTATE_MAGIC2) #define FP_XSTATE_MAGIC2_SIZE sizeof(FP_XSTATE_MAGIC2)
/* /*
* bytes 464..511 in the current 512byte layout of fxsave/fxrstor frame * Bytes 464..511 in the current 512-byte layout of the FXSAVE/FXRSTOR frame
* are reserved for SW usage. On cpu's supporting xsave/xrstor, these bytes * are reserved for SW usage. On CPUs supporting XSAVE/XRSTOR, these bytes
* are used to extended the fpstate pointer in the sigcontext, which now * are used to extend the fpstate pointer in the sigcontext, which now
* includes the extended state information along with fpstate information. * includes the extended state information along with fpstate information.
* *
* Presence of FP_XSTATE_MAGIC1 at the beginning of this SW reserved * If sw_reserved.magic1 == FP_XSTATE_MAGIC1 then there's a sw_reserved.extended_size
* area and FP_XSTATE_MAGIC2 at the end of memory layout * bytes large extended context area present. (The last 32-bit word of this extended
* (extended_size - FP_XSTATE_MAGIC2_SIZE) indicates the presence of the * area (at the fpstate+extended_size-FP_XSTATE_MAGIC2_SIZE address) is set to
* extended state information in the memory layout pointed by the fpstate * FP_XSTATE_MAGIC2 so that you can sanity check your size calculations.)
* pointer in sigcontext. *
* This extended area typically grows with newer CPUs that have larger and larger
* XSAVE areas.
*/ */
struct _fpx_sw_bytes { struct _fpx_sw_bytes {
__u32 magic1; /* FP_XSTATE_MAGIC1 */ /* If set to FP_XSTATE_MAGIC1 then this is an xstate context. 0 if a legacy frame. */
__u32 extended_size; /* total size of the layout referred by __u32 magic1;
* fpstate pointer in the sigcontext.
/*
* Total size of the fpstate area:
*
* - if magic1 == 0 then it's sizeof(struct _fpstate)
* - if magic1 == FP_XSTATE_MAGIC1 then it's sizeof(struct _xstate) plus extensions (if any)
*/ */
__u64 xfeatures; __u32 extended_size;
/* feature bit mask (including fp/sse/extended
* state) that is present in the memory /*
* layout. * Feature bit mask (including FP/SSE/extended state) that is present
* in the memory layout:
*/ */
__u32 xstate_size; /* actual xsave state size, based on the __u64 xfeatures;
* features saved in the layout.
* 'extended_size' will be greater than /*
* 'xstate_size'. * Actual XSAVE state size, based on the xfeatures saved in the layout.
* 'extended_size' is greater than 'xstate_size':
*/ */
__u32 padding[7]; /* for future use. */ __u32 xstate_size;
/* For future use: */
__u32 padding[7];
}; };
#ifdef __i386__ #ifdef __i386__
/* /*
* As documented in the iBCS2 standard.. * As documented in the iBCS2 standard:
* *
* The first part of "struct _fpstate" is just the normal i387 * The first part of "struct _fpstate" is just the normal i387
* hardware setup, the extra "status" word is used to save the * hardware setup, the extra "status" word is used to save the
* coprocessor status word before entering the handler. * coprocessor status word before entering the handler.
* *
* Pentium III FXSR, SSE support
* Gareth Hughes <gareth@valinux.com>, May 2000
*
* The FPU state data structure has had to grow to accommodate the * The FPU state data structure has had to grow to accommodate the
* extended FPU state required by the Streaming SIMD Extensions. * extended FPU state required by the Streaming SIMD Extensions.
* There is no documented standard to accomplish this at the moment. * There is no documented standard to accomplish this at the moment.
*/ */
/* 10-byte legacy floating point register: */
struct _fpreg { struct _fpreg {
unsigned short significand[4]; unsigned short significand[4];
unsigned short exponent; unsigned short exponent;
}; };
/* 16-byte floating point register: */
struct _fpxreg { struct _fpxreg {
unsigned short significand[4]; unsigned short significand[4];
unsigned short exponent; unsigned short exponent;
unsigned short padding[3]; unsigned short padding[3];
}; };
/* 16-byte XMM register: */
struct _xmmreg { struct _xmmreg {
unsigned long element[4]; unsigned long element[4];
}; };
#define X86_FXSR_MAGIC 0x0000
struct _fpstate { struct _fpstate {
/* Regular FPU environment */ /* Legacy FPU environment: */
unsigned long cw; unsigned long cw;
unsigned long sw; unsigned long sw;
unsigned long tag; unsigned long tag;
...@@ -79,26 +107,24 @@ struct _fpstate { ...@@ -79,26 +107,24 @@ struct _fpstate {
unsigned long datasel; unsigned long datasel;
struct _fpreg _st[8]; struct _fpreg _st[8];
unsigned short status; unsigned short status;
unsigned short magic; /* 0xffff = regular FPU data only */ unsigned short magic; /* 0xffff: regular FPU data only */
/* 0x0000: FXSR FPU data */
/* FXSR FPU environment */ /* FXSR FPU environment */
unsigned long _fxsr_env[6]; /* FXSR FPU env is ignored */ unsigned long _fxsr_env[6]; /* FXSR FPU env is ignored */
unsigned long mxcsr; unsigned long mxcsr;
unsigned long reserved; unsigned long reserved;
struct _fpxreg _fxsr_st[8]; /* FXSR FPU reg data is ignored */ struct _fpxreg _fxsr_st[8]; /* FXSR FPU reg data is ignored */
struct _xmmreg _xmm[8]; struct _xmmreg _xmm[8]; /* First 8 XMM registers */
unsigned long padding1[44]; unsigned long padding1[44]; /* Second 8 XMM registers plus padding */
union { union {
unsigned long padding2[12]; unsigned long padding2[12];
struct _fpx_sw_bytes sw_reserved; /* represents the extended struct _fpx_sw_bytes sw_reserved; /* Potential extended state is encoded here */
* state info */
}; };
}; };
#define X86_FXSR_MAGIC 0x0000 # ifndef __KERNEL__
#ifndef __KERNEL__
/* /*
* User-space might still rely on the old definition: * User-space might still rely on the old definition:
*/ */
...@@ -126,34 +152,41 @@ struct sigcontext { ...@@ -126,34 +152,41 @@ struct sigcontext {
unsigned long oldmask; unsigned long oldmask;
unsigned long cr2; unsigned long cr2;
}; };
#endif /* !__KERNEL__ */ # endif /* !__KERNEL__ */
#else /* __i386__ */ #else /* __x86_64__: */
/* FXSAVE frame */ /*
/* Note: reserved1/2 may someday contain valuable data. Always save/restore * The FXSAVE frame.
them when you change signal frames. */ *
* Note1: If sw_reserved.magic1 == FP_XSTATE_MAGIC1 then the structure is
* larger: 'struct _xstate'. Note that 'struct _xstate' embedds
* 'struct _fpstate' so that you can always assume the _fpstate portion
* exists so that you can check the magic value.
*
* Note2: Reserved fields may someday contain valuable data. Always save/restore
* them when you change signal frames.
*/
struct _fpstate { struct _fpstate {
__u16 cwd; __u16 cwd;
__u16 swd; __u16 swd;
__u16 twd; /* Note this is not the same as the /* Note this is not the same as the 32-bit/x87/FSAVE twd: */
32bit/x87/FSAVE twd */ __u16 twd;
__u16 fop; __u16 fop;
__u64 rip; __u64 rip;
__u64 rdp; __u64 rdp;
__u32 mxcsr; __u32 mxcsr;
__u32 mxcsr_mask; __u32 mxcsr_mask;
__u32 st_space[32]; /* 8*16 bytes for each FP-reg */ __u32 st_space[32]; /* 8x FP registers, 16 bytes each */
__u32 xmm_space[64]; /* 16*16 bytes for each XMM-reg */ __u32 xmm_space[64]; /* 16x XMM registers, 16 bytes each */
__u32 reserved2[12]; __u32 reserved2[12];
union { union {
__u32 reserved3[12]; __u32 reserved3[12];
struct _fpx_sw_bytes sw_reserved; /* represents the extended struct _fpx_sw_bytes sw_reserved; /* Potential extended state is encoded here */
* state information */
}; };
}; };
#ifndef __KERNEL__ # ifndef __KERNEL__
/* /*
* User-space might still rely on the old definition: * User-space might still rely on the old definition:
*/ */
...@@ -184,15 +217,15 @@ struct sigcontext { ...@@ -184,15 +217,15 @@ struct sigcontext {
__u64 trapno; __u64 trapno;
__u64 oldmask; __u64 oldmask;
__u64 cr2; __u64 cr2;
struct _fpstate __user *fpstate; /* zero when no FPU context */ struct _fpstate __user *fpstate; /* Zero when no FPU context */
#ifdef __ILP32__ # ifdef __ILP32__
__u32 __fpstate_pad; __u32 __fpstate_pad;
#endif # endif
__u64 reserved1[8]; __u64 reserved1[8];
}; };
#endif /* !__KERNEL__ */ # endif /* !__KERNEL__ */
#endif /* !__i386__ */ #endif /* __x86_64__ */
struct _header { struct _header {
__u64 xfeatures; __u64 xfeatures;
...@@ -201,21 +234,22 @@ struct _header { ...@@ -201,21 +234,22 @@ struct _header {
}; };
struct _ymmh_state { struct _ymmh_state {
/* 16 * 16 bytes for each YMMH-reg */ /* 16x YMM registers, 16 bytes each: */
__u32 ymmh_space[64]; __u32 ymmh_space[64];
}; };
/* /*
* Extended state pointed by the fpstate pointer in the sigcontext. * Extended state pointed to by sigcontext::fpstate.
* In addition to the fpstate, information encoded in the xstate_hdr *
* indicates the presence of other extended state information * In addition to the fpstate, information encoded in _xstate::xstate_hdr
* supported by the processor and OS. * indicates the presence of other extended state information supported
* by the CPU and kernel:
*/ */
struct _xstate { struct _xstate {
struct _fpstate fpstate; struct _fpstate fpstate;
struct _header xstate_hdr; struct _header xstate_hdr;
struct _ymmh_state ymmh; struct _ymmh_state ymmh;
/* new processor state extensions go here */ /* New processor state extensions go here: */
}; };
#endif /* _UAPI_ASM_X86_SIGCONTEXT_H */ #endif /* _UAPI_ASM_X86_SIGCONTEXT_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment