[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 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |