@@ -120,11 +120,6 @@ static bool xfeature_is_supervisor(int xfeature_nr)
120
120
return ecx & 1 ;
121
121
}
122
122
123
- static bool xfeature_is_user (int xfeature_nr )
124
- {
125
- return !xfeature_is_supervisor (xfeature_nr );
126
- }
127
-
128
123
/*
129
124
* When executing XSAVEOPT (or other optimized XSAVE instructions), if
130
125
* a processor implementation detects that an FPU state component is still
@@ -265,21 +260,25 @@ static void __init setup_xstate_features(void)
265
260
266
261
cpuid_count (XSTATE_CPUID , i , & eax , & ebx , & ecx , & edx );
267
262
263
+ xstate_sizes [i ] = eax ;
264
+
268
265
/*
269
- * If an xfeature is supervisor state, the offset
270
- * in EBX is invalid. We leave it to -1.
266
+ * If an xfeature is supervisor state, the offset in EBX is
267
+ * invalid, leave it to -1.
271
268
*/
272
- if (xfeature_is_user (i ))
273
- xstate_offsets [i ] = ebx ;
269
+ if (xfeature_is_supervisor (i ))
270
+ continue ;
271
+
272
+ xstate_offsets [i ] = ebx ;
274
273
275
- xstate_sizes [i ] = eax ;
276
274
/*
277
- * In our xstate size checks, we assume that the
278
- * highest-numbered xstate feature has the
279
- * highest offset in the buffer. Ensure it does.
275
+ * In our xstate size checks, we assume that the highest-numbered
276
+ * xstate feature has the highest offset in the buffer. Ensure
277
+ * it does.
280
278
*/
281
279
WARN_ONCE (last_good_offset > xstate_offsets [i ],
282
- "x86/fpu: misordered xstate at %d\n" , last_good_offset );
280
+ "x86/fpu: misordered xstate at %d\n" , last_good_offset );
281
+
283
282
last_good_offset = xstate_offsets [i ];
284
283
}
285
284
}
@@ -326,6 +325,13 @@ static int xfeature_is_aligned(int xfeature_nr)
326
325
u32 eax , ebx , ecx , edx ;
327
326
328
327
CHECK_XFEATURE (xfeature_nr );
328
+
329
+ if (!xfeature_enabled (xfeature_nr )) {
330
+ WARN_ONCE (1 , "Checking alignment of disabled xfeature %d\n" ,
331
+ xfeature_nr );
332
+ return 0 ;
333
+ }
334
+
329
335
cpuid_count (XSTATE_CPUID , xfeature_nr , & eax , & ebx , & ecx , & edx );
330
336
/*
331
337
* The value returned by ECX[1] indicates the alignment
@@ -338,11 +344,11 @@ static int xfeature_is_aligned(int xfeature_nr)
338
344
/*
339
345
* This function sets up offsets and sizes of all extended states in
340
346
* xsave area. This supports both standard format and compacted format
341
- * of the xsave aread .
347
+ * of the xsave area .
342
348
*/
343
- static void __init setup_xstate_comp (void )
349
+ static void __init setup_xstate_comp_offsets (void )
344
350
{
345
- unsigned int xstate_comp_sizes [ XFEATURE_MAX ] ;
351
+ unsigned int next_offset ;
346
352
int i ;
347
353
348
354
/*
@@ -356,31 +362,23 @@ static void __init setup_xstate_comp(void)
356
362
357
363
if (!boot_cpu_has (X86_FEATURE_XSAVES )) {
358
364
for (i = FIRST_EXTENDED_XFEATURE ; i < XFEATURE_MAX ; i ++ ) {
359
- if (xfeature_enabled (i )) {
365
+ if (xfeature_enabled (i ))
360
366
xstate_comp_offsets [i ] = xstate_offsets [i ];
361
- xstate_comp_sizes [i ] = xstate_sizes [i ];
362
- }
363
367
}
364
368
return ;
365
369
}
366
370
367
- xstate_comp_offsets [FIRST_EXTENDED_XFEATURE ] =
368
- FXSAVE_SIZE + XSAVE_HDR_SIZE ;
371
+ next_offset = FXSAVE_SIZE + XSAVE_HDR_SIZE ;
369
372
370
373
for (i = FIRST_EXTENDED_XFEATURE ; i < XFEATURE_MAX ; i ++ ) {
371
- if (xfeature_enabled (i ))
372
- xstate_comp_sizes [i ] = xstate_sizes [i ];
373
- else
374
- xstate_comp_sizes [i ] = 0 ;
374
+ if (!xfeature_enabled (i ))
375
+ continue ;
375
376
376
- if (i > FIRST_EXTENDED_XFEATURE ) {
377
- xstate_comp_offsets [i ] = xstate_comp_offsets [i - 1 ]
378
- + xstate_comp_sizes [i - 1 ];
377
+ if (xfeature_is_aligned (i ))
378
+ next_offset = ALIGN (next_offset , 64 );
379
379
380
- if (xfeature_is_aligned (i ))
381
- xstate_comp_offsets [i ] =
382
- ALIGN (xstate_comp_offsets [i ], 64 );
383
- }
380
+ xstate_comp_offsets [i ] = next_offset ;
381
+ next_offset += xstate_sizes [i ];
384
382
}
385
383
}
386
384
@@ -774,7 +772,7 @@ void __init fpu__init_system_xstate(void)
774
772
775
773
fpu__init_prepare_fx_sw_frame ();
776
774
setup_init_fpu_buf ();
777
- setup_xstate_comp ();
775
+ setup_xstate_comp_offsets ();
778
776
print_xstate_offset_size ();
779
777
780
778
pr_info ("x86/fpu: Enabled xstate features 0x%llx, context size is %d bytes, using '%s' format.\n" ,
@@ -897,8 +895,6 @@ const void *get_xsave_field_ptr(int xfeature_nr)
897
895
898
896
#ifdef CONFIG_ARCH_HAS_PKEYS
899
897
900
- #define NR_VALID_PKRU_BITS (CONFIG_NR_PROTECTION_KEYS * 2)
901
- #define PKRU_VALID_MASK (NR_VALID_PKRU_BITS - 1)
902
898
/*
903
899
* This will go out and modify PKRU register to set the access
904
900
* rights for @pkey to @init_val.
@@ -917,6 +913,13 @@ int arch_set_user_pkey_access(struct task_struct *tsk, int pkey,
917
913
if (!boot_cpu_has (X86_FEATURE_OSPKE ))
918
914
return - EINVAL ;
919
915
916
+ /*
917
+ * This code should only be called with valid 'pkey'
918
+ * values originating from in-kernel users. Complain
919
+ * if a bad value is observed.
920
+ */
921
+ WARN_ON_ONCE (pkey >= arch_max_pkey ());
922
+
920
923
/* Set the bits we need in PKRU: */
921
924
if (init_val & PKEY_DISABLE_ACCESS )
922
925
new_pkru_bits |= PKRU_AD_BIT ;
0 commit comments