diff --git a/drivers/kvm/svm.c b/drivers/kvm/svm.c index ed33f59..f2d5ab0 100644 --- a/drivers/kvm/svm.c +++ b/drivers/kvm/svm.c @@ -1474,6 +1474,18 @@ static void load_db_regs(unsigned long *db_regs) asm volatile ("mov %0, %%dr3" : : "r"(db_regs[3])); } +/* pass data that is likly in L1 here */ +static inline void fx_clear_error_pointers(void *data) +{ + /* + * AMD K7/K8 CPUs don't save/restore FDP/FIP/FOP unless an exception is + * pending. So this function is used to set these registers to defined + * values. + */ + asm volatile ("emms\n" + "fildl %[addr]\n" :: [addr] "m" (data)); +} + static int svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) { u16 fs_selector; @@ -1510,6 +1522,7 @@ again: if (vcpu->fpu_active) { fx_save(vcpu->host_fx_image); + fx_clear_error_pointers(vcpu->svm->vmcb); fx_restore(vcpu->guest_fx_image); } @@ -1624,6 +1637,7 @@ again: if (vcpu->fpu_active) { fx_save(vcpu->guest_fx_image); + fx_clear_error_pointers(vcpu->svm->vmcb); fx_restore(vcpu->host_fx_image); }