Skip to content

Commit cae3797

Browse files
aprzywaravikivity
authored andcommitted
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 <[email protected]> Signed-off-by: Marcelo Tosatti <[email protected]>
1 parent 7ff76d5 commit cae3797

File tree

1 file changed

+40
-16
lines changed

1 file changed

+40
-16
lines changed

arch/x86/kvm/svm.c

Lines changed: 40 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2745,6 +2745,30 @@ static int cr0_write_interception(struct vcpu_svm *svm)
27452745
return r;
27462746
}
27472747

2748+
static 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+
27482772
static int cr8_write_interception(struct vcpu_svm *svm)
27492773
{
27502774
struct kvm_run *kvm_run = svm->vcpu.run;
@@ -3010,22 +3034,22 @@ static int (*svm_exit_handlers[])(struct vcpu_svm *svm) = {
30103034
[SVM_EXIT_WRITE_CR3] = cr_interception,
30113035
[SVM_EXIT_WRITE_CR4] = cr_interception,
30123036
[SVM_EXIT_WRITE_CR8] = cr8_write_interception,
3013-
[SVM_EXIT_READ_DR0] = emulate_on_interception,
3014-
[SVM_EXIT_READ_DR1] = emulate_on_interception,
3015-
[SVM_EXIT_READ_DR2] = emulate_on_interception,
3016-
[SVM_EXIT_READ_DR3] = emulate_on_interception,
3017-
[SVM_EXIT_READ_DR4] = emulate_on_interception,
3018-
[SVM_EXIT_READ_DR5] = emulate_on_interception,
3019-
[SVM_EXIT_READ_DR6] = emulate_on_interception,
3020-
[SVM_EXIT_READ_DR7] = emulate_on_interception,
3021-
[SVM_EXIT_WRITE_DR0] = emulate_on_interception,
3022-
[SVM_EXIT_WRITE_DR1] = emulate_on_interception,
3023-
[SVM_EXIT_WRITE_DR2] = emulate_on_interception,
3024-
[SVM_EXIT_WRITE_DR3] = emulate_on_interception,
3025-
[SVM_EXIT_WRITE_DR4] = emulate_on_interception,
3026-
[SVM_EXIT_WRITE_DR5] = emulate_on_interception,
3027-
[SVM_EXIT_WRITE_DR6] = emulate_on_interception,
3028-
[SVM_EXIT_WRITE_DR7] = emulate_on_interception,
3037+
[SVM_EXIT_READ_DR0] = dr_interception,
3038+
[SVM_EXIT_READ_DR1] = dr_interception,
3039+
[SVM_EXIT_READ_DR2] = dr_interception,
3040+
[SVM_EXIT_READ_DR3] = dr_interception,
3041+
[SVM_EXIT_READ_DR4] = dr_interception,
3042+
[SVM_EXIT_READ_DR5] = dr_interception,
3043+
[SVM_EXIT_READ_DR6] = dr_interception,
3044+
[SVM_EXIT_READ_DR7] = dr_interception,
3045+
[SVM_EXIT_WRITE_DR0] = dr_interception,
3046+
[SVM_EXIT_WRITE_DR1] = dr_interception,
3047+
[SVM_EXIT_WRITE_DR2] = dr_interception,
3048+
[SVM_EXIT_WRITE_DR3] = dr_interception,
3049+
[SVM_EXIT_WRITE_DR4] = dr_interception,
3050+
[SVM_EXIT_WRITE_DR5] = dr_interception,
3051+
[SVM_EXIT_WRITE_DR6] = dr_interception,
3052+
[SVM_EXIT_WRITE_DR7] = dr_interception,
30293053
[SVM_EXIT_EXCP_BASE + DB_VECTOR] = db_interception,
30303054
[SVM_EXIT_EXCP_BASE + BP_VECTOR] = bp_interception,
30313055
[SVM_EXIT_EXCP_BASE + UD_VECTOR] = ud_interception,

0 commit comments

Comments
 (0)