Skip to content

Commit 5429cea

Browse files
KAGA-KOKObonzini
authored andcommitted
x86/fpu: Provide fpu_sync_guest_vmexit_xfd_state()
KVM can disable the write emulation for the XFD MSR when the vCPU's fpstate is already correctly sized to reduce the overhead. When write emulation is disabled the XFD MSR state after a VMEXIT is unknown and therefore not in sync with the software states in fpstate and the per CPU XFD cache. Provide fpu_sync_guest_vmexit_xfd_state() which has to be invoked after a VMEXIT before enabling interrupts when write emulation is disabled for the XFD MSR. It could be invoked unconditionally even when write emulation is enabled for the price of a pointless MSR read. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Jing Liu <jing2.liu@intel.com> Signed-off-by: Yang Zhong <yang.zhong@intel.com> Message-Id: <20220105123532.12586-21-yang.zhong@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
1 parent 415a3c3 commit 5429cea

File tree

2 files changed

+26
-0
lines changed

2 files changed

+26
-0
lines changed

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,10 @@ extern int fpu_enable_guest_xfd_features(struct fpu_guest *guest_fpu, u64 xfeatu
142142

143143
#ifdef CONFIG_X86_64
144144
extern void fpu_update_guest_xfd(struct fpu_guest *guest_fpu, u64 xfd);
145+
extern void fpu_sync_guest_vmexit_xfd_state(void);
145146
#else
146147
static inline void fpu_update_guest_xfd(struct fpu_guest *guest_fpu, u64 xfd) { }
148+
static inline void fpu_sync_guest_vmexit_xfd_state(void) { }
147149
#endif
148150

149151
extern void fpu_copy_guest_fpstate_to_uabi(struct fpu_guest *gfpu, void *buf, unsigned int size, u32 pkru);

arch/x86/kernel/fpu/core.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,30 @@ void fpu_update_guest_xfd(struct fpu_guest *guest_fpu, u64 xfd)
294294
fpregs_unlock();
295295
}
296296
EXPORT_SYMBOL_GPL(fpu_update_guest_xfd);
297+
298+
/**
299+
* fpu_sync_guest_vmexit_xfd_state - Synchronize XFD MSR and software state
300+
*
301+
* Must be invoked from KVM after a VMEXIT before enabling interrupts when
302+
* XFD write emulation is disabled. This is required because the guest can
303+
* freely modify XFD and the state at VMEXIT is not guaranteed to be the
304+
* same as the state on VMENTER. So software state has to be udpated before
305+
* any operation which depends on it can take place.
306+
*
307+
* Note: It can be invoked unconditionally even when write emulation is
308+
* enabled for the price of a then pointless MSR read.
309+
*/
310+
void fpu_sync_guest_vmexit_xfd_state(void)
311+
{
312+
struct fpstate *fps = current->thread.fpu.fpstate;
313+
314+
lockdep_assert_irqs_disabled();
315+
if (fpu_state_size_dynamic()) {
316+
rdmsrl(MSR_IA32_XFD, fps->xfd);
317+
__this_cpu_write(xfd_state, fps->xfd);
318+
}
319+
}
320+
EXPORT_SYMBOL_GPL(fpu_sync_guest_vmexit_xfd_state);
297321
#endif /* CONFIG_X86_64 */
298322

299323
int fpu_swap_kvm_fpstate(struct fpu_guest *guest_fpu, bool enter_guest)

0 commit comments

Comments
 (0)