aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/svm.c
diff options
context:
space:
mode:
authorAndre Przywara <andre.przywara@amd.com>2010-12-21 05:12:05 -0500
committerAvi Kivity <avi@redhat.com>2011-01-12 04:31:04 -0500
commitcae3797a4639898f339fad57c7e12d270ec91a6c (patch)
tree78f27fdcbf6c08298f40224c487803753dce3bc3 /arch/x86/kvm/svm.c
parent7ff76d58a9dc03a38b86d283abcaae2ac3c74fe3 (diff)
KVM: SVM: enhance mov DR intercept handler
Newer SVM implementations provide the GPR number in the VMCB, so that the emulation path is no longer necesarry to handle debug register access intercepts. Implement the handling in svm.c and use it when the info is provided. Signed-off-by: Andre Przywara <andre.przywara@amd.com> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
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,