if (npt_enabled)
goto set;
- if (kvm_read_cr0_bits(vcpu, X86_CR0_TS) && !(cr0 & X86_CR0_TS)) {
- svm->vmcb->control.intercept_exceptions &= ~(1 << NM_VECTOR);
- vcpu->fpu_active = 1;
- }
-
vcpu->arch.cr0 = cr0;
cr0 |= X86_CR0_PG | X86_CR0_WP;
- if (!vcpu->fpu_active) {
- svm->vmcb->control.intercept_exceptions |= (1 << NM_VECTOR);
+
+ if (!vcpu->fpu_active)
cr0 |= X86_CR0_TS;
- }
set:
/*
* re-enable caching here because the QEMU bios
svm->vmcb->control.intercept_exceptions &= ~(1 << NM_VECTOR);
if (!kvm_read_cr0_bits(&svm->vcpu, X86_CR0_TS))
svm->vmcb->save.cr0 &= ~X86_CR0_TS;
+ else
+ svm->vmcb->save.cr0 |= X86_CR0_TS;
svm->vcpu.fpu_active = 1;
return 1;
static void svm_prepare_guest_switch(struct kvm_vcpu *vcpu)
{
+ if (npt_enabled)
+ vcpu->fpu_active = 1;
}
static inline void sync_cr8_to_lapic(struct kvm_vcpu *vcpu)
svm->vmcb->save.cr3 = root;
force_new_asid(vcpu);
-
- if (vcpu->fpu_active) {
- svm->vmcb->control.intercept_exceptions |= (1 << NM_VECTOR);
- svm->vmcb->save.cr0 |= X86_CR0_TS;
- vcpu->fpu_active = 0;
- }
}
static int is_disabled(void)
return false;
}
+static void svm_fpu_deactivate(struct kvm_vcpu *vcpu)
+{
+ struct vcpu_svm *svm = to_svm(vcpu);
+
+ if (npt_enabled) {
+ /* hack: npt requires active fpu at this time */
+ vcpu->fpu_active = 1;
+ return;
+ }
+
+ svm->vmcb->control.intercept_exceptions |= 1 << NM_VECTOR;
+ svm->vmcb->save.cr0 |= X86_CR0_TS;
+}
+
static struct kvm_x86_ops svm_x86_ops = {
.cpu_has_kvm_support = has_svm,
.disabled_by_bios = is_disabled,
.cache_reg = svm_cache_reg,
.get_rflags = svm_get_rflags,
.set_rflags = svm_set_rflags,
+ .fpu_deactivate = svm_fpu_deactivate,
.tlb_flush = svm_flush_tlb,