aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/svm.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kvm/svm.c')
-rw-r--r--arch/x86/kvm/svm.c56
1 files changed, 40 insertions, 16 deletions
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 5abaa5b2f624..d84f6a7c2bc5 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -2745,6 +2745,30 @@ static int cr0_write_interception(struct vcpu_svm *svm)
2745 return r; 2745 return r;
2746} 2746}
2747 2747
2748static int dr_interception(struct vcpu_svm *svm)
2749{
2750 int reg, dr;
2751 unsigned long val;
2752 int err;
2753
2754 if (!boot_cpu_has(X86_FEATURE_DECODEASSISTS))
2755 return emulate_on_interception(svm);
2756
2757 reg = svm->vmcb->control.exit_info_1 & SVM_EXITINFO_REG_MASK;
2758 dr = svm->vmcb->control.exit_code - SVM_EXIT_READ_DR0;
2759
2760 if (dr >= 16) { /* mov to DRn */
2761 val = kvm_register_read(&svm->vcpu, reg);
2762 kvm_set_dr(&svm->vcpu, dr - 16, val);
2763 } else {
2764 err = kvm_get_dr(&svm->vcpu, dr, &val);
2765 if (!err)
2766 kvm_register_write(&svm->vcpu, reg, val);
2767 }
2768
2769 return 1;
2770}
2771
2748static int cr8_write_interception(struct vcpu_svm *svm) 2772static int cr8_write_interception(struct vcpu_svm *svm)
2749{ 2773{
2750 struct kvm_run *kvm_run = svm->vcpu.run; 2774 struct kvm_run *kvm_run = svm->vcpu.run;
@@ -3010,22 +3034,22 @@ static int (*svm_exit_handlers[])(struct vcpu_svm *svm) = {
3010 [SVM_EXIT_WRITE_CR3] = cr_interception, 3034 [SVM_EXIT_WRITE_CR3] = cr_interception,
3011 [SVM_EXIT_WRITE_CR4] = cr_interception, 3035 [SVM_EXIT_WRITE_CR4] = cr_interception,
3012 [SVM_EXIT_WRITE_CR8] = cr8_write_interception, 3036 [SVM_EXIT_WRITE_CR8] = cr8_write_interception,
3013 [SVM_EXIT_READ_DR0] = emulate_on_interception, 3037 [SVM_EXIT_READ_DR0] = dr_interception,
3014 [SVM_EXIT_READ_DR1] = emulate_on_interception, 3038 [SVM_EXIT_READ_DR1] = dr_interception,
3015 [SVM_EXIT_READ_DR2] = emulate_on_interception, 3039 [SVM_EXIT_READ_DR2] = dr_interception,
3016 [SVM_EXIT_READ_DR3] = emulate_on_interception, 3040 [SVM_EXIT_READ_DR3] = dr_interception,
3017 [SVM_EXIT_READ_DR4] = emulate_on_interception, 3041 [SVM_EXIT_READ_DR4] = dr_interception,
3018 [SVM_EXIT_READ_DR5] = emulate_on_interception, 3042 [SVM_EXIT_READ_DR5] = dr_interception,
3019 [SVM_EXIT_READ_DR6] = emulate_on_interception, 3043 [SVM_EXIT_READ_DR6] = dr_interception,
3020 [SVM_EXIT_READ_DR7] = emulate_on_interception, 3044 [SVM_EXIT_READ_DR7] = dr_interception,
3021 [SVM_EXIT_WRITE_DR0] = emulate_on_interception, 3045 [SVM_EXIT_WRITE_DR0] = dr_interception,
3022 [SVM_EXIT_WRITE_DR1] = emulate_on_interception, 3046 [SVM_EXIT_WRITE_DR1] = dr_interception,
3023 [SVM_EXIT_WRITE_DR2] = emulate_on_interception, 3047 [SVM_EXIT_WRITE_DR2] = dr_interception,
3024 [SVM_EXIT_WRITE_DR3] = emulate_on_interception, 3048 [SVM_EXIT_WRITE_DR3] = dr_interception,
3025 [SVM_EXIT_WRITE_DR4] = emulate_on_interception, 3049 [SVM_EXIT_WRITE_DR4] = dr_interception,
3026 [SVM_EXIT_WRITE_DR5] = emulate_on_interception, 3050 [SVM_EXIT_WRITE_DR5] = dr_interception,
3027 [SVM_EXIT_WRITE_DR6] = emulate_on_interception, 3051 [SVM_EXIT_WRITE_DR6] = dr_interception,
3028 [SVM_EXIT_WRITE_DR7] = emulate_on_interception, 3052 [SVM_EXIT_WRITE_DR7] = dr_interception,
3029 [SVM_EXIT_EXCP_BASE + DB_VECTOR] = db_interception, 3053 [SVM_EXIT_EXCP_BASE + DB_VECTOR] = db_interception,
3030 [SVM_EXIT_EXCP_BASE + BP_VECTOR] = bp_interception, 3054 [SVM_EXIT_EXCP_BASE + BP_VECTOR] = bp_interception,
3031 [SVM_EXIT_EXCP_BASE + UD_VECTOR] = ud_interception, 3055 [SVM_EXIT_EXCP_BASE + UD_VECTOR] = ud_interception,