[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH] rdtsc hypercall



Implement hypercall for rdtsc.  This provides a better
performing alternative for guests for which rdtsc emulation
is enabled (which may soon be the default).  Three forms:

1) Read the raw physical cpu TSC
2) Read monotonically-increasing Xen system time (nsec since
   guest boot)
3) Determine if rdtsc emulation is enabled for this guest

Form 3 can be used (once) to determine if rdtsc emulation
is enabled.  If it is not, the normal pvclock algorithm
can be used as if it can be done in a vsyscall (in user
space) it is, by far, the fastest.  If it is, form 1 can
be used to avoid the trap from rdtsc; or form 2 can be
used directly as it should return the same result as
applying the pvclock algorithm to the value returned by
Form 1 EXCEPT form 2 enforces monotonicity.

Signed-off-by: Dan Magenheimer <dan.magenheimer@xxxxxxxxxx>

--- a/xen/arch/x86/time.c       Wed Sep 09 16:39:41 2009 +0100
+++ b/xen/arch/x86/time.c       Fri Sep 11 09:52:18 2009 -0600
@@ -22,6 +22,7 @@
 #include <xen/irq.h>
 #include <xen/softirq.h>
 #include <xen/keyhandler.h>
+#include <public/xen.h>
 #include <asm/io.h>
 #include <asm/msr.h>
 #include <asm/mpspec.h>
@@ -1435,6 +1436,43 @@ struct tm wallclock_time(void)
 
 
 /*
+ * rdtsc hypercall
+ */
+
+#ifdef __x86_64__
+uint64_t do_rdtsc_op(unsigned long subop)
+{
+    struct vcpu *v = current;
+    unsigned long eax, edx;
+    s_time_t now = 0;
+
+    BUG_ON(is_pv_32on64_vcpu(v));
+    switch (subop)
+    {
+    case RDTSC_READ_XEN_TSC:
+
+        spin_lock(&v->domain->arch.vtsc_lock);
+        now = get_s_time() + v->domain->arch.vtsc_stime_offset;
+        if ( (int64_t)(now - v->domain->arch.vtsc_last) > 0 )
+            v->domain->arch.vtsc_last = now;
+        else
+            now = ++v->domain->arch.vtsc_last;
+        spin_unlock(&v->domain->arch.vtsc_lock);
+        break;
+    case RDTSC_READ_RAW_TSC:
+        rdtsc(eax, edx);
+        now = ((uint64_t)edx << 32) | (uint32_t)eax;
+        break;
+    case RDTSC_IS_EMULATED:
+        now = v->domain->arch.vtsc ? 1 : 0;
+        break;
+    }
+    return now;
+}
+#endif
+
+
+/*
  * PV SoftTSC Emulation.
  */
 
diff -r d2a32e24fe50 xen/arch/x86/x86_32/entry.S
--- a/xen/arch/x86/x86_32/entry.S       Wed Sep 09 16:39:41 2009 +0100
+++ b/xen/arch/x86/x86_32/entry.S       Fri Sep 11 09:52:18 2009 -0600
@@ -704,6 +704,7 @@ ENTRY(hypercall_table)
         .long do_domctl
         .long do_kexec_op
         .long do_tmem_op
+        .long do_ni_hypercall       /* reserved for x86_64 do_rdtsc_op */
         .rept __HYPERVISOR_arch_0-((.-hypercall_table)/4)
         .long do_ni_hypercall
         .endr
@@ -752,6 +753,7 @@ ENTRY(hypercall_args_table)
         .byte 1 /* do_domctl            */
         .byte 2 /* do_kexec_op          */
         .byte 1 /* do_tmem_op           */
+        .byte 0 /* x86_64-only do_rdtsc_op */
         .rept __HYPERVISOR_arch_0-(.-hypercall_args_table)
         .byte 0 /* do_ni_hypercall      */
         .endr
diff -r d2a32e24fe50 xen/arch/x86/x86_64/compat/entry.S
--- a/xen/arch/x86/x86_64/compat/entry.S        Wed Sep 09 16:39:41 2009 +0100
+++ b/xen/arch/x86/x86_64/compat/entry.S        Fri Sep 11 09:52:18 2009 -0600
@@ -409,6 +409,7 @@ ENTRY(compat_hypercall_table)
         .quad do_domctl
         .quad compat_kexec_op
         .quad do_tmem_op
+        .quad compat_ni_hypercall       /* reserved for x86_64 do_rdtsc_op */
         .rept __HYPERVISOR_arch_0-((.-compat_hypercall_table)/8)
         .quad compat_ni_hypercall
         .endr
@@ -457,6 +458,7 @@ ENTRY(compat_hypercall_args_table)
         .byte 1 /* do_domctl                */
         .byte 2 /* compat_kexec_op          */
         .byte 1 /* do_tmem_op               */
+        .byte 0 /* x86_64-only do_rdtsc_op  */
         .rept __HYPERVISOR_arch_0-(.-compat_hypercall_args_table)
         .byte 0 /* compat_ni_hypercall      */
         .endr
diff -r d2a32e24fe50 xen/arch/x86/x86_64/entry.S
--- a/xen/arch/x86/x86_64/entry.S       Wed Sep 09 16:39:41 2009 +0100
+++ b/xen/arch/x86/x86_64/entry.S       Fri Sep 11 09:52:18 2009 -0600
@@ -693,6 +693,7 @@ ENTRY(hypercall_table)
         .quad do_domctl
         .quad do_kexec_op
         .quad do_tmem_op
+        .quad do_rdtsc_op
         .rept __HYPERVISOR_arch_0-((.-hypercall_table)/8)
         .quad do_ni_hypercall
         .endr
@@ -741,6 +742,7 @@ ENTRY(hypercall_args_table)
         .byte 1 /* do_domctl            */
         .byte 2 /* do_kexec             */
         .byte 1 /* do_tmem_op           */
+        .byte 1 /* do_rdtsc             */
         .rept __HYPERVISOR_arch_0-(.-hypercall_args_table)
         .byte 0 /* do_ni_hypercall      */
         .endr
diff -r d2a32e24fe50 xen/include/public/xen.h
--- a/xen/include/public/xen.h  Wed Sep 09 16:39:41 2009 +0100
+++ b/xen/include/public/xen.h  Fri Sep 11 09:52:18 2009 -0600
@@ -92,6 +92,7 @@ DEFINE_XEN_GUEST_HANDLE(xen_pfn_t);
 #define __HYPERVISOR_domctl               36
 #define __HYPERVISOR_kexec_op             37
 #define __HYPERVISOR_tmem_op              38
+#define __HYPERVISOR_rdtsc_op             39 /* x86/64 only */
 
 /* Architecture-specific hypercall definitions. */
 #define __HYPERVISOR_arch_0               48
@@ -333,6 +334,17 @@ DEFINE_XEN_GUEST_HANDLE(mmuext_op_t);
 #define VMASST_TYPE_pae_extended_cr3     3
 
 #define MAX_VMASST_TYPE                  3
+
+/*
+ * Commands to HYPERVISOR_rdtsc_op() (x86/64 only)
+ */
+
+/* read raw physical cpu TSC value (approx 2-3x faster than trap/emulate) */
+#define RDTSC_READ_RAW_TSC               0
+/* read monotonically-increasing Xen system time (nsec since guest boot) */
+#define RDTSC_READ_XEN_TSC               1
+/* is rdtsc emulation enabled for this guest? */
+#define RDTSC_IS_EMULATED                2
 
 #ifndef __ASSEMBLY__

Attachment: hyp-rdtsc-090911.patch
Description: Binary data

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.