linux/arch/s390/kernel/vdso64/clock_gettime.S
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2/*
   3 * Userland implementation of clock_gettime() for 64 bits processes in a
   4 * s390 kernel for use in the vDSO
   5 *
   6 *  Copyright IBM Corp. 2008
   7 *  Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
   8 */
   9#include <asm/vdso.h>
  10#include <asm/asm-offsets.h>
  11#include <asm/unistd.h>
  12#include <asm/dwarf.h>
  13#include <asm/ptrace.h>
  14
  15        .text
  16        .align 4
  17        .globl __kernel_clock_gettime
  18        .type  __kernel_clock_gettime,@function
  19__kernel_clock_gettime:
  20        CFI_STARTPROC
  21        aghi    %r15,-16
  22        CFI_DEF_CFA_OFFSET STACK_FRAME_OVERHEAD+16
  23        CFI_VAL_OFFSET 15, -STACK_FRAME_OVERHEAD
  24        larl    %r5,_vdso_data
  25        cghi    %r2,__CLOCK_REALTIME_COARSE
  26        je      4f
  27        cghi    %r2,__CLOCK_REALTIME
  28        je      5f
  29        cghi    %r2,-3          /* Per-thread CPUCLOCK with PID=0, VIRT=1 */
  30        je      9f
  31        cghi    %r2,__CLOCK_MONOTONIC_COARSE
  32        je      3f
  33        cghi    %r2,__CLOCK_MONOTONIC
  34        jne     12f
  35
  36        /* CLOCK_MONOTONIC */
  370:      lg      %r4,__VDSO_UPD_COUNT(%r5)       /* load update counter */
  38        tmll    %r4,0x0001                      /* pending update ? loop */
  39        jnz     0b
  40        stcke   0(%r15)                         /* Store TOD clock */
  41        lgf     %r2,__VDSO_TK_SHIFT(%r5)        /* Timekeeper shift */
  42        lg      %r0,__VDSO_WTOM_SEC(%r5)
  43        lg      %r1,1(%r15)
  44        sg      %r1,__VDSO_XTIME_STAMP(%r5)     /* TOD - cycle_last */
  45        msgf    %r1,__VDSO_TK_MULT(%r5)         /*  * tk->mult */
  46        alg     %r1,__VDSO_WTOM_NSEC(%r5)
  47        srlg    %r1,%r1,0(%r2)                  /*  >> tk->shift */
  48        clg     %r4,__VDSO_UPD_COUNT(%r5)       /* check update counter */
  49        jne     0b
  50        larl    %r5,13f
  511:      clg     %r1,0(%r5)
  52        jl      2f
  53        slg     %r1,0(%r5)
  54        aghi    %r0,1
  55        j       1b
  562:      stg     %r0,0(%r3)                      /* store tp->tv_sec */
  57        stg     %r1,8(%r3)                      /* store tp->tv_nsec */
  58        lghi    %r2,0
  59        aghi    %r15,16
  60        CFI_DEF_CFA_OFFSET STACK_FRAME_OVERHEAD
  61        CFI_RESTORE 15
  62        br      %r14
  63
  64        /* CLOCK_MONOTONIC_COARSE */
  65        CFI_DEF_CFA_OFFSET STACK_FRAME_OVERHEAD+16
  66        CFI_VAL_OFFSET 15, -STACK_FRAME_OVERHEAD
  673:      lg      %r4,__VDSO_UPD_COUNT(%r5)       /* load update counter */
  68        tmll    %r4,0x0001                      /* pending update ? loop */
  69        jnz     3b
  70        lg      %r0,__VDSO_WTOM_CRS_SEC(%r5)
  71        lg      %r1,__VDSO_WTOM_CRS_NSEC(%r5)
  72        clg     %r4,__VDSO_UPD_COUNT(%r5)       /* check update counter */
  73        jne     3b
  74        j       2b
  75
  76        /* CLOCK_REALTIME_COARSE */
  774:      lg      %r4,__VDSO_UPD_COUNT(%r5)       /* load update counter */
  78        tmll    %r4,0x0001                      /* pending update ? loop */
  79        jnz     4b
  80        lg      %r0,__VDSO_XTIME_CRS_SEC(%r5)
  81        lg      %r1,__VDSO_XTIME_CRS_NSEC(%r5)
  82        clg     %r4,__VDSO_UPD_COUNT(%r5)       /* check update counter */
  83        jne     4b
  84        j       7f
  85
  86        /* CLOCK_REALTIME */
  875:      lg      %r4,__VDSO_UPD_COUNT(%r5)       /* load update counter */
  88        tmll    %r4,0x0001                      /* pending update ? loop */
  89        jnz     5b
  90        stcke   0(%r15)                         /* Store TOD clock */
  91        lg      %r1,1(%r15)
  92        lg      %r0,__VDSO_TS_END(%r5)          /* TOD steering end time */
  93        slgr    %r0,%r1                         /* now - ts_steering_end */
  94        ltgr    %r0,%r0                         /* past end of steering ? */
  95        jm      17f
  96        srlg    %r0,%r0,15                      /* 1 per 2^16 */
  97        tm      __VDSO_TS_DIR+3(%r5),0x01       /* steering direction? */
  98        jz      18f
  99        lcgr    %r0,%r0                         /* negative TOD offset */
 10018:     algr    %r1,%r0                         /* add steering offset */
 10117:     lgf     %r2,__VDSO_TK_SHIFT(%r5)        /* Timekeeper shift */
 102        sg      %r1,__VDSO_XTIME_STAMP(%r5)     /* TOD - cycle_last */
 103        msgf    %r1,__VDSO_TK_MULT(%r5)         /*  * tk->mult */
 104        alg     %r1,__VDSO_XTIME_NSEC(%r5)      /*  + tk->xtime_nsec */
 105        srlg    %r1,%r1,0(%r2)                  /*  >> tk->shift */
 106        lg      %r0,__VDSO_XTIME_SEC(%r5)       /* tk->xtime_sec */
 107        clg     %r4,__VDSO_UPD_COUNT(%r5)       /* check update counter */
 108        jne     5b
 109        larl    %r5,13f
 1106:      clg     %r1,0(%r5)
 111        jl      7f
 112        slg     %r1,0(%r5)
 113        aghi    %r0,1
 114        j       6b
 1157:      stg     %r0,0(%r3)                      /* store tp->tv_sec */
 116        stg     %r1,8(%r3)                      /* store tp->tv_nsec */
 117        lghi    %r2,0
 118        aghi    %r15,16
 119        CFI_DEF_CFA_OFFSET STACK_FRAME_OVERHEAD
 120        CFI_RESTORE 15
 121        br      %r14
 122
 123        /* CPUCLOCK_VIRT for this thread */
 124        CFI_DEF_CFA_OFFSET STACK_FRAME_OVERHEAD+16
 125        CFI_VAL_OFFSET 15, -STACK_FRAME_OVERHEAD
 1269:      lghi    %r4,0
 127        icm     %r0,15,__VDSO_ECTG_OK(%r5)
 128        jz      12f
 129        sacf    256                             /* Magic ectg instruction */
 130        .insn   ssf,0xc80100000000,__VDSO_ECTG_BASE(4),__VDSO_ECTG_USER(4),4
 131        sacf    0
 132        algr    %r1,%r0                         /* r1 = cputime as TOD value */
 133        mghi    %r1,1000                        /* convert to nanoseconds */
 134        srlg    %r1,%r1,12                      /* r1 = cputime in nanosec */
 135        lgr     %r4,%r1
 136        larl    %r5,13f
 137        srlg    %r1,%r1,9                       /* divide by 1000000000 */
 138        mlg     %r0,8(%r5)
 139        srlg    %r0,%r0,11                      /* r0 = tv_sec */
 140        stg     %r0,0(%r3)
 141        msg     %r0,0(%r5)                      /* calculate tv_nsec */
 142        slgr    %r4,%r0                         /* r4 = tv_nsec */
 143        stg     %r4,8(%r3)
 144        lghi    %r2,0
 145        aghi    %r15,16
 146        CFI_DEF_CFA_OFFSET STACK_FRAME_OVERHEAD
 147        CFI_RESTORE 15
 148        br      %r14
 149
 150        /* Fallback to system call */
 151        CFI_DEF_CFA_OFFSET STACK_FRAME_OVERHEAD+16
 152        CFI_VAL_OFFSET 15, -STACK_FRAME_OVERHEAD
 15312:     lghi    %r1,__NR_clock_gettime
 154        svc     0
 155        aghi    %r15,16
 156        CFI_DEF_CFA_OFFSET STACK_FRAME_OVERHEAD
 157        CFI_RESTORE 15
 158        br      %r14
 159        CFI_ENDPROC
 160
 16113:     .quad   1000000000
 16214:     .quad   19342813113834067
 163        .size   __kernel_clock_gettime,.-__kernel_clock_gettime
 164