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 148 #define HF_GIF_SHIFT 20 /* if set CPU takes interrupts */
149 149 #define HF_HIF_SHIFT 21 /* shadow copy of IF_MASK when in SVM */
150 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 152 #define HF_SVMI_SHIFT 24 /* SVM intercepts are active */
153 153  
154 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 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 1435 /* init SMM cpu state */
1436 1436  
1437 1437 #ifdef TARGET_X86_64
1438   - env->efer = 0;
1439   - env->hflags &= ~HF_LMA_MASK;
  1438 + cpu_load_efer(env, 0);
1440 1439 #endif
1441 1440 load_eflags(0, ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK));
1442 1441 env->eip = 0x00008000;
... ... @@ -1463,11 +1462,7 @@ void helper_rsm(void)
1463 1462  
1464 1463 sm_state = env->smbase + 0x8000;
1465 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 1467 for(i = 0; i < 6; i++) {
1473 1468 offset = 0x7e00 + i * 16;
... ... @@ -3069,8 +3064,10 @@ void helper_wrmsr(void)
3069 3064 update_mask |= MSR_EFER_FFXSR;
3070 3065 if (env->cpuid_ext2_features & CPUID_EXT2_NX)
3071 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 3072 break;
3076 3073 case MSR_STAR:
... ... @@ -4873,10 +4870,8 @@ void helper_vmrun(void)
4873 4870 }
4874 4871  
4875 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 4875 #endif
4881 4876 env->eflags = 0;
4882 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 5219 env->cr[8] = ldq_phys(env->vm_hsave + offsetof(struct vmcb, save.cr8));
5225 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 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 5227 #endif
5242 5228  
5243 5229 env->eflags = 0;
... ...