Commit 5efc27bbb695017a7386cb9acef247b9dd29f2b6

Authored by bellard
1 parent f2289cb6

EFER loading fixes, including SVME bit

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4659 c046a42c-6fe2-441c-8c8c-71466251a162
target-i386/cpu.h
@@ -148,7 +148,7 @@ @@ -148,7 +148,7 @@
148 #define HF_GIF_SHIFT 20 /* if set CPU takes interrupts */ 148 #define HF_GIF_SHIFT 20 /* if set CPU takes interrupts */
149 #define HF_HIF_SHIFT 21 /* shadow copy of IF_MASK when in SVM */ 149 #define HF_HIF_SHIFT 21 /* shadow copy of IF_MASK when in SVM */
150 #define HF_NMI_SHIFT 22 /* CPU serving NMI */ 150 #define HF_NMI_SHIFT 22 /* CPU serving NMI */
151 -#define HF_SVME_SHIFT 23 /* SVME enabled (copy of EFER.SVME */ 151 +#define HF_SVME_SHIFT 23 /* SVME enabled (copy of EFER.SVME) */
152 #define HF_SVMI_SHIFT 24 /* SVM intercepts are active */ 152 #define HF_SVMI_SHIFT 24 /* SVM intercepts are active */
153 153
154 #define HF_CPL_MASK (3 << HF_CPL_SHIFT) 154 #define HF_CPL_MASK (3 << HF_CPL_SHIFT)
target-i386/exec.h
@@ -397,3 +397,14 @@ static inline int cpu_halted(CPUState *env) { @@ -397,3 +397,14 @@ static inline int cpu_halted(CPUState *env) {
397 return EXCP_HALTED; 397 return EXCP_HALTED;
398 } 398 }
399 399
  400 +/* load efer and update the corresponding hflags. XXX: do consistency
  401 + checks with cpuid bits ? */
  402 +static inline void cpu_load_efer(CPUState *env, uint64_t val)
  403 +{
  404 + env->efer = val;
  405 + env->hflags &= ~(HF_LMA_MASK | HF_SVME_MASK);
  406 + if (env->efer & MSR_EFER_LMA)
  407 + env->hflags |= HF_LMA_MASK;
  408 + if (env->efer & MSR_EFER_SVME)
  409 + env->hflags |= HF_SVME_MASK;
  410 +}
target-i386/op_helper.c
@@ -1435,8 +1435,7 @@ void do_smm_enter(void) @@ -1435,8 +1435,7 @@ void do_smm_enter(void)
1435 /* init SMM cpu state */ 1435 /* init SMM cpu state */
1436 1436
1437 #ifdef TARGET_X86_64 1437 #ifdef TARGET_X86_64
1438 - env->efer = 0;  
1439 - env->hflags &= ~HF_LMA_MASK; 1438 + cpu_load_efer(env, 0);
1440 #endif 1439 #endif
1441 load_eflags(0, ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK)); 1440 load_eflags(0, ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK));
1442 env->eip = 0x00008000; 1441 env->eip = 0x00008000;
@@ -1463,11 +1462,7 @@ void helper_rsm(void) @@ -1463,11 +1462,7 @@ void helper_rsm(void)
1463 1462
1464 sm_state = env->smbase + 0x8000; 1463 sm_state = env->smbase + 0x8000;
1465 #ifdef TARGET_X86_64 1464 #ifdef TARGET_X86_64
1466 - env->efer = ldq_phys(sm_state + 0x7ed0);  
1467 - if (env->efer & MSR_EFER_LMA)  
1468 - env->hflags |= HF_LMA_MASK;  
1469 - else  
1470 - env->hflags &= ~HF_LMA_MASK; 1465 + cpu_load_efer(env, ldq_phys(sm_state + 0x7ed0));
1471 1466
1472 for(i = 0; i < 6; i++) { 1467 for(i = 0; i < 6; i++) {
1473 offset = 0x7e00 + i * 16; 1468 offset = 0x7e00 + i * 16;
@@ -3069,8 +3064,10 @@ void helper_wrmsr(void) @@ -3069,8 +3064,10 @@ void helper_wrmsr(void)
3069 update_mask |= MSR_EFER_FFXSR; 3064 update_mask |= MSR_EFER_FFXSR;
3070 if (env->cpuid_ext2_features & CPUID_EXT2_NX) 3065 if (env->cpuid_ext2_features & CPUID_EXT2_NX)
3071 update_mask |= MSR_EFER_NXE; 3066 update_mask |= MSR_EFER_NXE;
3072 - env->efer = (env->efer & ~update_mask) |  
3073 - (val & update_mask); 3067 + if (env->cpuid_ext3_features & CPUID_EXT3_SVM)
  3068 + update_mask |= MSR_EFER_SVME;
  3069 + cpu_load_efer(env, (env->efer & ~update_mask) |
  3070 + (val & update_mask));
3074 } 3071 }
3075 break; 3072 break;
3076 case MSR_STAR: 3073 case MSR_STAR:
@@ -4873,10 +4870,8 @@ void helper_vmrun(void) @@ -4873,10 +4870,8 @@ void helper_vmrun(void)
4873 } 4870 }
4874 4871
4875 #ifdef TARGET_X86_64 4872 #ifdef TARGET_X86_64
4876 - env->efer = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.efer));  
4877 - env->hflags &= ~HF_LMA_MASK;  
4878 - if (env->efer & MSR_EFER_LMA)  
4879 - env->hflags |= HF_LMA_MASK; 4873 + cpu_load_efer(env,
  4874 + ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.efer)));
4880 #endif 4875 #endif
4881 env->eflags = 0; 4876 env->eflags = 0;
4882 load_eflags(ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rflags)), 4877 load_eflags(ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rflags)),
@@ -5224,20 +5219,11 @@ void helper_vmexit(uint32_t exit_code, uint64_t exit_info_1) @@ -5224,20 +5219,11 @@ void helper_vmexit(uint32_t exit_code, uint64_t exit_info_1)
5224 env->cr[8] = ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.cr8)); 5219 env->cr[8] = ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.cr8));
5225 cpu_set_apic_tpr(env, env->cr[8]); 5220 cpu_set_apic_tpr(env, env->cr[8]);
5226 } 5221 }
5227 - /* we need to set the efer after the crs so the hidden flags get set properly */ 5222 + /* we need to set the efer after the crs so the hidden flags get
  5223 + set properly */
5228 #ifdef TARGET_X86_64 5224 #ifdef TARGET_X86_64
5229 - env->efer = ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.efer));  
5230 - env->hflags &= ~HF_LMA_MASK;  
5231 - if (env->efer & MSR_EFER_LMA)  
5232 - env->hflags |= HF_LMA_MASK;  
5233 - /* XXX: should also emulate the VM_CR MSR */  
5234 - env->hflags &= ~HF_SVME_MASK;  
5235 - if (env->cpuid_ext3_features & CPUID_EXT3_SVM) {  
5236 - if (env->efer & MSR_EFER_SVME)  
5237 - env->hflags |= HF_SVME_MASK;  
5238 - } else {  
5239 - env->efer &= ~MSR_EFER_SVME;  
5240 - } 5225 + cpu_load_efer(env,
  5226 + ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.efer)));
5241 #endif 5227 #endif
5242 5228
5243 env->eflags = 0; 5229 env->eflags = 0;