From: Avi Kivity <[EMAIL PROTECTED]> this adds support for enabling and disabling the tpr access reporting facility, as well as a callback that is triggered whenever the tpr is accessed.
Signed-off-by: Avi Kivity <[EMAIL PROTECTED]> diff --git a/libkvm/kvm-x86.h b/libkvm/kvm-x86.h index 0769bb5..1dccf64 100644 --- a/libkvm/kvm-x86.h +++ b/libkvm/kvm-x86.h @@ -25,4 +25,29 @@ int kvm_set_tss_addr(kvm_context_t kvm, unsigned long addr); +#ifdef KVM_CAP_VAPIC + +/*! + * \brief Enable kernel tpr access reporting + * + * When tpr access reporting is enabled, the kernel will call the + * ->tpr_access() callback every time the guest vcpu accesses the tpr. + * + * \param kvm Pointer to the current kvm_context + * \param vcpu vcpu to enable tpr access reporting on + */ +int kvm_enable_tpr_access_reporting(kvm_context_t kvm, int vcpu); + +/*! + * \brief Disable kernel tpr access reporting + * + * Undoes the effect of kvm_enable_tpr_access_reporting(). + * + * \param kvm Pointer to the current kvm_context + * \param vcpu vcpu to disable tpr access reporting on + */ +int kvm_disable_tpr_access_reporting(kvm_context_t kvm, int vcpu); + +#endif + #endif diff --git a/libkvm/libkvm-x86.c b/libkvm/libkvm-x86.c index ca56adb..e6eb66e 100644 --- a/libkvm/libkvm-x86.c +++ b/libkvm/libkvm-x86.c @@ -157,6 +157,34 @@ int kvm_arch_create(kvm_context_t kvm, unsigned long phys_mem_bytes, return 0; } +#ifdef KVM_EXIT_TPR_ACCESS + +static int handle_tpr_access(kvm_context_t kvm, struct kvm_run *run, int vcpu) +{ + return kvm->callbacks->tpr_access(kvm->opaque, vcpu, + run->tpr_access.rip, + run->tpr_access.is_write); +} + + +int kvm_enable_vapic(kvm_context_t kvm, int vcpu, uint64_t vapic) +{ + int r; + struct kvm_vapic_addr va = { + .vapic_addr = vapic, + }; + + r = ioctl(kvm->vcpu_fd[vcpu], KVM_SET_VAPIC_ADDR, &va); + if (r == -1) { + r = -errno; + perror("kvm_enable_vapic"); + return r; + } + return 0; +} + +#endif + int kvm_arch_run(struct kvm_run *run,kvm_context_t kvm, int vcpu) { int r = 0; @@ -166,7 +194,11 @@ int kvm_arch_run(struct kvm_run *run,kvm_context_t kvm, int vcpu) case KVM_EXIT_SET_TPR: break; #endif - default: +#ifdef KVM_EXIT_TPR_ACCESS + case KVM_EXIT_TPR_ACCESS: + r = handle_tpr_access(kvm, run, vcpu); + break; +#endif default: r = 1; break; } @@ -502,3 +534,36 @@ int kvm_get_shadow_pages(kvm_context_t kvm, unsigned int *nrshadow_pages) #endif return -1; } + +#ifdef KVM_CAP_VAPIC + +static int tpr_access_reporting(kvm_context_t kvm, int vcpu, int enabled) +{ + int r; + struct kvm_tpr_access_ctl tac = { + .enabled = enabled, + }; + + r = ioctl(kvm->fd, KVM_CHECK_EXTENSION, KVM_CAP_VAPIC); + if (r == -1 || r == 0) + return -ENOSYS; + r = ioctl(kvm->vcpu_fd[vcpu], KVM_TPR_ACCESS_REPORTING, &tac); + if (r == -1) { + r = -errno; + perror("KVM_TPR_ACCESS_REPORTING"); + return r; + } + return 0; +} + +int kvm_enable_tpr_access_reporting(kvm_context_t kvm, int vcpu) +{ + return tpr_access_reporting(kvm, vcpu, 1); +} + +int kvm_disable_tpr_access_reporting(kvm_context_t kvm, int vcpu) +{ + return tpr_access_reporting(kvm, vcpu, 0); +} + +#endif diff --git a/libkvm/libkvm.h b/libkvm/libkvm.h index 62407f5..3aae6f6 100644 --- a/libkvm/libkvm.h +++ b/libkvm/libkvm.h @@ -64,6 +64,7 @@ struct kvm_callbacks { int (*try_push_interrupts)(void *opaque); void (*post_kvm_run)(void *opaque, int vcpu); int (*pre_kvm_run)(void *opaque, int vcpu); + int (*tpr_access)(void *opaque, int vcpu, uint64_t rip, int is_write); }; /*! @@ -524,4 +525,31 @@ int kvm_set_lapic(kvm_context_t kvm, int vcpu, struct kvm_lapic_state *s); #endif +#ifdef KVM_CAP_VAPIC + +/*! + * \brief Enable kernel tpr access reporting + * + * When tpr access reporting is enabled, the kernel will call the + * ->tpr_access() callback every time the guest vcpu accesses the tpr. + * + * \param kvm Pointer to the current kvm_context + * \param vcpu vcpu to enable tpr access reporting on + */ +int kvm_enable_tpr_access_reporting(kvm_context_t kvm, int vcpu); + +/*! + * \brief Disable kernel tpr access reporting + * + * Undoes the effect of kvm_enable_tpr_access_reporting(). + * + * \param kvm Pointer to the current kvm_context + * \param vcpu vcpu to disable tpr access reporting on + */ +int kvm_disable_tpr_access_reporting(kvm_context_t kvm, int vcpu); + +int kvm_enable_vapic(kvm_context_t kvm, int vcpu, uint64_t vapic); + +#endif + #endif ------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2005. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ _______________________________________________ kvm-commits mailing list kvm-commits@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-commits