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; | ... | ... |