diff options
author | Lara Lazier <laramglazier@gmail.com> | 2021-06-16 14:39:06 +0200 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2021-06-16 15:02:40 +0200 |
commit | 498df2a7470e09d6cb0204f45eeb30d7ae796465 (patch) | |
tree | e4a300fa50d9589d9a0a9b92bc88a3c30639cef8 /target/i386/tcg/sysemu/svm_helper.c | |
parent | 7eb54ca95d369135f2570c10daf1a41a1f8a6b9c (diff) |
target/i386: Added consistency checks for CR0
The combination of unset CD and set NW bit in CR0 is illegal.
CR0[63:32] are also reserved and need to be zero.
(AMD64 Architecture Programmer's Manual, V2, 15.5)
Signed-off-by: Lara Lazier <laramglazier@gmail.com>
Message-Id: <20210616123907.17765-4-laramglazier@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'target/i386/tcg/sysemu/svm_helper.c')
-rw-r--r-- | target/i386/tcg/sysemu/svm_helper.c | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/target/i386/tcg/sysemu/svm_helper.c b/target/i386/tcg/sysemu/svm_helper.c index 902bf03fc3..1c2dbc1862 100644 --- a/target/i386/tcg/sysemu/svm_helper.c +++ b/target/i386/tcg/sysemu/svm_helper.c @@ -73,6 +73,7 @@ void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend) uint32_t event_inj; uint32_t int_ctl; uint32_t asid; + uint64_t new_cr0; cpu_svm_check_intercept_param(env, SVM_EXIT_VMRUN, 0, GETPC()); @@ -192,13 +193,18 @@ void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend) env->idt.limit = x86_ldl_phys(cs, env->vm_vmcb + offsetof(struct vmcb, save.idtr.limit)); + new_cr0 = x86_ldq_phys(cs, env->vm_vmcb + offsetof(struct vmcb, save.cr0)); + if (new_cr0 & SVM_CR0_RESERVED_MASK) { + cpu_vmexit(env, SVM_EXIT_ERR, 0, GETPC()); + } + if ((new_cr0 & CR0_NW_MASK) && !(new_cr0 & CR0_CD_MASK)) { + cpu_vmexit(env, SVM_EXIT_ERR, 0, GETPC()); + } /* clear exit_info_2 so we behave like the real hardware */ x86_stq_phys(cs, env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2), 0); - cpu_x86_update_cr0(env, x86_ldq_phys(cs, - env->vm_vmcb + offsetof(struct vmcb, - save.cr0))); + cpu_x86_update_cr0(env, new_cr0); cpu_x86_update_cr4(env, x86_ldq_phys(cs, env->vm_vmcb + offsetof(struct vmcb, save.cr4))); |