Skip to content

Commit 3ef0df3

Browse files
committed
KVM: VMX: Don't modify guest XFD_ERR if CR0.TS=1
Don't update the guest's XFD_ERR MSR if CR0.TS is set; per the SDM, XFD_ERR is not modified if CR0.TS=1. Although it's not explicitly stated in the SDM, conceptually it makes sense the CR0.TS check would be done prior to the XFD_ERR check, e.g. CR0.TS=1 blocks all SIMD state, whereas XFD blocks only XTILE state. Device-not-available exceptions that are not due to XFD - those resulting from setting CR0.TS to 1 - do not modify the IA32_XFD_ERR MSR. Opportunistically update the comment to call out that XFD_ERR is updated before the VM-Exit check occurs. Nothing in the SDM explicitly calls out this behavior, but logically it must be the behavior, otherwise reading XFD_ERR in handle_nm_fault_irqoff() would return stale data, i.e. the to-be-delivered XFD_ERR value would need to be saved in EXIT_QUALIFICATION, a la DR6 for #DB and CR2 for #PF, so that software could capture the guest value. Fixes: ec5be88 ("kvm: x86: Intercept #NM for saving IA32_XFD_ERR") Signed-off-by: Xin Li (Intel) <xin@zytor.com> Tested-by: Shan Kang <shan.kang@intel.com> Link: https://lore.kernel.org/r/20241001050110.3643764-3-xin@zytor.com Signed-off-by: Sean Christopherson <seanjc@google.com>
1 parent a64dcfb commit 3ef0df3

File tree

1 file changed

+8
-8
lines changed

1 file changed

+8
-8
lines changed

arch/x86/kvm/vmx/vmx.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6995,16 +6995,16 @@ static void handle_nm_fault_irqoff(struct kvm_vcpu *vcpu)
69956995
* MSR value is not clobbered by the host activity before the guest
69966996
* has chance to consume it.
69976997
*
6998-
* Do not blindly read xfd_err here, since this exception might
6999-
* be caused by L1 interception on a platform which doesn't
7000-
* support xfd at all.
6998+
* Update the guest's XFD_ERR if and only if XFD is enabled, as the #NM
6999+
* interception may have been caused by L1 interception. Per the SDM,
7000+
* XFD_ERR is not modified if CR0.TS=1.
70017001
*
7002-
* Do it conditionally upon guest_fpu::xfd. xfd_err matters
7003-
* only when xfd contains a non-zero value.
7004-
*
7005-
* Queuing exception is done in vmx_handle_exit. See comment there.
7002+
* Note, XFD_ERR is updated _before_ the #NM interception check, i.e.
7003+
* unlike CR2 and DR6, the value is not a payload that is attached to
7004+
* the #NM exception.
70067005
*/
7007-
if (vcpu->arch.guest_fpu.fpstate->xfd)
7006+
if (vcpu->arch.guest_fpu.fpstate->xfd &&
7007+
!kvm_is_cr0_bit_set(vcpu, X86_CR0_TS))
70087008
rdmsrl(MSR_IA32_XFD_ERR, vcpu->arch.guest_fpu.xfd_err);
70097009
}
70107010

0 commit comments

Comments
 (0)