@@ -125,6 +125,7 @@ struct fpsimd_last_state_struct {
125
125
u64 * svcr ;
126
126
unsigned int sve_vl ;
127
127
unsigned int sme_vl ;
128
+ enum fp_type * fp_type ;
128
129
};
129
130
130
131
static DEFINE_PER_CPU (struct fpsimd_last_state_struct , fpsimd_last_state ) ;
@@ -330,15 +331,6 @@ void task_set_vl_onexec(struct task_struct *task, enum vec_type type,
330
331
* The task can execute SVE instructions while in userspace without
331
332
* trapping to the kernel.
332
333
*
333
- * When stored, Z0-Z31 (incorporating Vn in bits[127:0] or the
334
- * corresponding Zn), P0-P15 and FFR are encoded in
335
- * task->thread.sve_state, formatted appropriately for vector
336
- * length task->thread.sve_vl or, if SVCR.SM is set,
337
- * task->thread.sme_vl.
338
- *
339
- * task->thread.sve_state must point to a valid buffer at least
340
- * sve_state_size(task) bytes in size.
341
- *
342
334
* During any syscall, the kernel may optionally clear TIF_SVE and
343
335
* discard the vector state except for the FPSIMD subset.
344
336
*
@@ -348,7 +340,15 @@ void task_set_vl_onexec(struct task_struct *task, enum vec_type type,
348
340
* do_sve_acc() to be called, which does some preparation and then
349
341
* sets TIF_SVE.
350
342
*
351
- * When stored, FPSIMD registers V0-V31 are encoded in
343
+ * During any syscall, the kernel may optionally clear TIF_SVE and
344
+ * discard the vector state except for the FPSIMD subset.
345
+ *
346
+ * The data will be stored in one of two formats:
347
+ *
348
+ * * FPSIMD only - FP_STATE_FPSIMD:
349
+ *
350
+ * When the FPSIMD only state stored task->thread.fp_type is set to
351
+ * FP_STATE_FPSIMD, the FPSIMD registers V0-V31 are encoded in
352
352
* task->thread.uw.fpsimd_state; bits [max : 128] for each of Z0-Z31 are
353
353
* logically zero but not stored anywhere; P0-P15 and FFR are not
354
354
* stored and have unspecified values from userspace's point of
@@ -358,6 +358,19 @@ void task_set_vl_onexec(struct task_struct *task, enum vec_type type,
358
358
* task->thread.sve_state does not need to be non-NULL, valid or any
359
359
* particular size: it must not be dereferenced.
360
360
*
361
+ * * SVE state - FP_STATE_SVE:
362
+ *
363
+ * When the full SVE state is stored task->thread.fp_type is set to
364
+ * FP_STATE_SVE and Z0-Z31 (incorporating Vn in bits[127:0] or the
365
+ * corresponding Zn), P0-P15 and FFR are encoded in in
366
+ * task->thread.sve_state, formatted appropriately for vector
367
+ * length task->thread.sve_vl or, if SVCR.SM is set,
368
+ * task->thread.sme_vl. The storage for the vector registers in
369
+ * task->thread.uw.fpsimd_state should be ignored.
370
+ *
371
+ * task->thread.sve_state must point to a valid buffer at least
372
+ * sve_state_size(task) bytes in size.
373
+ *
361
374
* * FPSR and FPCR are always stored in task->thread.uw.fpsimd_state
362
375
* irrespective of whether TIF_SVE is clear or set, since these are
363
376
* not vector length dependent.
@@ -404,12 +417,15 @@ static void task_fpsimd_load(void)
404
417
}
405
418
}
406
419
407
- if (restore_sve_regs )
420
+ if (restore_sve_regs ) {
421
+ WARN_ON_ONCE (current -> thread .fp_type != FP_STATE_SVE );
408
422
sve_load_state (sve_pffr (& current -> thread ),
409
423
& current -> thread .uw .fpsimd_state .fpsr ,
410
424
restore_ffr );
411
- else
425
+ } else {
426
+ WARN_ON_ONCE (current -> thread .fp_type != FP_STATE_FPSIMD );
412
427
fpsimd_load_state (& current -> thread .uw .fpsimd_state );
428
+ }
413
429
}
414
430
415
431
/*
@@ -474,8 +490,10 @@ static void fpsimd_save(void)
474
490
sve_save_state ((char * )last -> sve_state +
475
491
sve_ffr_offset (vl ),
476
492
& last -> st -> fpsr , save_ffr );
493
+ * last -> fp_type = FP_STATE_SVE ;
477
494
} else {
478
495
fpsimd_save_state (last -> st );
496
+ * last -> fp_type = FP_STATE_FPSIMD ;
479
497
}
480
498
}
481
499
@@ -848,8 +866,10 @@ int vec_set_vector_length(struct task_struct *task, enum vec_type type,
848
866
849
867
fpsimd_flush_task_state (task );
850
868
if (test_and_clear_tsk_thread_flag (task , TIF_SVE ) ||
851
- thread_sm_enabled (& task -> thread ))
869
+ thread_sm_enabled (& task -> thread )) {
852
870
sve_to_fpsimd (task );
871
+ task -> thread .fp_type = FP_STATE_FPSIMD ;
872
+ }
853
873
854
874
if (system_supports_sme () && type == ARM64_VEC_SME ) {
855
875
task -> thread .svcr &= ~(SVCR_SM_MASK |
@@ -1368,6 +1388,7 @@ static void sve_init_regs(void)
1368
1388
fpsimd_bind_task_to_cpu ();
1369
1389
} else {
1370
1390
fpsimd_to_sve (current );
1391
+ current -> thread .fp_type = FP_STATE_SVE ;
1371
1392
}
1372
1393
}
1373
1394
@@ -1596,6 +1617,8 @@ void fpsimd_flush_thread(void)
1596
1617
current -> thread .svcr = 0 ;
1597
1618
}
1598
1619
1620
+ current -> thread .fp_type = FP_STATE_FPSIMD ;
1621
+
1599
1622
put_cpu_fpsimd_context ();
1600
1623
kfree (sve_state );
1601
1624
kfree (za_state );
@@ -1644,8 +1667,10 @@ void fpsimd_kvm_prepare(void)
1644
1667
*/
1645
1668
get_cpu_fpsimd_context ();
1646
1669
1647
- if (test_and_clear_thread_flag (TIF_SVE ))
1670
+ if (test_and_clear_thread_flag (TIF_SVE )) {
1648
1671
sve_to_fpsimd (current );
1672
+ current -> thread .fp_type = FP_STATE_FPSIMD ;
1673
+ }
1649
1674
1650
1675
put_cpu_fpsimd_context ();
1651
1676
}
@@ -1667,6 +1692,7 @@ static void fpsimd_bind_task_to_cpu(void)
1667
1692
last -> sve_vl = task_get_sve_vl (current );
1668
1693
last -> sme_vl = task_get_sme_vl (current );
1669
1694
last -> svcr = & current -> thread .svcr ;
1695
+ last -> fp_type = & current -> thread .fp_type ;
1670
1696
current -> thread .fpsimd_cpu = smp_processor_id ();
1671
1697
1672
1698
/*
@@ -1690,7 +1716,8 @@ static void fpsimd_bind_task_to_cpu(void)
1690
1716
1691
1717
void fpsimd_bind_state_to_cpu (struct user_fpsimd_state * st , void * sve_state ,
1692
1718
unsigned int sve_vl , void * za_state ,
1693
- unsigned int sme_vl , u64 * svcr )
1719
+ unsigned int sme_vl , u64 * svcr ,
1720
+ enum fp_type * type )
1694
1721
{
1695
1722
struct fpsimd_last_state_struct * last =
1696
1723
this_cpu_ptr (& fpsimd_last_state );
@@ -1704,6 +1731,7 @@ void fpsimd_bind_state_to_cpu(struct user_fpsimd_state *st, void *sve_state,
1704
1731
last -> za_state = za_state ;
1705
1732
last -> sve_vl = sve_vl ;
1706
1733
last -> sme_vl = sme_vl ;
1734
+ last -> fp_type = type ;
1707
1735
}
1708
1736
1709
1737
/*
0 commit comments