Commit 5efc27bbb695017a7386cb9acef247b9dd29f2b6
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
Showing
3 changed files
with
24 additions
and
27 deletions
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; | ... | ... |