Patch: target/i386: Change CR4 before CR0 in SVM

Bernhard Kauer posted 1 patch 1 year, 3 months ago
Failed in applying to current master (apply log)
save.cr0)) |
Patch: target/i386: Change CR4 before CR0 in SVM
Posted by Bernhard Kauer 1 year, 3 months ago
 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)));