~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/x86/include/asm/pvclock.h

Version: ~ [ linux-5.8-rc4 ] ~ [ linux-5.7.7 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.50 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.131 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.187 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.229 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.229 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.85 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 #ifndef _ASM_X86_PVCLOCK_H
  2 #define _ASM_X86_PVCLOCK_H
  3 
  4 #include <linux/clocksource.h>
  5 #include <asm/pvclock-abi.h>
  6 
  7 /* some helper functions for xen and kvm pv clock sources */
  8 cycle_t pvclock_clocksource_read(struct pvclock_vcpu_time_info *src);
  9 u8 pvclock_read_flags(struct pvclock_vcpu_time_info *src);
 10 void pvclock_set_flags(u8 flags);
 11 unsigned long pvclock_tsc_khz(struct pvclock_vcpu_time_info *src);
 12 void pvclock_read_wallclock(struct pvclock_wall_clock *wall,
 13                             struct pvclock_vcpu_time_info *vcpu,
 14                             struct timespec *ts);
 15 void pvclock_resume(void);
 16 
 17 void pvclock_touch_watchdogs(void);
 18 
 19 /*
 20  * Scale a 64-bit delta by scaling and multiplying by a 32-bit fraction,
 21  * yielding a 64-bit result.
 22  */
 23 static inline u64 pvclock_scale_delta(u64 delta, u32 mul_frac, int shift)
 24 {
 25         u64 product;
 26 #ifdef __i386__
 27         u32 tmp1, tmp2;
 28 #else
 29         ulong tmp;
 30 #endif
 31 
 32         if (shift < 0)
 33                 delta >>= -shift;
 34         else
 35                 delta <<= shift;
 36 
 37 #ifdef __i386__
 38         __asm__ (
 39                 "mul  %5       ; "
 40                 "mov  %4,%%eax ; "
 41                 "mov  %%edx,%4 ; "
 42                 "mul  %5       ; "
 43                 "xor  %5,%5    ; "
 44                 "add  %4,%%eax ; "
 45                 "adc  %5,%%edx ; "
 46                 : "=A" (product), "=r" (tmp1), "=r" (tmp2)
 47                 : "a" ((u32)delta), "1" ((u32)(delta >> 32)), "2" (mul_frac) );
 48 #elif defined(__x86_64__)
 49         __asm__ (
 50                 "mulq %[mul_frac] ; shrd $32, %[hi], %[lo]"
 51                 : [lo]"=a"(product),
 52                   [hi]"=d"(tmp)
 53                 : ""(delta),
 54                   [mul_frac]"rm"((u64)mul_frac));
 55 #else
 56 #error implement me!
 57 #endif
 58 
 59         return product;
 60 }
 61 
 62 static __always_inline
 63 u64 pvclock_get_nsec_offset(const struct pvclock_vcpu_time_info *src)
 64 {
 65         u64 delta = __native_read_tsc() - src->tsc_timestamp;
 66         return pvclock_scale_delta(delta, src->tsc_to_system_mul,
 67                                    src->tsc_shift);
 68 }
 69 
 70 static __always_inline
 71 unsigned __pvclock_read_cycles(const struct pvclock_vcpu_time_info *src,
 72                                cycle_t *cycles, u8 *flags)
 73 {
 74         unsigned version;
 75         cycle_t ret, offset;
 76         u8 ret_flags;
 77 
 78         version = src->version;
 79         /* Note: emulated platforms which do not advertise SSE2 support
 80          * result in kvmclock not using the necessary RDTSC barriers.
 81          * Without barriers, it is possible that RDTSC instruction reads from
 82          * the time stamp counter outside rdtsc_barrier protected section
 83          * below, resulting in violation of monotonicity.
 84          */
 85         rdtsc_barrier();
 86         offset = pvclock_get_nsec_offset(src);
 87         ret = src->system_time + offset;
 88         ret_flags = src->flags;
 89         rdtsc_barrier();
 90 
 91         *cycles = ret;
 92         *flags = ret_flags;
 93         return version;
 94 }
 95 
 96 struct pvclock_vsyscall_time_info {
 97         struct pvclock_vcpu_time_info pvti;
 98 } __attribute__((__aligned__(SMP_CACHE_BYTES)));
 99 
100 #define PVTI_SIZE sizeof(struct pvclock_vsyscall_time_info)
101 #define PVCLOCK_VSYSCALL_NR_PAGES (((NR_CPUS-1)/(PAGE_SIZE/PVTI_SIZE))+1)
102 
103 int __init pvclock_init_vsyscall(struct pvclock_vsyscall_time_info *i,
104                                  int size);
105 struct pvclock_vcpu_time_info *pvclock_get_vsyscall_time_info(int cpu);
106 
107 #endif /* _ASM_X86_PVCLOCK_H */
108 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp