Skip to content

Commit d62c02a

Browse files
committed
KVM: VMX: Pass XFD_ERR as pseudo-payload when injecting #NM
Pass XFD_ERR via KVM's exception payload mechanism when injecting an #NM after interception so that XFD_ERR can be propagated to FRED's event_data field without needing a dedicated field (which would need to be migrated). For non-FRED vCPUs, this is a glorified NOP as kvm_deliver_exception_payload() will simply do nothing (which is desirable and correct). 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-15-xin@zytor.com Signed-off-by: Sean Christopherson <seanjc@google.com>
1 parent 3ef0df3 commit d62c02a

File tree

1 file changed

+10
-4
lines changed

1 file changed

+10
-4
lines changed

arch/x86/kvm/vmx/vmx.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5215,6 +5215,12 @@ bool vmx_guest_inject_ac(struct kvm_vcpu *vcpu)
52155215
(kvm_get_rflags(vcpu) & X86_EFLAGS_AC);
52165216
}
52175217

5218+
static bool is_xfd_nm_fault(struct kvm_vcpu *vcpu)
5219+
{
5220+
return vcpu->arch.guest_fpu.fpstate->xfd &&
5221+
!kvm_is_cr0_bit_set(vcpu, X86_CR0_TS);
5222+
}
5223+
52185224
static int handle_exception_nmi(struct kvm_vcpu *vcpu)
52195225
{
52205226
struct vcpu_vmx *vmx = to_vmx(vcpu);
@@ -5241,7 +5247,8 @@ static int handle_exception_nmi(struct kvm_vcpu *vcpu)
52415247
* point.
52425248
*/
52435249
if (is_nm_fault(intr_info)) {
5244-
kvm_queue_exception(vcpu, NM_VECTOR);
5250+
kvm_queue_exception_p(vcpu, NM_VECTOR,
5251+
is_xfd_nm_fault(vcpu) ? vcpu->arch.guest_fpu.xfd_err : 0);
52455252
return 1;
52465253
}
52475254

@@ -6997,14 +7004,13 @@ static void handle_nm_fault_irqoff(struct kvm_vcpu *vcpu)
69977004
*
69987005
* Update the guest's XFD_ERR if and only if XFD is enabled, as the #NM
69997006
* interception may have been caused by L1 interception. Per the SDM,
7000-
* XFD_ERR is not modified if CR0.TS=1.
7007+
* XFD_ERR is not modified for non-XFD #NM, i.e. if CR0.TS=1.
70017008
*
70027009
* Note, XFD_ERR is updated _before_ the #NM interception check, i.e.
70037010
* unlike CR2 and DR6, the value is not a payload that is attached to
70047011
* the #NM exception.
70057012
*/
7006-
if (vcpu->arch.guest_fpu.fpstate->xfd &&
7007-
!kvm_is_cr0_bit_set(vcpu, X86_CR0_TS))
7013+
if (is_xfd_nm_fault(vcpu))
70087014
rdmsrl(MSR_IA32_XFD_ERR, vcpu->arch.guest_fpu.xfd_err);
70097015
}
70107016

0 commit comments

Comments
 (0)