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

Reply via email to