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

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

Version: ~ [ linux-5.15-rc1 ] ~ [ linux-5.14.5 ] ~ [ linux-5.13.18 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.66 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.147 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.206 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.246 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.282 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.283 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.18.140 ] ~ [ linux-3.16.85 ] ~ [ linux-3.14.79 ] ~ [ linux-3.12.74 ] ~ [ 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 #ifdef CONFIG_PARAVIRT_CLOCK
  8 extern struct pvclock_vsyscall_time_info *pvclock_pvti_cpu0_va(void);
  9 #else
 10 static inline struct pvclock_vsyscall_time_info *pvclock_pvti_cpu0_va(void)
 11 {
 12         return NULL;
 13 }
 14 #endif
 15 
 16 /* some helper functions for xen and kvm pv clock sources */
 17 cycle_t pvclock_clocksource_read(struct pvclock_vcpu_time_info *src);
 18 u8 pvclock_read_flags(struct pvclock_vcpu_time_info *src);
 19 void pvclock_set_flags(u8 flags);
 20 unsigned long pvclock_tsc_khz(struct pvclock_vcpu_time_info *src);
 21 void pvclock_read_wallclock(struct pvclock_wall_clock *wall,
 22                             struct pvclock_vcpu_time_info *vcpu,
 23                             struct timespec *ts);
 24 void pvclock_resume(void);
 25 
 26 void pvclock_touch_watchdogs(void);
 27 
 28 /*
 29  * Scale a 64-bit delta by scaling and multiplying by a 32-bit fraction,
 30  * yielding a 64-bit result.
 31  */
 32 static inline u64 pvclock_scale_delta(u64 delta, u32 mul_frac, int shift)
 33 {
 34         u64 product;
 35 #ifdef __i386__
 36         u32 tmp1, tmp2;
 37 #else
 38         ulong tmp;
 39 #endif
 40 
 41         if (shift < 0)
 42                 delta >>= -shift;
 43         else
 44                 delta <<= shift;
 45 
 46 #ifdef __i386__
 47         __asm__ (
 48                 "mul  %5       ; "
 49                 "mov  %4,%%eax ; "
 50                 "mov  %%edx,%4 ; "
 51                 "mul  %5       ; "
 52                 "xor  %5,%5    ; "
 53                 "add  %4,%%eax ; "
 54                 "adc  %5,%%edx ; "
 55                 : "=A" (product), "=r" (tmp1), "=r" (tmp2)
 56                 : "a" ((u32)delta), "1" ((u32)(delta >> 32)), "2" (mul_frac) );
 57 #elif defined(__x86_64__)
 58         __asm__ (
 59                 "mulq %[mul_frac] ; shrd $32, %[hi], %[lo]"
 60                 : [lo]"=a"(product),
 61                   [hi]"=d"(tmp)
 62                 : ""(delta),
 63                   [mul_frac]"rm"((u64)mul_frac));
 64 #else
 65 #error implement me!
 66 #endif
 67 
 68         return product;
 69 }
 70 
 71 static __always_inline
 72 u64 pvclock_get_nsec_offset(const struct pvclock_vcpu_time_info *src)
 73 {
 74         u64 delta = __native_read_tsc() - src->tsc_timestamp;
 75         return pvclock_scale_delta(delta, src->tsc_to_system_mul,
 76                                    src->tsc_shift);
 77 }
 78 
 79 static __always_inline
 80 unsigned __pvclock_read_cycles(const struct pvclock_vcpu_time_info *src,
 81                                cycle_t *cycles, u8 *flags)
 82 {
 83         unsigned version;
 84         cycle_t ret, offset;
 85         u8 ret_flags;
 86 
 87         version = src->version;
 88         /* Note: emulated platforms which do not advertise SSE2 support
 89          * result in kvmclock not using the necessary RDTSC barriers.
 90          * Without barriers, it is possible that RDTSC instruction reads from
 91          * the time stamp counter outside rdtsc_barrier protected section
 92          * below, resulting in violation of monotonicity.
 93          */
 94         rdtsc_barrier();
 95         offset = pvclock_get_nsec_offset(src);
 96         ret = src->system_time + offset;
 97         ret_flags = src->flags;
 98         rdtsc_barrier();
 99 
100         *cycles = ret;
101         *flags = ret_flags;
102         return version;
103 }
104 
105 struct pvclock_vsyscall_time_info {
106         struct pvclock_vcpu_time_info pvti;
107 } __attribute__((__aligned__(SMP_CACHE_BYTES)));
108 
109 #define PVTI_SIZE sizeof(struct pvclock_vsyscall_time_info)
110 
111 #endif /* _ASM_X86_PVCLOCK_H */
112 

~ [ 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