19
19
#include <sys/wait.h>
20
20
#include <sys/uio.h>
21
21
22
- #include "../kselftest.h" /* For __cpuid_count() */
23
22
#include "helpers.h"
23
+ #include "xstate.h"
24
24
25
25
#ifndef __x86_64__
26
26
# error This test is 64-bit only
27
27
#endif
28
28
29
- #define XSAVE_HDR_OFFSET 512
30
- #define XSAVE_HDR_SIZE 64
31
-
32
- struct xsave_buffer {
33
- union {
34
- struct {
35
- char legacy [XSAVE_HDR_OFFSET ];
36
- char header [XSAVE_HDR_SIZE ];
37
- char extended [0 ];
38
- };
39
- char bytes [0 ];
40
- };
41
- };
42
-
43
- static inline void xsave (struct xsave_buffer * xbuf , uint64_t rfbm )
44
- {
45
- uint32_t rfbm_lo = rfbm ;
46
- uint32_t rfbm_hi = rfbm >> 32 ;
47
-
48
- asm volatile ("xsave (%%rdi)"
49
- : : "D" (xbuf ), "a" (rfbm_lo ), "d" (rfbm_hi )
50
- : "memory" );
51
- }
52
-
53
- static inline void xrstor (struct xsave_buffer * xbuf , uint64_t rfbm )
54
- {
55
- uint32_t rfbm_lo = rfbm ;
56
- uint32_t rfbm_hi = rfbm >> 32 ;
57
-
58
- asm volatile ("xrstor (%%rdi)"
59
- : : "D" (xbuf ), "a" (rfbm_lo ), "d" (rfbm_hi ));
60
- }
61
-
62
29
/* err() exits and will not return */
63
30
#define fatal_error (msg , ...) err(1, "[FAIL]\t" msg, ##__VA_ARGS__)
64
31
@@ -68,92 +35,12 @@ static inline void xrstor(struct xsave_buffer *xbuf, uint64_t rfbm)
68
35
#define XFEATURE_MASK_XTILEDATA (1 << XFEATURE_XTILEDATA)
69
36
#define XFEATURE_MASK_XTILE (XFEATURE_MASK_XTILECFG | XFEATURE_MASK_XTILEDATA)
70
37
71
- #define CPUID_LEAF1_ECX_XSAVE_MASK (1 << 26)
72
- #define CPUID_LEAF1_ECX_OSXSAVE_MASK (1 << 27)
73
-
74
38
static uint32_t xbuf_size ;
75
39
76
- static struct {
77
- uint32_t xbuf_offset ;
78
- uint32_t size ;
79
- } xtiledata ;
80
-
81
- #define CPUID_LEAF_XSTATE 0xd
82
- #define CPUID_SUBLEAF_XSTATE_USER 0x0
83
- #define TILE_CPUID 0x1d
84
- #define TILE_PALETTE_ID 0x1
85
-
86
- static void check_cpuid_xtiledata (void )
87
- {
88
- uint32_t eax , ebx , ecx , edx ;
89
-
90
- __cpuid_count (CPUID_LEAF_XSTATE , CPUID_SUBLEAF_XSTATE_USER ,
91
- eax , ebx , ecx , edx );
92
-
93
- /*
94
- * EBX enumerates the size (in bytes) required by the XSAVE
95
- * instruction for an XSAVE area containing all the user state
96
- * components corresponding to bits currently set in XCR0.
97
- *
98
- * Stash that off so it can be used to allocate buffers later.
99
- */
100
- xbuf_size = ebx ;
101
-
102
- __cpuid_count (CPUID_LEAF_XSTATE , XFEATURE_XTILEDATA ,
103
- eax , ebx , ecx , edx );
104
- /*
105
- * eax: XTILEDATA state component size
106
- * ebx: XTILEDATA state component offset in user buffer
107
- */
108
- if (!eax || !ebx )
109
- fatal_error ("xstate cpuid: invalid tile data size/offset: %d/%d" ,
110
- eax , ebx );
111
-
112
- xtiledata .size = eax ;
113
- xtiledata .xbuf_offset = ebx ;
114
- }
40
+ struct xstate_info xtiledata ;
115
41
116
42
/* The helpers for managing XSAVE buffer and tile states: */
117
43
118
- struct xsave_buffer * alloc_xbuf (void )
119
- {
120
- struct xsave_buffer * xbuf ;
121
-
122
- /* XSAVE buffer should be 64B-aligned. */
123
- xbuf = aligned_alloc (64 , xbuf_size );
124
- if (!xbuf )
125
- fatal_error ("aligned_alloc()" );
126
- return xbuf ;
127
- }
128
-
129
- static inline void clear_xstate_header (struct xsave_buffer * buffer )
130
- {
131
- memset (& buffer -> header , 0 , sizeof (buffer -> header ));
132
- }
133
-
134
- static inline void set_xstatebv (struct xsave_buffer * buffer , uint64_t bv )
135
- {
136
- /* XSTATE_BV is at the beginning of the header: */
137
- * (uint64_t * )(& buffer -> header ) = bv ;
138
- }
139
-
140
- static void set_rand_tiledata (struct xsave_buffer * xbuf )
141
- {
142
- int * ptr = (int * )& xbuf -> bytes [xtiledata .xbuf_offset ];
143
- int data ;
144
- int i ;
145
-
146
- /*
147
- * Ensure that 'data' is never 0. This ensures that
148
- * the registers are never in their initial configuration
149
- * and thus never tracked as being in the init state.
150
- */
151
- data = rand () | 1 ;
152
-
153
- for (i = 0 ; i < xtiledata .size / sizeof (int ); i ++ , ptr ++ )
154
- * ptr = data ;
155
- }
156
-
157
44
struct xsave_buffer * stashed_xsave ;
158
45
159
46
static void init_stashed_xsave (void )
@@ -169,21 +56,6 @@ static void free_stashed_xsave(void)
169
56
free (stashed_xsave );
170
57
}
171
58
172
- /* See 'struct _fpx_sw_bytes' at sigcontext.h */
173
- #define SW_BYTES_OFFSET 464
174
- /* N.B. The struct's field name varies so read from the offset. */
175
- #define SW_BYTES_BV_OFFSET (SW_BYTES_OFFSET + 8)
176
-
177
- static inline struct _fpx_sw_bytes * get_fpx_sw_bytes (void * buffer )
178
- {
179
- return (struct _fpx_sw_bytes * )(buffer + SW_BYTES_OFFSET );
180
- }
181
-
182
- static inline uint64_t get_fpx_sw_bytes_features (void * buffer )
183
- {
184
- return * (uint64_t * )(buffer + SW_BYTES_BV_OFFSET );
185
- }
186
-
187
59
/* Work around printf() being unsafe in signals: */
188
60
#define SIGNAL_BUF_LEN 1000
189
61
char signal_message_buffer [SIGNAL_BUF_LEN ];
@@ -281,7 +153,7 @@ static inline bool load_rand_tiledata(struct xsave_buffer *xbuf)
281
153
{
282
154
clear_xstate_header (xbuf );
283
155
set_xstatebv (xbuf , XFEATURE_MASK_XTILEDATA );
284
- set_rand_tiledata ( xbuf );
156
+ set_rand_data ( & xtiledata , xbuf );
285
157
return xrstor_safe (xbuf , XFEATURE_MASK_XTILEDATA );
286
158
}
287
159
@@ -884,7 +756,13 @@ int main(void)
884
756
return KSFT_SKIP ;
885
757
}
886
758
887
- check_cpuid_xtiledata ();
759
+ xbuf_size = get_xbuf_size ();
760
+
761
+ xtiledata = get_xstate_info (XFEATURE_XTILEDATA );
762
+ if (!xtiledata .size || !xtiledata .xbuf_offset ) {
763
+ fatal_error ("xstate cpuid: invalid tile data size/offset: %d/%d" ,
764
+ xtiledata .size , xtiledata .xbuf_offset );
765
+ }
888
766
889
767
init_stashed_xsave ();
890
768
sethandler (SIGILL , handle_noperm , 0 );
0 commit comments