Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=4e87173eacfd0d798aeeba14026893797826bc93
Commit:     4e87173eacfd0d798aeeba14026893797826bc93
Parent:     16e2011be67b8625c1c600f9742c2279be3c0c68
Author:     Glauber de Oliveira Costa <[EMAIL PROTECTED]>
AuthorDate: Wed Jan 30 13:31:03 2008 +0100
Committer:  Ingo Molnar <[EMAIL PROTECTED]>
CommitDate: Wed Jan 30 13:31:03 2008 +0100

    x86: split get_cycles_sync
    
    This patch splits get_cycles_sync() into  __get_cycles_sync(),
    and the rdtscll part. Paravirt guests cannot issue rdtscl directly,
    as it involves a function call in vdso area.
    
    So, using the __get_cycles_sync() base, we introduce vget_cycles_sync,
    which then calls the native version of rdtscll. Ideally, however, a guest
    should define its own clocksource, together with a vread function
    
    Signed-off-by: Glauber de Oliveira Costa <[EMAIL PROTECTED]>
    Signed-off-by: Ingo Molnar <[EMAIL PROTECTED]>
    Signed-off-by: Thomas Gleixner <[EMAIL PROTECTED]>
---
 arch/x86/kernel/tsc_64.c |    2 +-
 include/asm-x86/tsc.h    |   37 +++++++++++++++++++++++++++++++++----
 2 files changed, 34 insertions(+), 5 deletions(-)

diff --git a/arch/x86/kernel/tsc_64.c b/arch/x86/kernel/tsc_64.c
index 204a908..3723401 100644
--- a/arch/x86/kernel/tsc_64.c
+++ b/arch/x86/kernel/tsc_64.c
@@ -306,7 +306,7 @@ static cycle_t read_tsc(void)
 
 static cycle_t __vsyscall_fn vread_tsc(void)
 {
-       cycle_t ret = (cycle_t)get_cycles_sync();
+       cycle_t ret = (cycle_t)vget_cycles_sync();
        return ret;
 }
 
diff --git a/include/asm-x86/tsc.h b/include/asm-x86/tsc.h
index d7b1c4e..9b7d264 100644
--- a/include/asm-x86/tsc.h
+++ b/include/asm-x86/tsc.h
@@ -33,14 +33,14 @@ static inline cycles_t get_cycles(void)
 }
 
 /* Like get_cycles, but make sure the CPU is synchronized. */
-static __always_inline cycles_t get_cycles_sync(void)
+static __always_inline cycles_t __get_cycles_sync(void)
 {
        unsigned long long ret;
        unsigned eax, edx;
 
        /*
-        * Use RDTSCP if possible; it is guaranteed to be synchronous
-        * and doesn't cause a VMEXIT on Hypervisors
+        * Use RDTSCP if possible; it is guaranteed to be synchronous
+        * and doesn't cause a VMEXIT on Hypervisors
         */
        alternative_io(ASM_NOP3, ".byte 0x0f,0x01,0xf9", X86_FEATURE_RDTSCP,
                       ASM_OUTPUT2("=a" (eax), "=d" (edx)),
@@ -55,11 +55,40 @@ static __always_inline cycles_t get_cycles_sync(void)
         */
        alternative_io("cpuid", ASM_NOP2, X86_FEATURE_SYNC_RDTSC,
                          "=a" (eax), "0" (1) : "ebx","ecx","edx","memory");
-       rdtscll(ret);
 
+       return 0;
+}
+
+static __always_inline cycles_t get_cycles_sync(void)
+{
+       unsigned long long ret;
+       ret = __get_cycles_sync();
+       if (!ret)
+               rdtscll(ret);
        return ret;
 }
 
+#ifdef CONFIG_PARAVIRT
+/*
+ * For paravirt guests, some functionalities are executed through function
+ * pointers in the various pvops structures.
+ * These function pointers exist inside the kernel and can not
+ * be accessed by user space. To avoid this, we make a copy of the
+ * get_cycles_sync (called in kernel) but force the use of native_read_tsc.
+ * Ideally, the guest should set up it's own clock and vread
+ */
+static __always_inline long long vget_cycles_sync(void)
+{
+       unsigned long long ret;
+       ret = __get_cycles_sync();
+       if (!ret)
+               ret = native_read_tsc();
+       return ret;
+}
+#else
+# define vget_cycles_sync() get_cycles_sync()
+#endif
+
 extern void tsc_init(void);
 extern void mark_tsc_unstable(char *reason);
 extern int unsynchronized_tsc(void);
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to