x86/fpu/xstate: Fix XSAVES issues - Part 2
cover x86/fpu/xstate: Fix XSAVES issues - Part 2
** Based on tip/master **
This is Part 2 of previous 13 XSAVES patches. Break it down to smaller series. There are no code changes; only minor fixes in the titles.
Yu-cheng Yu (5):
x86/fpu/xstate: Align xstate components according to CPUID x86/fpu/xstate: Fix supervisor xstate component offset x86/fpu/xstate: Fix PTRACE frames for XSAVES x86/fpu/xstate: Fix XSTATE component offset print out x86/fpu/xstate: Fix xstate_offsets, xstate_sizes for non-extended
xstates
arch/x86/include/asm/fpu/types.h | 1 + arch/x86/include/asm/fpu/xstate.h | 8 +- arch/x86/kernel/fpu/regset.c | 55 +++++-- arch/x86/kernel/fpu/xstate.c | 312 +++++++++++++++++++++++++++++++------- 4 files changed, 308 insertions(+), 68 deletions(-)
Signature · 1 line
1.9.1
PATCH 1/5 x86/fpu/xstate: Align xstate components according to CPUID
CPUID function 0x0d, sub function (i, i > 1) returns in ecx[1] the alignment requirement of component i when the compacted format is used.
If ecx[1] is 0, component i is located immediately following the preceding component. If ecx[1] is 1, component i is located on the next 64-byte boundary following the preceding component.
--- arch/x86/kernel/fpu/xstate.c | 60 +++++++++++++++++++++++--------------------- 1 file changed, 32 insertions(+), 28 deletions(-)
arch/x86/kernel/fpu/xstate.c +32 -28
@@ -270,6 +270,33 @@ static void __init print_xstate_features(void) }/* +* This check is important because it is easy to get XSTATE_* +* confused with XSTATE_BIT_*. +*/ +#define CHECK_XFEATURE (nr) do { \ + WARN_ON(nr < FIRST_EXTENDED_XFEATURE); \ + WARN_ON(nr >= XFEATURE_MAX); \ +} while (0) + +/* +* We could cache this like xstate_size[], but we only use +* it here, so it would be a waste of space. +*/ +static int xfeature_is_aligned (int xfeature_nr) +{ +u32 eax, ebx, ecx, edx; + +CHECK_XFEATURE (xfeature_nr); +cpuid_count (XSTATE_CPUID , xfeature_nr, &eax, &ebx, &ecx, &edx); +/* +* The value returned by ECX[1] indicates the alignment +* of state component i when the compacted format +* of the extended region of an XSAVE area is used +*/ +return !!(ecx &2 ); +} + +/* * This function sets up offsets and sizes of all extended states in * xsave area. This supports both standard format and compacted format * of the xsave aread.
@@ -306,10 +333,14 @@ static void __init setup_xstate_comp(void)else xstate_comp_sizes[i] =0 ; -if (i >FIRST_EXTENDED_XFEATURE ) +if (i >FIRST_EXTENDED_XFEATURE ) { xstate_comp_offsets[i] = xstate_comp_offsets[i-1 ] + xstate_comp_sizes[i-1 ]; +if (xfeature_is_aligned (i)) + xstate_comp_offsets[i] = +ALIGN (xstate_comp_offsets[i],64 ); + } } }
@@ -366,33 +397,6 @@ static int xfeature_is_user(int xfeature_nr)} */ -/* -* This check is important because it is easy to get XSTATE_* -* confused with XSTATE_BIT_*. -*/ -#define CHECK_XFEATURE (nr) do { \ - WARN_ON(nr < FIRST_EXTENDED_XFEATURE); \ - WARN_ON(nr >= XFEATURE_MAX); \ -} while (0) - -/* -* We could cache this like xstate_size[], but we only use -* it here, so it would be a waste of space. -*/ -static int xfeature_is_aligned (int xfeature_nr) -{ -u32 eax, ebx, ecx, edx; - -CHECK_XFEATURE (xfeature_nr); -cpuid_count (XSTATE_CPUID , xfeature_nr, &eax, &ebx, &ecx, &edx); -/* -* The value returned by ECX[1] indicates the alignment -* of state component i when the compacted format -* of the extended region of an XSAVE area is used -*/ -return !!(ecx &2 ); -} -static int xfeature_uncompacted_offset (int xfeature_nr) {u32 eax, ebx, ecx, edx;
Signature · 1 line
1.9.1
tip-bot for Yu-cheng Yu
merge bot[tip:x86/fpu] x86/fpu/xstate: Align xstate components according to CPUID
x86/fpu/xstate: Align xstate components according to CPUID
Commit-ID: 03482e08a87d24e5c8c23e6981c482e832cf3bdc Gitweb: http://git.kernel.org/tip/03482e08a87d24e5c8c23e6981c482e832cf3bdc Author: Yu-cheng Yu <[email protected]> AuthorDate: Fri, 17 Jun 2016 13:07:15 -0700 Committer: Ingo Molnar <[email protected]> CommitDate: Sun, 10 Jul 2016 17:12:10 +0200
x86/fpu/xstate: Align xstate components according to CPUID
CPUID function 0x0d, sub function (i, i > 1) returns in ecx[1] the alignment requirement of component 'i' when the compacted format is used.
If ecx[1] is 0, component 'i' is located immediately following the preceding component. If ecx[1] is 1, component 'i' is located on the next 64-byte boundary following the preceding component.
--- arch/x86/kernel/fpu/xstate.c | 60 +++++++++++++++++++++++--------------------- 1 file changed, 32 insertions(+), 28 deletions(-)
arch/x86/kernel/fpu/xstate.c +32 -28
@@ -270,6 +270,33 @@ static void __init print_xstate_features(void) }/* +* This check is important because it is easy to get XSTATE_* +* confused with XSTATE_BIT_*. +*/ +#define CHECK_XFEATURE (nr) do { \ + WARN_ON(nr < FIRST_EXTENDED_XFEATURE); \ + WARN_ON(nr >= XFEATURE_MAX); \ +} while (0) + +/* +* We could cache this like xstate_size[], but we only use +* it here, so it would be a waste of space. +*/ +static int xfeature_is_aligned (int xfeature_nr) +{ +u32 eax, ebx, ecx, edx; + +CHECK_XFEATURE (xfeature_nr); +cpuid_count (XSTATE_CPUID , xfeature_nr, &eax, &ebx, &ecx, &edx); +/* +* The value returned by ECX[1] indicates the alignment +* of state component 'i' when the compacted format +* of the extended region of an XSAVE area is used: +*/ +return !!(ecx &2 ); +} + +/* * This function sets up offsets and sizes of all extended states in * xsave area. This supports both standard format and compacted format * of the xsave aread.
@@ -306,10 +333,14 @@ static void __init setup_xstate_comp(void)else xstate_comp_sizes[i] =0 ; -if (i >FIRST_EXTENDED_XFEATURE ) +if (i >FIRST_EXTENDED_XFEATURE ) { xstate_comp_offsets[i] = xstate_comp_offsets[i-1 ] + xstate_comp_sizes[i-1 ]; +if (xfeature_is_aligned (i)) + xstate_comp_offsets[i] = +ALIGN (xstate_comp_offsets[i],64 ); + } } }
@@ -366,33 +397,6 @@ static int xfeature_is_user(int xfeature_nr)} */ -/* -* This check is important because it is easy to get XSTATE_* -* confused with XSTATE_BIT_*. -*/ -#define CHECK_XFEATURE (nr) do { \ - WARN_ON(nr < FIRST_EXTENDED_XFEATURE); \ - WARN_ON(nr >= XFEATURE_MAX); \ -} while (0) - -/* -* We could cache this like xstate_size[], but we only use -* it here, so it would be a waste of space. -*/ -static int xfeature_is_aligned (int xfeature_nr) -{ -u32 eax, ebx, ecx, edx; - -CHECK_XFEATURE (xfeature_nr); -cpuid_count (XSTATE_CPUID , xfeature_nr, &eax, &ebx, &ecx, &edx); -/* -* The value returned by ECX[1] indicates the alignment -* of state component i when the compacted format -* of the extended region of an XSAVE area is used -*/ -return !!(ecx &2 ); -} -static int xfeature_uncompacted_offset (int xfeature_nr) {u32 eax, ebx, ecx, edx;
PATCH 2/5 x86/fpu/xstate: Fix supervisor xstate component offset
In reply to Yu-cheng YuCPUID function 0x0d, sub function (i, i > 1) returns in ebx the offset of xstate component i. Zero is returned for a supervisor state. A supervisor state can only be saved by XSAVES and XSAVES uses a compacted format. There is no fixed offset for a supervisor state. This patch checks and makes sure a supervisor state offset is not recorded or mis-used. This has no effect in practice as we currently use no supervisor states, but it would be good to fix.
--- arch/x86/include/asm/fpu/types.h | 1 + arch/x86/include/asm/fpu/xstate.h | 3 ++ arch/x86/kernel/fpu/xstate.c | 62 ++++++++++++++++++++++++--------------- 3 files changed, 43 insertions(+), 23 deletions(-)
arch/x86/include/asm/fpu/types.h +1 -0
@@ -122,6 +122,7 @@ enum xfeature {#define XFEATURE_MASK_OPMASK (1 << XFEATURE_OPMASK)#define XFEATURE_MASK_ZMM_Hi256 (1 << XFEATURE_ZMM_Hi256)#define XFEATURE_MASK_Hi16_ZMM (1 << XFEATURE_Hi16_ZMM) +#define XFEATURE_MASK_PT (1 << XFEATURE_PT_UNIMPLEMENTED_SO_FAR)#define XFEATURE_MASK_PKRU (1 << XFEATURE_PKRU)#define XFEATURE_MASK_FPSSE (XFEATURE_MASK_FP | XFEATURE_MASK_SSE)
arch/x86/include/asm/fpu/xstate.h +3 -0
@@ -18,6 +18,9 @@#define XSAVE_YMM_SIZE 256#define XSAVE_YMM_OFFSET (XSAVE_HDR_SIZE + XSAVE_HDR_OFFSET) +/* Supervisor features */ +#define XFEATURE_MASK_SUPERVISOR (XFEATURE_MASK_PT) +/* Supported features which support lazy state saving */ #define XFEATURE_MASK_LAZY (XFEATURE_MASK_FP | \ XFEATURE_MASK_SSE | \
arch/x86/kernel/fpu/xstate.c +39 -23
84 lines not on this page · raw message
Signature · 1 line
1.9.1
tip-bot for Yu-cheng Yu
merge bot[tip:x86/fpu] x86/fpu/xstate: Fix supervisor xstate component offset
x86/fpu/xstate: Fix supervisor xstate component offset
Commit-ID: 1499ce2dd45afddea2e84f9f920890cf88384c4e Gitweb: http://git.kernel.org/tip/1499ce2dd45afddea2e84f9f920890cf88384c4e Author: Yu-cheng Yu <[email protected]> AuthorDate: Fri, 17 Jun 2016 13:07:16 -0700 Committer: Ingo Molnar <[email protected]> CommitDate: Sun, 10 Jul 2016 17:12:10 +0200
x86/fpu/xstate: Fix supervisor xstate component offset
CPUID function 0x0d, sub function (i, i > 1) returns in ebx the offset of xstate component i. Zero is returned for a supervisor state. A supervisor state can only be saved by XSAVES and XSAVES uses a compacted format. There is no fixed offset for a supervisor state. This patch checks and makes sure a supervisor state offset is not recorded or mis-used. This has no effect in practice as we currently use no supervisor states, but it would be good to fix.
--- arch/x86/include/asm/fpu/types.h | 1 + arch/x86/include/asm/fpu/xstate.h | 3 ++ arch/x86/kernel/fpu/xstate.c | 62 ++++++++++++++++++++++++--------------- 3 files changed, 43 insertions(+), 23 deletions(-)
arch/x86/include/asm/fpu/types.h +1 -0
@@ -122,6 +122,7 @@ enum xfeature {#define XFEATURE_MASK_OPMASK (1 << XFEATURE_OPMASK)#define XFEATURE_MASK_ZMM_Hi256 (1 << XFEATURE_ZMM_Hi256)#define XFEATURE_MASK_Hi16_ZMM (1 << XFEATURE_Hi16_ZMM) +#define XFEATURE_MASK_PT (1 << XFEATURE_PT_UNIMPLEMENTED_SO_FAR)#define XFEATURE_MASK_PKRU (1 << XFEATURE_PKRU)#define XFEATURE_MASK_FPSSE (XFEATURE_MASK_FP | XFEATURE_MASK_SSE)
arch/x86/include/asm/fpu/xstate.h +3 -0
@@ -18,6 +18,9 @@#define XSAVE_YMM_SIZE 256#define XSAVE_YMM_OFFSET (XSAVE_HDR_SIZE + XSAVE_HDR_OFFSET) +/* Supervisor features */ +#define XFEATURE_MASK_SUPERVISOR (XFEATURE_MASK_PT) +/* Supported features which support lazy state saving */ #define XFEATURE_MASK_LAZY (XFEATURE_MASK_FP | \ XFEATURE_MASK_SSE | \
arch/x86/kernel/fpu/xstate.c +39 -23
84 lines not on this page · raw message
PATCH 3/5 x86/fpu/xstate: Fix PTRACE frames for XSAVES
In reply to Yu-cheng YuXSAVES uses compacted format and is a kernel instruction. The kernel should use standard-format, non-supervisor state data for PTRACE.
--- arch/x86/include/asm/fpu/xstate.h | 5 +- arch/x86/kernel/fpu/regset.c | 55 +++++++++---- arch/x86/kernel/fpu/xstate.c | 167 +++++++++++++++++++++++++++++++++++++- 3 files changed, 210 insertions(+), 17 deletions(-)
arch/x86/include/asm/fpu/xstate.h +4 -1
@@ -51,5 +51,8 @@ void fpu__xstate_clear_all_cpu_caps(void);void *get_xsave_addr (struct xregs_state *xsave,int xstate);const void *get_xsave_field_ptr (int xstate_field);int using_compacted_format (void ); - +int copyout_from_xsaves (unsigned int pos,unsigned int count,void *kbuf, +void __user *ubuf,struct xregs_state *xsave); +int copyin_to_xsaves (const void *kbuf,const void __user *ubuf, +struct xregs_state *xsave);#endif
arch/x86/kernel/fpu/regset.c +40 -15
78 lines not on this page · raw message
arch/x86/kernel/fpu/xstate.c +166 -1
182 lines not on this page · raw message
Signature · 1 line
1.9.1
tip-bot for Yu-cheng Yu
merge bot[tip:x86/fpu] x86/fpu/xstate: Fix PTRACE frames for XSAVES
x86/fpu/xstate: Fix PTRACE frames for XSAVES
Commit-ID: 91c3dba7dbc199191272f4a9863f86ea3bfd679f Gitweb: http://git.kernel.org/tip/91c3dba7dbc199191272f4a9863f86ea3bfd679f Author: Yu-cheng Yu <[email protected]> AuthorDate: Fri, 17 Jun 2016 13:07:17 -0700 Committer: Ingo Molnar <[email protected]> CommitDate: Sun, 10 Jul 2016 17:12:10 +0200
x86/fpu/xstate: Fix PTRACE frames for XSAVES
XSAVES uses compacted format and is a kernel instruction. The kernel should use standard-format, non-supervisor state data for PTRACE.
--- arch/x86/include/asm/fpu/xstate.h | 5 +- arch/x86/kernel/fpu/regset.c | 52 +++++++---- arch/x86/kernel/fpu/xstate.c | 183 ++++++++++++++++++++++++++++++++++++-- 3 files changed, 216 insertions(+), 24 deletions(-)
arch/x86/include/asm/fpu/xstate.h +4 -1
@@ -51,5 +51,8 @@ void fpu__xstate_clear_all_cpu_caps(void);void *get_xsave_addr (struct xregs_state *xsave,int xstate);const void *get_xsave_field_ptr (int xstate_field);int using_compacted_format (void ); - +int copyout_from_xsaves (unsigned int pos,unsigned int count,void *kbuf, +void __user *ubuf,struct xregs_state *xsave); +int copyin_to_xsaves (const void *kbuf,const void __user *ubuf, +struct xregs_state *xsave);#endif
arch/x86/kernel/fpu/regset.c +37 -15
75 lines not on this page · raw message
arch/x86/kernel/fpu/xstate.c +175 -8
221 lines not on this page · raw message
PATCH 4/5 x86/fpu/xstate: Fix XSTATE component offset print out
In reply to Yu-cheng YuComponent offset print out was incorrect for XSAVES. Correct it and move to a separate function.
--- arch/x86/kernel/fpu/xstate.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-)
arch/x86/kernel/fpu/xstate.c +16 -2
@@ -269,8 +269,6 @@ static void __init setup_xstate_features(void)WARN_ONCE (last_good_offset > xstate_offsets[i],"x86/fpu: misordered xstate at %d\n" , last_good_offset); last_good_offset = xstate_offsets[i]; - -printk (KERN_INFO "x86/fpu: xstate_offset[%d]: %4d, xstate_sizes[%d]: %4d\n" , i, ebx, i, eax); } }
@@ -374,6 +372,21 @@ static void __init setup_xstate_comp(void) }/* +* Print out xstate component offsets and sizes +*/ +static void __init print_xstate_offset_size (void ) +{ +int i; + +for (i =FIRST_EXTENDED_XFEATURE ; i <XFEATURE_MAX ; i++) { +if (!xfeature_enabled (i)) +continue ; +pr_info ("x86/fpu: xstate_offset[%d]: %4d, xstate_sizes[%d]: %4d\n" , + i, xstate_comp_offsets[i], i, xstate_sizes[i]); + } +} + +/* * setup the xstate image representing the init state */ static void __init setup_init_fpu_buf (void )
@@ -708,6 +721,7 @@ void __init fpu__init_system_xstate(void)fpu__init_prepare_fx_sw_frame ();setup_init_fpu_buf ();setup_xstate_comp (); +print_xstate_offset_size (); pr_info("x86/fpu: Enabled xstate features 0x%llx, context size is %d bytes, using '%s' format.\n", xfeatures_mask,
Signature · 1 line
1.9.1
tip-bot for Yu-cheng Yu
merge bot[tip:x86/fpu] x86/fpu/xstate: Fix XSTATE component offset print out
x86/fpu/xstate: Fix XSTATE component offset print out
Commit-ID: 996952e0148026ac0e512db5cad26e14f4267e8b Gitweb: http://git.kernel.org/tip/996952e0148026ac0e512db5cad26e14f4267e8b Author: Yu-cheng Yu <[email protected]> AuthorDate: Fri, 17 Jun 2016 13:07:18 -0700 Committer: Ingo Molnar <[email protected]> CommitDate: Sun, 10 Jul 2016 17:12:10 +0200
x86/fpu/xstate: Fix XSTATE component offset print out
Component offset print out was incorrect for XSAVES. Correct it and move to a separate function.
--- arch/x86/kernel/fpu/xstate.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-)
arch/x86/kernel/fpu/xstate.c +16 -2
@@ -269,8 +269,6 @@ static void __init setup_xstate_features(void)WARN_ONCE (last_good_offset > xstate_offsets[i],"x86/fpu: misordered xstate at %d\n" , last_good_offset); last_good_offset = xstate_offsets[i]; - -printk (KERN_INFO "x86/fpu: xstate_offset[%d]: %4d, xstate_sizes[%d]: %4d\n" , i, ebx, i, eax); } }
@@ -374,6 +372,21 @@ static void __init setup_xstate_comp(void) }/* +* Print out xstate component offsets and sizes +*/ +static void __init print_xstate_offset_size (void ) +{ +int i; + +for (i =FIRST_EXTENDED_XFEATURE ; i <XFEATURE_MAX ; i++) { +if (!xfeature_enabled (i)) +continue ; +pr_info ("x86/fpu: xstate_offset[%d]: %4d, xstate_sizes[%d]: %4d\n" , + i, xstate_comp_offsets[i], i, xstate_sizes[i]); + } +} + +/* * setup the xstate image representing the init state */ static void __init setup_init_fpu_buf (void )
@@ -707,6 +720,7 @@ void __init fpu__init_system_xstate(void)fpu__init_prepare_fx_sw_frame ();setup_init_fpu_buf ();setup_xstate_comp (); +print_xstate_offset_size (); pr_info("x86/fpu: Enabled xstate features 0x%llx, context size is %d bytes, using '%s' format.\n", xfeatures_mask,
PATCH 5/5 x86/fpu/xstate: Fix xstate_offsets, xstate_sizes for non-extended xstates
In reply to Yu-cheng YuThe arrays xstate_offsets[] and xstate_sizes[] record XSAVE standard- format offsets and sizes. Values for non-extended state components fpu and xmm's were not initialized or used. Ptrace format conversion needs them. Fix it.
--- arch/x86/kernel/fpu/xstate.c | 9 +++++++++ 1 file changed, 9 insertions(+)
arch/x86/kernel/fpu/xstate.c +9 -0
@@ -246,6 +246,15 @@ static void __init setup_xstate_features(void)/* start at the beginnning of the "extended state" */ unsigned int last_good_offset = offsetof(struct xregs_state , extended_state_area); +/* +* The FP xstates and SSE xstates are legacy states. They are always +* in the fixed offsets in the xsave area in either compacted form +* or standard form. +*/ + xstate_offsets[0 ] =0 ; + xstate_sizes[0 ] = offsetof(struct fxregs_state , xmm_space); + xstate_offsets[1 ] = xstate_sizes[0 ]; + xstate_sizes[1] = FIELD_SIZEOF(struct fxregs_state, xmm_space);for (i =FIRST_EXTENDED_XFEATURE ; i <XFEATURE_MAX ; i++) {if (!xfeature_enabled (i))
Signature · 1 line
1.9.1
tip-bot for Yu-cheng Yu
merge bot[tip:x86/fpu] x86/fpu/xstate: Fix xstate_offsets, xstate_sizes for non-extended xstates
x86/fpu/xstate: Fix xstate_offsets, xstate_sizes for non-extended xstates
Commit-ID: ac73b27aea4eacdd7555f664d5fc6e1d4d1c8bf6 Gitweb: http://git.kernel.org/tip/ac73b27aea4eacdd7555f664d5fc6e1d4d1c8bf6 Author: Yu-cheng Yu <[email protected]> AuthorDate: Fri, 17 Jun 2016 13:07:19 -0700 Committer: Ingo Molnar <[email protected]> CommitDate: Sun, 10 Jul 2016 17:12:11 +0200
x86/fpu/xstate: Fix xstate_offsets, xstate_sizes for non-extended xstates
The arrays xstate_offsets[] and xstate_sizes[] record XSAVE standard- format offsets and sizes. Values for non-extended state components fpu and xmm's were not initialized or used. Ptrace format conversion needs them. Fix it.
--- arch/x86/kernel/fpu/xstate.c | 9 +++++++++ 1 file changed, 9 insertions(+)
arch/x86/kernel/fpu/xstate.c +9 -0
@@ -246,6 +246,15 @@ static void __init setup_xstate_features(void)/* start at the beginnning of the "extended state" */ unsigned int last_good_offset = offsetof(struct xregs_state , extended_state_area); +/* +* The FP xstates and SSE xstates are legacy states. They are always +* in the fixed offsets in the xsave area in either compacted form +* or standard form. +*/ + xstate_offsets[0 ] =0 ; + xstate_sizes[0 ] = offsetof(struct fxregs_state , xmm_space); + xstate_offsets[1 ] = xstate_sizes[0 ]; + xstate_sizes[1] = FIELD_SIZEOF(struct fxregs_state, xmm_space);for (i =FIRST_EXTENDED_XFEATURE ; i <XFEATURE_MAX ; i++) {if (!xfeature_enabled (i))