save.cr0)) |
There is a dependency in cpu_x86_update_cr0() to the current value of CR4
to enable or disable long-mode. This value is outdated when switching into
or out of SVM. This leads to invalid CPU state when returning from an unpaged
VM when EFER.LME is set.
Signed-off-by: Bernhard Kauer <bernhard.kauer@incari.com>
diff --git a/target/i386/tcg/sysemu/svm_helper.c b/target/i386/tcg/sysemu/svm_helper.c
index 2d27731b60..229a22816e 100644
--- a/target/i386/tcg/sysemu/svm_helper.c
+++ b/target/i386/tcg/sysemu/svm_helper.c
@@ -312,8 +312,8 @@ void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
x86_stq_phys(cs,
env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2), 0);
- cpu_x86_update_cr0(env, new_cr0);
cpu_x86_update_cr4(env, new_cr4);
+ cpu_x86_update_cr0(env, new_cr0);
cpu_x86_update_cr3(env, new_cr3);
env->cr[2] = x86_ldq_phys(cs,
env->vm_vmcb + offsetof(struct vmcb, save.cr2));
@@ -812,13 +812,13 @@ void do_vmexit(CPUX86State *env)
env->idt.limit = x86_ldl_phys(cs, env->vm_hsave + offsetof(struct vmcb,
save.idtr.limit));
+ cpu_x86_update_cr4(env, x86_ldq_phys(cs,
+ env->vm_hsave + offsetof(struct vmcb,
+ save.cr4)));
cpu_x86_update_cr0(env, x86_ldq_phys(cs,
env->vm_hsave + offsetof(struct vmcb,
save.cr0)) |
CR0_PE_MASK);
- cpu_x86_update_cr4(env, x86_ldq_phys(cs,
- env->vm_hsave + offsetof(struct vmcb,
- save.cr4)));
cpu_x86_update_cr3(env, x86_ldq_phys(cs,
env->vm_hsave + offsetof(struct vmcb,
save.cr3)));
© 2016 - 2024 Red Hat, Inc.