Skip to content

Commit 75c52da

Browse files
KAGA-KOKOsuryasaimadhu
authored andcommitted
x86/fpu: Prepare for sanitizing KVM FPU code
For the upcoming AMX support it's necessary to do a proper integration with KVM. To avoid more nasty hackery in KVM which violate encapsulation extend struct fpu and fpstate so the fpstate switching can be consolidated and simplified. Currently KVM allocates two FPU structs which are used for saving the user state of the vCPU thread and restoring the guest state when entering vcpu_run() and doing the reverse operation before leaving vcpu_run(). With the new fpstate mechanism this can be reduced to one extra buffer by swapping the fpstate pointer in current::thread::fpu. This makes the upcoming support for AMX and XFD simpler because then fpstate information (features, sizes, xfd) are always consistent and it does not require any nasty workarounds. Add fpu::__task_fpstate to save the regular fpstate pointer while the task is inside vcpu_run(). Add some state fields to fpstate to indicate the nature of the state. Signed-off-by: Thomas Gleixner <[email protected]> Signed-off-by: Borislav Petkov <[email protected]> Link: https://lkml.kernel.org/r/[email protected]
1 parent d72c870 commit 75c52da

File tree

1 file changed

+43
-1
lines changed

1 file changed

+43
-1
lines changed

arch/x86/include/asm/fpu/types.h

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,8 +322,32 @@ struct fpstate {
322322
/* @user_xfeatures: xfeatures valid in UABI buffers */
323323
u64 user_xfeatures;
324324

325+
/* @is_valloc: Indicator for dynamically allocated state */
326+
unsigned int is_valloc : 1;
327+
328+
/* @is_guest: Indicator for guest state (KVM) */
329+
unsigned int is_guest : 1;
330+
331+
/*
332+
* @is_confidential: Indicator for KVM confidential mode.
333+
* The FPU registers are restored by the
334+
* vmentry firmware from encrypted guest
335+
* memory. On vmexit the FPU registers are
336+
* saved by firmware to encrypted guest memory
337+
* and the registers are scrubbed before
338+
* returning to the host. So there is no
339+
* content which is worth saving and restoring.
340+
* The fpstate has to be there so that
341+
* preemption and softirq FPU usage works
342+
* without special casing.
343+
*/
344+
unsigned int is_confidential : 1;
345+
346+
/* @in_use: State is in use */
347+
unsigned int in_use : 1;
348+
325349
/* @regs: The register state union for all supported formats */
326-
union fpregs_state regs;
350+
union fpregs_state regs;
327351

328352
/* @regs is dynamically sized! Don't add anything after @regs! */
329353
} __aligned(64);
@@ -363,6 +387,14 @@ struct fpu {
363387
*/
364388
struct fpstate *fpstate;
365389

390+
/*
391+
* @__task_fpstate:
392+
*
393+
* Pointer to an inactive struct fpstate. Initialized to NULL. Is
394+
* used only for KVM support to swap out the regular task fpstate.
395+
*/
396+
struct fpstate *__task_fpstate;
397+
366398
/*
367399
* @__fpstate:
368400
*
@@ -378,6 +410,16 @@ struct fpu {
378410
*/
379411
};
380412

413+
/*
414+
* Guest pseudo FPU container
415+
*/
416+
struct fpu_guest {
417+
/*
418+
* @fpstate: Pointer to the allocated guest fpstate
419+
*/
420+
struct fpstate *fpstate;
421+
};
422+
381423
/*
382424
* FPU state configuration data. Initialized at boot time. Read only after init.
383425
*/

0 commit comments

Comments
 (0)