aboutsummaryrefslogtreecommitdiff
path: root/target/i386/tcg/sysemu/svm_helper.c
diff options
context:
space:
mode:
authorLara Lazier <laramglazier@gmail.com>2021-06-16 14:39:06 +0200
committerPaolo Bonzini <pbonzini@redhat.com>2021-06-16 15:02:40 +0200
commit498df2a7470e09d6cb0204f45eeb30d7ae796465 (patch)
treee4a300fa50d9589d9a0a9b92bc88a3c30639cef8 /target/i386/tcg/sysemu/svm_helper.c
parent7eb54ca95d369135f2570c10daf1a41a1f8a6b9c (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.c12
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)));