În 19 iunie 2020 22:49:32 EEST, Mark Kettenis <mark.kette...@xs4all.nl> a scris:
>> Date: Fri, 19 Jun 2020 20:28:58 +0300
>> From: Paul Irofti <p...@irofti.net>
>> 
>> On Fri, Jun 19, 2020 at 06:52:40PM +0200, Mark Kettenis wrote:
>> > > Date: Fri, 19 Jun 2020 14:31:17 +0300
>> > > From: Paul Irofti <p...@irofti.net>
>> > > 
>> > > Hi,
>> > > 
>> > > Here is another iteration of the diff that addresses all issues
>raised
>> > > in the meantime:
>> > > 
>> > >   - Switch tc to uint
>> > 
>> > The request was to use u_int, like we de in the kernel.  The uint
>type
>> > should not be used in OpenBSD code.
>> > 
>> > >   - Check for version at init and switch to machite/timetc.h defs
>> > >   - Remove tk_nclocks
>> > >   - Switch to single version and ditch minor/major
>> > >   - Do not enable user TSC for large skew values
>> > >   - Add amd64 clocks and use the define in TSC
>> > >   - Include and add machine/timetc.h
>> > > 
>> > > As we have seen most architectures have support for clocks now
>and the
>> > > above addresses Mark's last concerns. 
>> > > 
>> > > Unless other blocking issues arise, this time around I am looking
>for
>> > > OKs to commit. Theo? Mark?
>> > 
>> > There is one other issue that I wanted to raise.  An that is
>whether
>> > we really need to implement CLOCK_UPTINME as a userland clock.  If
>we
>> > don't do that we can drop tk_naptime from the shared struct.  I
>> > mention this because th_naptime was only recently added to struct
>> > timehands and much more an implementation detail than the other
>fields.
>> > 
>> > I don't expect userland processes to call CLOCK_UPTIME in a loop
>like
>> > they tend to do do for CLOCK_MONOTONIC and CLOCK_REALTIME.  Linux
>> > doesn't have it ;).
>> 
>> I don't care eitherway about this. But I don't see why we would not
>have
>> this functionality if it is easy to offer. Maybe someone can help us
>> grep the ports tree for this? Stuart? :)
>> 
>> > We're getting there...
>> 
>> I have addressed your comments bellow, except for the CPU skew one.
>That
>> code disables TSC for all CPUs, not just for PRIMARY. Would you like
>to
>> walk and add code for every CPU to check the drift and then disable
>the
>> TSC? It seems a little too much...
>
>Still uses uint instead of u_int in places. 

Ok. I will check that again.

> Still has the pointless
>extra NULL and 0 for timecounters in files that are otherwise

I am not fixing that. If there's a null present before my diff, then there can 
be a 0 afterwards. If anything my diff unifies this. This is silly. 

>And regarding the TSC.  That issue is a show-stopper.  We can tolerate
>a small amout of skew, but not a large amount.  Because otherwise a
>multithreaded process might observe time going backwards.

I don't see how this is still an issue with my diff, which is what I said last 
time. I am stopping the TSC when the drift is larger than a random value that I 
defined a year ago. What more is needed? Can you describe in more details?

Thank you,
Paul


>
>> diff --git lib/libc/arch/aarch64/gen/Makefile.inc
>lib/libc/arch/aarch64/gen/Makefile.inc
>> index a7b1b73f3ef..ee198f5d611 100644
>> --- lib/libc/arch/aarch64/gen/Makefile.inc
>> +++ lib/libc/arch/aarch64/gen/Makefile.inc
>> @@ -9,4 +9,4 @@ SRCS+=       fpgetmask.c fpgetround.c fpgetsticky.c
>>  SRCS+=      fpsetmask.c fpsetround.c fpsetsticky.c
>>  SRCS+=      fpclassifyl.c
>>  SRCS+=      isfinitel.c isinfl.c isnanl.c isnormall.c
>> -SRCS+=      signbitl.c
>> +SRCS+=      signbitl.c usertc.c
>> diff --git lib/libc/arch/aarch64/gen/usertc.c
>lib/libc/arch/aarch64/gen/usertc.c
>> new file mode 100644
>> index 00000000000..6551854a010
>> --- /dev/null
>> +++ lib/libc/arch/aarch64/gen/usertc.c
>> @@ -0,0 +1,21 @@
>> +/*  $OpenBSD$       */
>> +/*
>> + * Copyright (c) 2020 Paul Irofti <p...@irofti.net>
>> + *
>> + * Permission to use, copy, modify, and distribute this software for
>any
>> + * purpose with or without fee is hereby granted, provided that the
>above
>> + * copyright notice and this permission notice appear in all copies.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
>WARRANTIES
>> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
>> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE
>LIABLE FOR
>> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
>DAMAGES
>> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
>IN AN
>> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
>OUT OF
>> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>> + */
>> +
>> +#include <sys/types.h>
>> +#include <sys/timetc.h>
>> +
>> +int (*const _tc_get_timecount)(struct timekeep *, u_int *) = NULL;
>> diff --git lib/libc/arch/alpha/gen/Makefile.inc
>lib/libc/arch/alpha/gen/Makefile.inc
>> index a44599d2cab..2a8abd32b61 100644
>> --- lib/libc/arch/alpha/gen/Makefile.inc
>> +++ lib/libc/arch/alpha/gen/Makefile.inc
>> @@ -3,5 +3,5 @@
>>  
>>  SRCS+=      _setjmp.S fabs.S infinity.c ldexp.c modf.c nan.c setjmp.S
>>  SRCS+=      flt_rounds.c fpgetmask.c fpgetround.c fpgetsticky.c
>fpsetmask.c \
>> -    fpsetround.c fpsetsticky.c
>> +    fpsetround.c fpsetsticky.c usertc.c
>>  SRCS+=      sigsetjmp.S
>> diff --git lib/libc/arch/alpha/gen/usertc.c
>lib/libc/arch/alpha/gen/usertc.c
>> new file mode 100644
>> index 00000000000..6551854a010
>> --- /dev/null
>> +++ lib/libc/arch/alpha/gen/usertc.c
>> @@ -0,0 +1,21 @@
>> +/*  $OpenBSD$       */
>> +/*
>> + * Copyright (c) 2020 Paul Irofti <p...@irofti.net>
>> + *
>> + * Permission to use, copy, modify, and distribute this software for
>any
>> + * purpose with or without fee is hereby granted, provided that the
>above
>> + * copyright notice and this permission notice appear in all copies.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
>WARRANTIES
>> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
>> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE
>LIABLE FOR
>> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
>DAMAGES
>> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
>IN AN
>> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
>OUT OF
>> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>> + */
>> +
>> +#include <sys/types.h>
>> +#include <sys/timetc.h>
>> +
>> +int (*const _tc_get_timecount)(struct timekeep *, u_int *) = NULL;
>> diff --git lib/libc/arch/amd64/gen/Makefile.inc
>lib/libc/arch/amd64/gen/Makefile.inc
>> index e995309ed71..f6349e2b974 100644
>> --- lib/libc/arch/amd64/gen/Makefile.inc
>> +++ lib/libc/arch/amd64/gen/Makefile.inc
>> @@ -2,6 +2,7 @@
>>  
>>  SRCS+=      _setjmp.S fabs.S infinity.c ldexp.c modf.S nan.c setjmp.S \
>>      sigsetjmp.S
>> -SRCS+=      fpclassifyl.c isfinitel.c isinfl.c isnanl.c isnormall.c
>signbitl.c
>> +SRCS+=      fpclassifyl.c isfinitel.c isinfl.c isnanl.c isnormall.c
>signbitl.c \
>> +    usertc.c
>>  SRCS+=      flt_rounds.S fpgetmask.S fpgetround.S fpgetsticky.S
>fpsetmask.S \
>>      fpsetround.S fpsetsticky.S
>> diff --git lib/libc/arch/amd64/gen/usertc.c
>lib/libc/arch/amd64/gen/usertc.c
>> new file mode 100644
>> index 00000000000..742fb0cc458
>> --- /dev/null
>> +++ lib/libc/arch/amd64/gen/usertc.c
>> @@ -0,0 +1,41 @@
>> +/*  $OpenBSD$ */
>> +/*
>> + * Copyright (c) 2020 Paul Irofti <p...@irofti.net>
>> + *
>> + * Permission to use, copy, modify, and distribute this software for
>any
>> + * purpose with or without fee is hereby granted, provided that the
>above
>> + * copyright notice and this permission notice appear in all copies.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
>WARRANTIES
>> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
>> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE
>LIABLE FOR
>> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
>DAMAGES
>> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
>IN AN
>> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
>OUT OF
>> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>> + */
>> +
>> +#include <sys/types.h>
>> +#include <sys/timetc.h>
>> +
>> +static inline uint
>> +rdtsc(void)
>> +{
>> +    uint32_t hi, lo;
>> +    asm volatile("rdtsc" : "=a"(lo), "=d"(hi));
>> +    return ((uint64_t)lo)|(((uint64_t)hi)<<32);
>> +}
>> +
>> +int
>> +tc_get_timecount(struct timekeep *tk, u_int *tc)
>> +{
>> +    int tk_user = tk->tk_user;
>> +
>> +    if (tk_user < 1 || tk_user >= TC_LAST)
>> +            return -1;
>> +
>> +    *tc = rdtsc();
>> +    return 0;
>> +}
>> +int (*const _tc_get_timecount)(struct timekeep *tk, u_int *tc)
>> +    = tc_get_timecount;
>> diff --git lib/libc/arch/arm/gen/Makefile.inc
>lib/libc/arch/arm/gen/Makefile.inc
>> index 1b4ab2f3ae7..27090a0d9dc 100644
>> --- lib/libc/arch/arm/gen/Makefile.inc
>> +++ lib/libc/arch/arm/gen/Makefile.inc
>> @@ -2,5 +2,5 @@
>>  # $NetBSD: Makefile.inc,v 1.6 2003/08/01 17:03:47 lukem Exp $
>>  
>>  SRCS+=      byte_swap_2.S byte_swap_4.S divsi3.S fabs.c flt_rounds.c
>infinity.c
>> -SRCS+=      ldexp.c modf.c nan.c
>> +SRCS+=      ldexp.c modf.c nan.c usertc.c
>>  SRCS+=      setjmp.S _setjmp.S sigsetjmp.S
>> diff --git lib/libc/arch/arm/gen/usertc.c
>lib/libc/arch/arm/gen/usertc.c
>> new file mode 100644
>> index 00000000000..6551854a010
>> --- /dev/null
>> +++ lib/libc/arch/arm/gen/usertc.c
>> @@ -0,0 +1,21 @@
>> +/*  $OpenBSD$       */
>> +/*
>> + * Copyright (c) 2020 Paul Irofti <p...@irofti.net>
>> + *
>> + * Permission to use, copy, modify, and distribute this software for
>any
>> + * purpose with or without fee is hereby granted, provided that the
>above
>> + * copyright notice and this permission notice appear in all copies.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
>WARRANTIES
>> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
>> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE
>LIABLE FOR
>> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
>DAMAGES
>> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
>IN AN
>> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
>OUT OF
>> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>> + */
>> +
>> +#include <sys/types.h>
>> +#include <sys/timetc.h>
>> +
>> +int (*const _tc_get_timecount)(struct timekeep *, u_int *) = NULL;
>> diff --git lib/libc/arch/hppa/gen/Makefile.inc
>lib/libc/arch/hppa/gen/Makefile.inc
>> index e0c864242fe..1fde24670f1 100644
>> --- lib/libc/arch/hppa/gen/Makefile.inc
>> +++ lib/libc/arch/hppa/gen/Makefile.inc
>> @@ -2,6 +2,6 @@
>>  
>>  SRCS+=      setjmp.S
>>  SRCS+=      fabs.c
>> -SRCS+=      infinity.c ldexp.c modf.c nan.c
>> +SRCS+=      infinity.c ldexp.c modf.c nan.c usertc.c
>>  SRCS+=      flt_rounds.c fpgetmask.c fpgetround.c fpgetsticky.c
>fpsetmask.c \
>>      fpsetround.c fpsetsticky.c
>> diff --git lib/libc/arch/hppa/gen/usertc.c
>lib/libc/arch/hppa/gen/usertc.c
>> new file mode 100644
>> index 00000000000..6551854a010
>> --- /dev/null
>> +++ lib/libc/arch/hppa/gen/usertc.c
>> @@ -0,0 +1,21 @@
>> +/*  $OpenBSD$       */
>> +/*
>> + * Copyright (c) 2020 Paul Irofti <p...@irofti.net>
>> + *
>> + * Permission to use, copy, modify, and distribute this software for
>any
>> + * purpose with or without fee is hereby granted, provided that the
>above
>> + * copyright notice and this permission notice appear in all copies.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
>WARRANTIES
>> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
>> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE
>LIABLE FOR
>> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
>DAMAGES
>> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
>IN AN
>> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
>OUT OF
>> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>> + */
>> +
>> +#include <sys/types.h>
>> +#include <sys/timetc.h>
>> +
>> +int (*const _tc_get_timecount)(struct timekeep *, u_int *) = NULL;
>> diff --git lib/libc/arch/i386/gen/Makefile.inc
>lib/libc/arch/i386/gen/Makefile.inc
>> index 4c18e059581..b7dd30adccd 100644
>> --- lib/libc/arch/i386/gen/Makefile.inc
>> +++ lib/libc/arch/i386/gen/Makefile.inc
>> @@ -1,6 +1,6 @@
>>  #   $OpenBSD: Makefile.inc,v 1.14 2012/04/19 19:14:56 deraadt Exp $
>>  
>> -SRCS+=      _setjmp.S fabs.S infinity.c ldexp.c \
>> +SRCS+=      _setjmp.S fabs.S infinity.c ldexp.c usertc.c \
>>      modf.S nan.c setjmp.S sigsetjmp.S
>>  SRCS+=      fpclassifyl.c isfinitel.c isinfl.c isnanl.c isnormall.c
>signbitl.c
>>  SRCS+=      flt_rounds.S fpgetmask.S fpgetround.S fpgetsticky.S
>fpsetmask.S \
>> diff --git lib/libc/arch/i386/gen/usertc.c
>lib/libc/arch/i386/gen/usertc.c
>> new file mode 100644
>> index 00000000000..6551854a010
>> --- /dev/null
>> +++ lib/libc/arch/i386/gen/usertc.c
>> @@ -0,0 +1,21 @@
>> +/*  $OpenBSD$       */
>> +/*
>> + * Copyright (c) 2020 Paul Irofti <p...@irofti.net>
>> + *
>> + * Permission to use, copy, modify, and distribute this software for
>any
>> + * purpose with or without fee is hereby granted, provided that the
>above
>> + * copyright notice and this permission notice appear in all copies.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
>WARRANTIES
>> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
>> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE
>LIABLE FOR
>> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
>DAMAGES
>> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
>IN AN
>> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
>OUT OF
>> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>> + */
>> +
>> +#include <sys/types.h>
>> +#include <sys/timetc.h>
>> +
>> +int (*const _tc_get_timecount)(struct timekeep *, u_int *) = NULL;
>> diff --git lib/libc/arch/m88k/gen/Makefile.inc
>lib/libc/arch/m88k/gen/Makefile.inc
>> index cff75b8d425..d66f66af4af 100644
>> --- lib/libc/arch/m88k/gen/Makefile.inc
>> +++ lib/libc/arch/m88k/gen/Makefile.inc
>> @@ -1,7 +1,7 @@
>>  #   $OpenBSD: Makefile.inc,v 1.16 2013/06/05 22:06:30 miod Exp $
>>  #   $NetBSD: Makefile.inc,v 1.3 1995/04/10 21:09:06 jtc Exp $
>>  
>> -SRCS+=      _setjmp.S fabs.S infinity.c ldexp.c modf.c nan.c
>> +SRCS+=      _setjmp.S fabs.S infinity.c ldexp.c modf.c nan.c usertc.c
>>  SRCS+=      flt_rounds.c fpgetmask.c fpgetround.c fpgetsticky.c
>fpsetmask.c \
>>      fpsetround.c fpsetsticky.c
>>  SRCS+=      setjmp.S sigsetjmp.S
>> diff --git lib/libc/arch/m88k/gen/usertc.c
>lib/libc/arch/m88k/gen/usertc.c
>> new file mode 100644
>> index 00000000000..6551854a010
>> --- /dev/null
>> +++ lib/libc/arch/m88k/gen/usertc.c
>> @@ -0,0 +1,21 @@
>> +/*  $OpenBSD$       */
>> +/*
>> + * Copyright (c) 2020 Paul Irofti <p...@irofti.net>
>> + *
>> + * Permission to use, copy, modify, and distribute this software for
>any
>> + * purpose with or without fee is hereby granted, provided that the
>above
>> + * copyright notice and this permission notice appear in all copies.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
>WARRANTIES
>> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
>> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE
>LIABLE FOR
>> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
>DAMAGES
>> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
>IN AN
>> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
>OUT OF
>> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>> + */
>> +
>> +#include <sys/types.h>
>> +#include <sys/timetc.h>
>> +
>> +int (*const _tc_get_timecount)(struct timekeep *, u_int *) = NULL;
>> diff --git lib/libc/arch/mips64/gen/Makefile.inc
>lib/libc/arch/mips64/gen/Makefile.inc
>> index 8cf1fc2d28a..839241a2069 100644
>> --- lib/libc/arch/mips64/gen/Makefile.inc
>> +++ lib/libc/arch/mips64/gen/Makefile.inc
>> @@ -1,6 +1,6 @@
>>  #   $OpenBSD: Makefile.inc,v 1.12 2012/04/12 16:14:09 deraadt Exp $
>>  
>> -SRCS+=      _setjmp.S fabs.S infinity.c ldexp.S modf.S nan.c
>> +SRCS+=      _setjmp.S fabs.S infinity.c ldexp.S modf.S nan.c usertc.c
>>  SRCS+=      flt_rounds.c fpgetmask.c fpgetround.c fpgetsticky.c
>fpsetmask.c \
>>      fpsetround.c fpsetsticky.c
>>  SRCS+=      fpclassifyl.c isfinitel.c isinfl.c isnanl.c isnormall.c
>signbitl.c
>> diff --git lib/libc/arch/mips64/gen/usertc.c
>lib/libc/arch/mips64/gen/usertc.c
>> new file mode 100644
>> index 00000000000..6551854a010
>> --- /dev/null
>> +++ lib/libc/arch/mips64/gen/usertc.c
>> @@ -0,0 +1,21 @@
>> +/*  $OpenBSD$       */
>> +/*
>> + * Copyright (c) 2020 Paul Irofti <p...@irofti.net>
>> + *
>> + * Permission to use, copy, modify, and distribute this software for
>any
>> + * purpose with or without fee is hereby granted, provided that the
>above
>> + * copyright notice and this permission notice appear in all copies.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
>WARRANTIES
>> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
>> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE
>LIABLE FOR
>> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
>DAMAGES
>> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
>IN AN
>> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
>OUT OF
>> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>> + */
>> +
>> +#include <sys/types.h>
>> +#include <sys/timetc.h>
>> +
>> +int (*const _tc_get_timecount)(struct timekeep *, u_int *) = NULL;
>> diff --git lib/libc/arch/powerpc/gen/Makefile.inc
>lib/libc/arch/powerpc/gen/Makefile.inc
>> index 6b2e4613ee8..d4d7b00bff7 100644
>> --- lib/libc/arch/powerpc/gen/Makefile.inc
>> +++ lib/libc/arch/powerpc/gen/Makefile.inc
>> @@ -1,5 +1,5 @@
>>  SRCS+= infinity.c setjmp.S sigsetjmp.S flt_rounds.c ldexp.c modf.c
>nan.c
>> -SRCS+= fabs.c
>> +SRCS+= fabs.c usertc.c
>>  SRCS+= fpgetmask.c fpsetmask.c
>>  SRCS+= fpgetround.c fpsetround.c
>>  SRCS+= fpgetsticky.c fpsetsticky.c
>> diff --git lib/libc/arch/powerpc/gen/usertc.c
>lib/libc/arch/powerpc/gen/usertc.c
>> new file mode 100644
>> index 00000000000..6551854a010
>> --- /dev/null
>> +++ lib/libc/arch/powerpc/gen/usertc.c
>> @@ -0,0 +1,21 @@
>> +/*  $OpenBSD$       */
>> +/*
>> + * Copyright (c) 2020 Paul Irofti <p...@irofti.net>
>> + *
>> + * Permission to use, copy, modify, and distribute this software for
>any
>> + * purpose with or without fee is hereby granted, provided that the
>above
>> + * copyright notice and this permission notice appear in all copies.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
>WARRANTIES
>> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
>> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE
>LIABLE FOR
>> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
>DAMAGES
>> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
>IN AN
>> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
>OUT OF
>> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>> + */
>> +
>> +#include <sys/types.h>
>> +#include <sys/timetc.h>
>> +
>> +int (*const _tc_get_timecount)(struct timekeep *, u_int *) = NULL;
>> diff --git lib/libc/arch/sh/gen/Makefile.inc
>lib/libc/arch/sh/gen/Makefile.inc
>> index 55de1973b30..4724fb3a6a8 100644
>> --- lib/libc/arch/sh/gen/Makefile.inc
>> +++ lib/libc/arch/sh/gen/Makefile.inc
>> @@ -3,4 +3,4 @@
>>  SRCS+= flt_rounds.c infinity.c ldexp.c modf.c nan.c setjmp.S
>_setjmp.S
>>  SRCS+= sigsetjmp.S
>>  SRCS+=      fabs.c fpgetmask.c fpgetround.c fpgetsticky.c \
>> -    fpsetmask.c fpsetround.c fpsetsticky.c
>> +    fpsetmask.c fpsetround.c fpsetsticky.c usertc.c
>> diff --git lib/libc/arch/sh/gen/usertc.c
>lib/libc/arch/sh/gen/usertc.c
>> new file mode 100644
>> index 00000000000..6551854a010
>> --- /dev/null
>> +++ lib/libc/arch/sh/gen/usertc.c
>> @@ -0,0 +1,21 @@
>> +/*  $OpenBSD$       */
>> +/*
>> + * Copyright (c) 2020 Paul Irofti <p...@irofti.net>
>> + *
>> + * Permission to use, copy, modify, and distribute this software for
>any
>> + * purpose with or without fee is hereby granted, provided that the
>above
>> + * copyright notice and this permission notice appear in all copies.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
>WARRANTIES
>> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
>> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE
>LIABLE FOR
>> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
>DAMAGES
>> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
>IN AN
>> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
>OUT OF
>> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>> + */
>> +
>> +#include <sys/types.h>
>> +#include <sys/timetc.h>
>> +
>> +int (*const _tc_get_timecount)(struct timekeep *, u_int *) = NULL;
>> diff --git lib/libc/arch/sparc64/gen/Makefile.inc
>lib/libc/arch/sparc64/gen/Makefile.inc
>> index 58259cedef6..a908e022954 100644
>> --- lib/libc/arch/sparc64/gen/Makefile.inc
>> +++ lib/libc/arch/sparc64/gen/Makefile.inc
>> @@ -3,5 +3,5 @@
>>  SRCS+=      _setjmp.S fabs.S fixunsdfsi.S flt_rounds.c fpclassifyl.c \
>>      fpgetmask.c fpgetround.c fpgetsticky.c fpsetmask.c \
>>      fpsetround.c fpsetsticky.c infinity.c isfinitel.c \
>> -    isinfl.c isnanl.c isnormall.c ldexp.c modf.S \
>> +    isinfl.c isnanl.c isnormall.c ldexp.c usertc.c modf.S \
>>      mul.S nan.c setjmp.S signbitl.c sigsetjmp.S umul.S
>> diff --git lib/libc/arch/sparc64/gen/usertc.c
>lib/libc/arch/sparc64/gen/usertc.c
>> new file mode 100644
>> index 00000000000..6551854a010
>> --- /dev/null
>> +++ lib/libc/arch/sparc64/gen/usertc.c
>> @@ -0,0 +1,21 @@
>> +/*  $OpenBSD$       */
>> +/*
>> + * Copyright (c) 2020 Paul Irofti <p...@irofti.net>
>> + *
>> + * Permission to use, copy, modify, and distribute this software for
>any
>> + * purpose with or without fee is hereby granted, provided that the
>above
>> + * copyright notice and this permission notice appear in all copies.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
>WARRANTIES
>> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
>> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE
>LIABLE FOR
>> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
>DAMAGES
>> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
>IN AN
>> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
>OUT OF
>> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>> + */
>> +
>> +#include <sys/types.h>
>> +#include <sys/timetc.h>
>> +
>> +int (*const _tc_get_timecount)(struct timekeep *, u_int *) = NULL;
>> diff --git lib/libc/asr/asr.c lib/libc/asr/asr.c
>> index 131da4b2190..40e84771f86 100644
>> --- lib/libc/asr/asr.c
>> +++ lib/libc/asr/asr.c
>> @@ -198,11 +198,11 @@ poll_intrsafe(struct pollfd *fds, nfds_t nfds,
>int timeout)
>>      struct timespec pollstart, pollend, elapsed;
>>      int r;
>>  
>> -    if (clock_gettime(CLOCK_MONOTONIC, &pollstart))
>> +    if (WRAP(clock_gettime)(CLOCK_MONOTONIC, &pollstart))
>>              return -1;
>>  
>>      while ((r = poll(fds, 1, timeout)) == -1 && errno == EINTR) {
>> -            if (clock_gettime(CLOCK_MONOTONIC, &pollend))
>> +            if (WRAP(clock_gettime)(CLOCK_MONOTONIC, &pollend))
>>                      return -1;
>>              timespecsub(&pollend, &pollstart, &elapsed);
>>              timeout -= elapsed.tv_sec * 1000 + elapsed.tv_nsec / 1000000;
>> @@ -420,7 +420,7 @@ asr_check_reload(struct asr *asr)
>>              asr->a_rtime = 0;
>>      }
>>  
>> -    if (clock_gettime(CLOCK_MONOTONIC, &ts) == -1)
>> +    if (WRAP(clock_gettime)(CLOCK_MONOTONIC, &ts) == -1)
>>              return;
>>  
>>      if ((ts.tv_sec - asr->a_rtime) < RELOAD_DELAY && asr->a_rtime != 0)
>> diff --git lib/libc/crypt/bcrypt.c lib/libc/crypt/bcrypt.c
>> index 82de8fa33b7..02fd3013cc1 100644
>> --- lib/libc/crypt/bcrypt.c
>> +++ lib/libc/crypt/bcrypt.c
>> @@ -248,9 +248,9 @@ _bcrypt_autorounds(void)
>>      char buf[_PASSWORD_LEN];
>>      int duration;
>>  
>> -    clock_gettime(CLOCK_THREAD_CPUTIME_ID, &before);
>> +    WRAP(clock_gettime)(CLOCK_THREAD_CPUTIME_ID, &before);
>>      bcrypt_newhash("testpassword", r, buf, sizeof(buf));
>> -    clock_gettime(CLOCK_THREAD_CPUTIME_ID, &after);
>> +    WRAP(clock_gettime)(CLOCK_THREAD_CPUTIME_ID, &after);
>>  
>>      duration = after.tv_sec - before.tv_sec;
>>      duration *= 1000000;
>> diff --git lib/libc/dlfcn/init.c lib/libc/dlfcn/init.c
>> index 270f54aada5..d2632455f11 100644
>> --- lib/libc/dlfcn/init.c
>> +++ lib/libc/dlfcn/init.c
>> @@ -20,6 +20,7 @@
>>  
>>  #include <sys/types.h>
>>  #include <sys/syscall.h>
>> +#include <sys/timetc.h>             /* timekeep */
>>  
>>  #ifndef PIC
>>  #include <sys/mman.h>
>> @@ -45,8 +46,9 @@
>>  /* XXX should be in an include file shared with csu */
>>  char        ***_csu_finish(char **_argv, char **_envp, void
>(*_cleanup)(void));
>>  
>> -/* provide definition for this */
>> +/* provide definitions for these */
>>  int _pagesize = 0;
>> +struct timekeep     *_timekeep;
>>  
>>  /*
>>   * In dynamicly linked binaries environ and __progname are overriden
>by
>> @@ -105,6 +107,13 @@ _libc_preinit(int argc, char **argv, char
>**envp, dl_cb_cb *cb)
>>                      phnum = aux->au_v;
>>                      break;
>>  #endif /* !PIC */
>> +            case AUX_openbsd_timekeep:
>> +                    if (_tc_get_timecount) {
>> +                            _timekeep = (void *)aux->au_v;
>> +                            if (_timekeep->tk_version != TK_VERSION)
>> +                                    _timekeep = NULL;
>> +                    }
>> +                    break;
>>              }
>>      }
>>  
>> diff --git lib/libc/gen/auth_subr.c lib/libc/gen/auth_subr.c
>> index 1286a96fe40..32f86eda50f 100644
>> --- lib/libc/gen/auth_subr.c
>> +++ lib/libc/gen/auth_subr.c
>> @@ -752,7 +752,7 @@ auth_check_expire(auth_session_t *as)
>>  
>>      if (as->pwd && (quad_t)as->pwd->pw_expire != 0) {
>>              if (as->now.tv_sec == 0)
>> -                    gettimeofday(&as->now, NULL);
>> +                    WRAP(gettimeofday)(&as->now, NULL);
>>              if ((quad_t)as->now.tv_sec >= (quad_t)as->pwd->pw_expire) {
>>                      as->state &= ~AUTH_ALLOW;
>>                      as->state |= AUTH_EXPIRED;
>> @@ -779,7 +779,7 @@ auth_check_change(auth_session_t *as)
>>  
>>      if (as->pwd && (quad_t)as->pwd->pw_change) {
>>              if (as->now.tv_sec == 0)
>> -                    gettimeofday(&as->now, NULL);
>> +                    WRAP(gettimeofday)(&as->now, NULL);
>>              if (as->now.tv_sec >= (quad_t)as->pwd->pw_change) {
>>                      as->state &= ~AUTH_ALLOW;
>>                      as->state |= AUTH_PWEXPIRED;
>> diff --git lib/libc/gen/time.c lib/libc/gen/time.c
>> index 3bbd0d733d1..b3ce9a800f1 100644
>> --- lib/libc/gen/time.c
>> +++ lib/libc/gen/time.c
>> @@ -36,7 +36,7 @@ time(time_t *t)
>>  {
>>      struct timeval tt;
>>  
>> -    if (gettimeofday(&tt, NULL) == -1)
>> +    if (WRAP(gettimeofday)(&tt, NULL) == -1)
>>              return (-1);
>>      if (t)
>>              *t = (time_t)tt.tv_sec;
>> diff --git lib/libc/gen/times.c lib/libc/gen/times.c
>> index 02e4dd44b5c..36841810d1b 100644
>> --- lib/libc/gen/times.c
>> +++ lib/libc/gen/times.c
>> @@ -52,7 +52,7 @@ times(struct tms *tp)
>>              return ((clock_t)-1);
>>      tp->tms_cutime = CONVTCK(ru.ru_utime);
>>      tp->tms_cstime = CONVTCK(ru.ru_stime);
>> -    if (clock_gettime(CLOCK_MONOTONIC, &ts) == -1)
>> +    if (WRAP(clock_gettime)(CLOCK_MONOTONIC, &ts) == -1)
>>              return ((clock_t)-1);
>>      return (ts.tv_sec * CLK_TCK + ts.tv_nsec / (1000000000 / CLK_TCK));
>>  }
>> diff --git lib/libc/gen/timespec_get.c lib/libc/gen/timespec_get.c
>> index 520a5954025..845cbe80356 100644
>> --- lib/libc/gen/timespec_get.c
>> +++ lib/libc/gen/timespec_get.c
>> @@ -37,7 +37,7 @@ timespec_get(struct timespec *ts, int base)
>>  {
>>      switch (base) {
>>      case TIME_UTC:
>> -            if (clock_gettime(CLOCK_REALTIME, ts) == -1)
>> +            if (WRAP(clock_gettime)(CLOCK_REALTIME, ts) == -1)
>>                      return 0;
>>              break;
>>      default:
>> diff --git lib/libc/hidden/sys/time.h lib/libc/hidden/sys/time.h
>> index ed112320fa2..df717021cab 100644
>> --- lib/libc/hidden/sys/time.h
>> +++ lib/libc/hidden/sys/time.h
>> @@ -24,7 +24,7 @@ PROTO_NORMAL(adjfreq);
>>  PROTO_NORMAL(adjtime);
>>  PROTO_NORMAL(futimes);
>>  PROTO_NORMAL(getitimer);
>> -PROTO_NORMAL(gettimeofday);
>> +PROTO_WRAP(gettimeofday);
>>  PROTO_NORMAL(setitimer);
>>  PROTO_NORMAL(settimeofday);
>>  PROTO_NORMAL(utimes);
>> diff --git lib/libc/hidden/sys/timetc.h lib/libc/hidden/sys/timetc.h
>> new file mode 100644
>> index 00000000000..bbdaa2d0d4c
>> --- /dev/null
>> +++ lib/libc/hidden/sys/timetc.h
>> @@ -0,0 +1,38 @@
>> +/*  $OpenBSD$       */
>> +/*
>> + * Copyright (c) 2020 Paul Irofti <p...@irofti.net>
>> + *
>> + * Permission to use, copy, modify, and distribute this software for
>any
>> + * purpose with or without fee is hereby granted, provided that the
>above
>> + * copyright notice and this permission notice appear in all copies.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
>WARRANTIES
>> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
>> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE
>LIABLE FOR
>> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
>DAMAGES
>> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
>IN AN
>> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
>OUT OF
>> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>> + */
>> +
>> +#ifndef _LIBC_SYS_TIMETC_H_
>> +#define _LIBC_SYS_TIMETC_H_
>> +
>> +#define _LIBC
>> +#include <sys/types.h>
>> +#include <sys/time.h>
>> +
>> +#include_next <sys/timetc.h>
>> +
>> +__BEGIN_HIDDEN_DECLS
>> +extern struct timekeep *_timekeep;
>> +
>> +extern int (*const _tc_get_timecount)(struct timekeep *, u_int *);
>> +
>> +int _microtime(struct timeval *, struct timekeep *);
>> +int _nanotime(struct timespec *, struct timekeep *);
>> +int _nanoruntime(struct timespec *, struct timekeep *);
>> +int _nanouptime(struct timespec *, struct timekeep *);
>> +__END_HIDDEN_DECLS
>> +
>> +#endif /* !_LIBC_SYS_TIMETC_H_ */
>> diff --git lib/libc/hidden/time.h lib/libc/hidden/time.h
>> index 18c49f8fcb9..d8e1e0caf64 100644
>> --- lib/libc/hidden/time.h
>> +++ lib/libc/hidden/time.h
>> @@ -29,7 +29,7 @@ PROTO_NORMAL(asctime_r);
>>  PROTO_STD_DEPRECATED(clock);
>>  PROTO_DEPRECATED(clock_getcpuclockid);
>>  PROTO_NORMAL(clock_getres);
>> -PROTO_NORMAL(clock_gettime);
>> +PROTO_WRAP(clock_gettime);
>>  PROTO_NORMAL(clock_settime);
>>  PROTO_STD_DEPRECATED(ctime);
>>  PROTO_DEPRECATED(ctime_r);
>> diff --git lib/libc/net/res_random.c lib/libc/net/res_random.c
>> index 763e420bb88..9babb28470a 100644
>> --- lib/libc/net/res_random.c
>> +++ lib/libc/net/res_random.c
>> @@ -219,7 +219,7 @@ res_initid(void)
>>      if (ru_prf != NULL)
>>              arc4random_buf(ru_prf, sizeof(*ru_prf));
>>  
>> -    clock_gettime(CLOCK_MONOTONIC, &ts);
>> +    WRAP(clock_gettime)(CLOCK_MONOTONIC, &ts);
>>      ru_reseed = ts.tv_sec + RU_OUT;
>>      ru_msb = ru_msb == 0x8000 ? 0 : 0x8000; 
>>  }
>> @@ -232,7 +232,7 @@ __res_randomid(void)
>>      u_int r;
>>      static void *randomid_mutex;
>>  
>> -    clock_gettime(CLOCK_MONOTONIC, &ts);
>> +    WRAP(clock_gettime)(CLOCK_MONOTONIC, &ts);
>>      pid = getpid();
>>  
>>      _MUTEX_LOCK(&randomid_mutex);
>> diff --git lib/libc/rpc/auth_unix.c lib/libc/rpc/auth_unix.c
>> index 402d98cede4..917a6d42b8a 100644
>> --- lib/libc/rpc/auth_unix.c
>> +++ lib/libc/rpc/auth_unix.c
>> @@ -121,7 +121,7 @@ authunix_create(char *machname, int uid, int gid,
>int len, int *aup_gids)
>>      /*
>>       * fill in param struct from the given params
>>       */
>> -    (void)gettimeofday(&now,  NULL);
>> +    (void)WRAP(gettimeofday)(&now,  NULL);
>>      aup.aup_time = now.tv_sec;
>>      aup.aup_machname = machname;
>>      aup.aup_uid = uid;
>> @@ -274,7 +274,7 @@ authunix_refresh(AUTH *auth)
>>              goto done;
>>  
>>      /* update the time and serialize in place */
>> -    (void)gettimeofday(&now, NULL);
>> +    (void)WRAP(gettimeofday)(&now, NULL);
>>      aup.aup_time = now.tv_sec;
>>      xdrs.x_op = XDR_ENCODE;
>>      XDR_SETPOS(&xdrs, 0);
>> diff --git lib/libc/rpc/clnt_tcp.c lib/libc/rpc/clnt_tcp.c
>> index 8e6ef515b0e..927b4bf2028 100644
>> --- lib/libc/rpc/clnt_tcp.c
>> +++ lib/libc/rpc/clnt_tcp.c
>> @@ -393,12 +393,12 @@ readtcp(struct ct_data *ct, caddr_t buf, int
>len)
>>      pfd[0].events = POLLIN;
>>      TIMEVAL_TO_TIMESPEC(&ct->ct_wait, &wait);
>>      delta = wait;
>> -    clock_gettime(CLOCK_MONOTONIC, &start);
>> +    WRAP(clock_gettime)(CLOCK_MONOTONIC, &start);
>>      for (;;) {
>>              r = ppoll(pfd, 1, &delta, NULL);
>>              save_errno = errno;
>>  
>> -            clock_gettime(CLOCK_MONOTONIC, &after);
>> +            WRAP(clock_gettime)(CLOCK_MONOTONIC, &after);
>>              timespecsub(&start, &after, &duration);
>>              timespecsub(&wait, &duration, &delta);
>>              if (delta.tv_sec < 0 || !timespecisset(&delta))
>> diff --git lib/libc/rpc/clnt_udp.c lib/libc/rpc/clnt_udp.c
>> index 68d01674410..92e1d5c350d 100644
>> --- lib/libc/rpc/clnt_udp.c
>> +++ lib/libc/rpc/clnt_udp.c
>> @@ -265,7 +265,7 @@ send_again:
>>      reply_msg.acpted_rply.ar_results.where = resultsp;
>>      reply_msg.acpted_rply.ar_results.proc = xresults;
>>  
>> -    clock_gettime(CLOCK_MONOTONIC, &start);
>> +    WRAP(clock_gettime)(CLOCK_MONOTONIC, &start);
>>      for (;;) {
>>              switch (ppoll(pfd, 1, &wait, NULL)) {
>>              case 0:
>> @@ -283,7 +283,7 @@ send_again:
>>                      /* FALLTHROUGH */
>>              case -1:
>>                      if (errno == EINTR) {
>> -                            clock_gettime(CLOCK_MONOTONIC, &after);
>> +                            WRAP(clock_gettime)(CLOCK_MONOTONIC, &after);
>>                              timespecsub(&after, &start, &duration);
>>                              timespecadd(&time_waited, &duration, 
>> &time_waited);
>>                              if (timespeccmp(&time_waited, &timeout, <))
>> diff --git lib/libc/rpc/svc_tcp.c lib/libc/rpc/svc_tcp.c
>> index f9d7a70938f..6c99db84359 100644
>> --- lib/libc/rpc/svc_tcp.c
>> +++ lib/libc/rpc/svc_tcp.c
>> @@ -342,7 +342,7 @@ readtcp(SVCXPRT *xprt, caddr_t buf, int len)
>>       * A timeout is fatal for the connection.
>>       */
>>      delta = wait_per_try;
>> -    clock_gettime(CLOCK_MONOTONIC, &start);
>> +    WRAP(clock_gettime)(CLOCK_MONOTONIC, &start);
>>      pfd[0].fd = sock;
>>      pfd[0].events = POLLIN;
>>      do {
>> @@ -351,7 +351,7 @@ readtcp(SVCXPRT *xprt, caddr_t buf, int len)
>>              case -1:
>>                      if (errno != EINTR)
>>                              goto fatal_err;
>> -                    clock_gettime(CLOCK_MONOTONIC, &after);
>> +                    WRAP(clock_gettime)(CLOCK_MONOTONIC, &after);
>>                      timespecsub(&after, &start, &duration);
>>                      timespecsub(&wait_per_try, &duration, &delta);
>>                      if (delta.tv_sec < 0 || !timespecisset(&delta))
>> diff --git lib/libc/sys/Makefile.inc lib/libc/sys/Makefile.inc
>> index 34769576ced..d57418d81bf 100644
>> --- lib/libc/sys/Makefile.inc
>> +++ lib/libc/sys/Makefile.inc
>> @@ -12,7 +12,8 @@ SRCS+=     Ovfork.S brk.S ${CERROR} \
>>  
>>  # glue to offer userland wrappers for some syscalls
>>  SRCS+=      posix_madvise.c pthread_sigmask.c \
>> -    w_fork.c w_sigaction.c w_sigprocmask.c w_sigsuspend.c w_vfork.c
>> +    w_fork.c w_sigaction.c w_sigprocmask.c w_sigsuspend.c w_vfork.c \
>> +    w_clock_gettime.c w_gettimeofday.c microtime.c
>>  
>>  # glue for compat with old syscall interfaces.
>>  SRCS+=      ftruncate.c lseek.c mquery.c mmap.c ptrace.c semctl.c
>truncate.c \
>> @@ -43,7 +44,7 @@ SRCS+=     ${CANCEL:%=w_%.c} w_pread.c w_preadv.c
>w_pwrite.c w_pwritev.c
>>  ASM=        __semctl.o __syscall.o __thrsigdivert.o \
>>      access.o acct.o adjfreq.o adjtime.o \
>>      bind.o chdir.o chflags.o chflagsat.o chmod.o chown.o chroot.o \
>> -    clock_getres.o clock_gettime.o clock_settime.o \
>> +    clock_getres.o clock_settime.o \
>>      dup.o dup2.o dup3.o \
>>      execve.o \
>>      faccessat.o fchdir.o fchflags.o fchmod.o fchmodat.o fchown.o \
>> @@ -54,7 +55,7 @@ ASM=       __semctl.o __syscall.o __thrsigdivert.o \
>>      getgroups.o getitimer.o getpeername.o getpgid.o \
>>      getpriority.o getresgid.o getresuid.o \
>>      getrlimit.o getrusage.o getsid.o getsockname.o \
>> -    getsockopt.o gettimeofday.o ioctl.o \
>> +    getsockopt.o ioctl.o \
>>      kevent.o kill.o kqueue.o ktrace.o lchown.o \
>>      link.o linkat.o listen.o lstat.o madvise.o \
>>      minherit.o mkdir.o mkdirat.o mkfifo.o mkfifoat.o \
>> @@ -109,7 +110,8 @@ PPSEUDO_NOERR=${PSEUDO_NOERR:.o=.po}
>>  SPSEUDO_NOERR=${PSEUDO_NOERR:.o=.so}
>>  DPSEUDO_NOERR=${PSEUDO_NOERR:.o=.do}
>>  
>> -HIDDEN= ___realpath.o ___getcwd.o fork.o sigaction.o _ptrace.o
>${CANCEL:=.o}
>> +HIDDEN= ___realpath.o ___getcwd.o fork.o sigaction.o _ptrace.o
>${CANCEL:=.o} \
>> +    clock_gettime.o gettimeofday.o
>>  PHIDDEN=${HIDDEN:.o=.po}
>>  SHIDDEN=${HIDDEN:.o=.so}
>>  DHIDDEN=${HIDDEN:.o=.do}
>> diff --git lib/libc/sys/microtime.c lib/libc/sys/microtime.c
>> new file mode 100644
>> index 00000000000..5191b5b2606
>> --- /dev/null
>> +++ lib/libc/sys/microtime.c
>> @@ -0,0 +1,181 @@
>> +/*  $OpenBSD$ */
>> +/*
>> + * Copyright (c) 2000 Poul-Henning Kamp <p...@freebsd.org>
>> + * Copyright (c) 2020 Paul Irofti <p...@irofti.net>
>> + *
>> + * Permission to use, copy, modify, and distribute this software for
>any
>> + * purpose with or without fee is hereby granted, provided that the
>above
>> + * copyright notice and this permission notice appear in all copies.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
>WARRANTIES
>> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
>> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE
>LIABLE FOR
>> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
>DAMAGES
>> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
>IN AN
>> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
>OUT OF
>> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>> + */
>> +
>> +#include <sys/types.h>
>> +#include <sys/atomic.h>
>> +#include <sys/timetc.h>
>> +
>> +#include <time.h>
>> +
>> +/*
>> + * Return the difference between the timehands' counter value now
>and what
>> + * was when we copied it to the timehands' offset_count.
>> + */
>> +static inline int
>> +tc_delta(struct timekeep *tk, u_int *delta)
>> +{
>> +    uint tc;
>> +
>> +    if (_tc_get_timecount(tk, &tc))
>> +            return -1;
>> +    *delta = (tc - tk->tk_offset_count) & tk->tk_counter_mask;
>> +    return 0;
>> +}
>> +
>> +static inline void
>> +bintimeaddfrac(const struct bintime *bt, uint64_t x, struct bintime
>*ct)
>> +{
>> +    ct->sec = bt->sec;
>> +    if (bt->frac > bt->frac + x)
>> +            ct->sec++;
>> +    ct->frac = bt->frac + x;
>> +}
>> +
>> +static inline void
>> +BINTIME_TO_TIMESPEC(const struct bintime *bt, struct timespec *ts)
>> +{
>> +    ts->tv_sec = bt->sec;
>> +    ts->tv_nsec = (long)(((uint64_t)1000000000 * (uint32_t)(bt->frac >>
>32)) >> 32);
>> +}
>> +
>> +static inline void
>> +BINTIME_TO_TIMEVAL(const struct bintime *bt, struct timeval *tv)
>> +{
>> +    tv->tv_sec = bt->sec;
>> +    tv->tv_usec = (long)(((uint64_t)1000000 * (uint32_t)(bt->frac >>
>32)) >> 32);
>> +}
>> +
>> +static int
>> +binuptime(struct bintime *bt, struct timekeep *tk)
>> +{
>> +    u_int gen, delta;
>> +
>> +    do {
>> +            gen = tk->tk_generation;
>> +            membar_consumer();
>> +            *bt = tk->tk_offset;
>> +            if (tc_delta(tk, &delta))
>> +                    return -1;
>> +            bintimeaddfrac(bt, tk->tk_scale * delta, bt);
>> +            membar_consumer();
>> +    } while (gen == 0 || gen != tk->tk_generation);
>> +
>> +    return 0;
>> +}
>> +
>> +static inline void
>> +bintimeadd(const struct bintime *bt, const struct bintime *ct,
>> +    struct bintime *dt)
>> +{
>> +    dt->sec = bt->sec + ct->sec;
>> +    if (bt->frac > bt->frac + ct->frac)
>> +            dt->sec++;
>> +    dt->frac = bt->frac + ct->frac;
>> +}
>> +
>> +static inline void
>> +bintimesub(const struct bintime *bt, const struct bintime *ct,
>> +    struct bintime *dt)
>> +{
>> +    dt->sec = bt->sec - ct->sec;
>> +    if (bt->frac < bt->frac - ct->frac)
>> +            dt->sec--;
>> +    dt->frac = bt->frac - ct->frac;
>> +}
>> +
>> +static int
>> +binruntime(struct bintime *bt, struct timekeep *tk)
>> +{
>> +    u_int gen, delta;
>> +
>> +    do {
>> +            gen = tk->tk_generation;
>> +            membar_consumer();
>> +            if (tc_delta(tk, &delta))
>> +                    return -1;
>> +            bintimeaddfrac(&tk->tk_offset, tk->tk_scale * delta, bt);
>> +            bintimesub(bt, &tk->tk_naptime, bt);
>> +            membar_consumer();
>> +    } while (gen == 0 || gen != tk->tk_generation);
>> +
>> +    return 0;
>> +}
>> +
>> +static int
>> +bintime(struct bintime *bt, struct timekeep *tk)
>> +{
>> +    u_int gen, delta;
>> +
>> +    do {
>> +            gen = tk->tk_generation;
>> +            membar_consumer();
>> +            *bt = tk->tk_offset;
>> +            if (tc_delta(tk, &delta))
>> +                    return -1;
>> +            bintimeaddfrac(bt, tk->tk_scale * delta, bt);
>> +            bintimeadd(bt, &tk->tk_boottime, bt);
>> +            membar_consumer();
>> +    } while (gen == 0 || gen != tk->tk_generation);
>> +
>> +    return 0;
>> +}
>> +
>> +int
>> +_microtime(struct timeval *tvp, struct timekeep *tk)
>> +{
>> +    struct bintime bt;
>> +
>> +    if (bintime(&bt, tk))
>> +            return -1;
>> +    BINTIME_TO_TIMEVAL(&bt, tvp);
>> +    return 0;
>> +}
>> +
>> +int
>> +_nanotime(struct timespec *tsp, struct timekeep *tk)
>> +{
>> +    struct bintime bt;
>> +
>> +    if (bintime(&bt, tk))
>> +            return -1;
>> +    BINTIME_TO_TIMESPEC(&bt, tsp);
>> +    return 0;
>> +}
>> +
>> +int
>> +_nanoruntime(struct timespec *ts, struct timekeep *tk)
>> +{
>> +    struct bintime bt;
>> +
>> +    if (binruntime(&bt, tk))
>> +            return -1;
>> +    BINTIME_TO_TIMESPEC(&bt, ts);
>> +    return 0;
>> +}
>> +
>> +
>> +int
>> +_nanouptime(struct timespec *tsp, struct timekeep *tk)
>> +{
>> +    struct bintime bt;
>> +
>> +    if (binuptime(&bt, tk))
>> +            return -1;
>> +    BINTIME_TO_TIMESPEC(&bt, tsp);
>> +    return 0;
>> +}
>> diff --git lib/libc/sys/w_clock_gettime.c
>lib/libc/sys/w_clock_gettime.c
>> new file mode 100644
>> index 00000000000..6e6478bd131
>> --- /dev/null
>> +++ lib/libc/sys/w_clock_gettime.c
>> @@ -0,0 +1,51 @@
>> +/*  $OpenBSD$ */
>> +/*
>> + * Copyright (c) 2020 Paul Irofti <p...@irofti.net>
>> + *
>> + * Permission to use, copy, modify, and distribute this software for
>any
>> + * purpose with or without fee is hereby granted, provided that the
>above
>> + * copyright notice and this permission notice appear in all copies.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
>WARRANTIES
>> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
>> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE
>LIABLE FOR
>> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
>DAMAGES
>> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
>IN AN
>> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
>OUT OF
>> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>> + */
>> +
>> +#include <sys/timetc.h>
>> +
>> +#include <time.h>
>> +
>> +int
>> +WRAP(clock_gettime)(clockid_t clock_id, struct timespec *tp)
>> +{
>> +    int rc = 0;
>> +    struct timekeep *timekeep = _timekeep;
>> +
>> +    if (timekeep == NULL || timekeep->tk_user == 0)
>> +            return clock_gettime(clock_id, tp);
>> +
>> +    switch (clock_id) {
>> +    case CLOCK_REALTIME:
>> +            rc = _nanotime(tp, timekeep);
>> +            break;
>> +    case CLOCK_UPTIME:
>> +            rc = _nanoruntime(tp, timekeep);
>> +            break;
>> +    case CLOCK_MONOTONIC:
>> +    case CLOCK_BOOTTIME:
>> +            rc = _nanouptime(tp, timekeep);
>> +            break;
>> +    default:
>> +            return clock_gettime(clock_id, tp);
>> +    }
>> +
>> +    if (rc)
>> +            return clock_gettime(clock_id, tp);
>> +
>> +    return 0;
>> +}
>> +DEF_WRAP(clock_gettime);
>> diff --git lib/libc/sys/w_gettimeofday.c
>lib/libc/sys/w_gettimeofday.c
>> new file mode 100644
>> index 00000000000..f44edfbb1ad
>> --- /dev/null
>> +++ lib/libc/sys/w_gettimeofday.c
>> @@ -0,0 +1,40 @@
>> +/*  $OpenBSD$ */
>> +/*
>> + * Copyright (c) 2020 Robert Nagy <rob...@openbsd.org>
>> + *
>> + * Permission to use, copy, modify, and distribute this software for
>any
>> + * purpose with or without fee is hereby granted, provided that the
>above
>> + * copyright notice and this permission notice appear in all copies.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
>WARRANTIES
>> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
>> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE
>LIABLE FOR
>> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
>DAMAGES
>> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
>IN AN
>> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
>OUT OF
>> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>> + */
>> +
>> +#include <sys/timetc.h>
>> +
>> +int
>> +WRAP(gettimeofday)(struct timeval *tp, struct timezone *tzp)
>> +{
>> +    int rc = 0;
>> +    struct timekeep *timekeep = _timekeep;
>> +    static struct timezone zerotz = { 0, 0 };
>> +
>> +    if (timekeep == NULL || timekeep->tk_user == 0)
>> +            return gettimeofday(tp, tzp);
>> +
>> +    if (tp)
>> +            rc = _microtime(tp, timekeep);
>> +    if (rc)
>> +            return gettimeofday(tp, tzp);
>> +
>> +    if (tzp)
>> +            *tzp = zerotz;
>> +
>> +    return 0;
>> +}
>> +DEF_WRAP(gettimeofday);
>> diff --git lib/libc/thread/synch.h lib/libc/thread/synch.h
>> index 788890add89..df2239438d2 100644
>> --- lib/libc/thread/synch.h
>> +++ lib/libc/thread/synch.h
>> @@ -33,7 +33,7 @@ _twait(volatile uint32_t *p, int val, clockid_t
>clockid, const struct timespec *
>>      if (abs == NULL)
>>              return futex(p, FUTEX_WAIT_PRIVATE, val, NULL, NULL);
>>  
>> -    if (abs->tv_nsec >= 1000000000 || clock_gettime(clockid, &rel))
>> +    if (abs->tv_nsec >= 1000000000 || WRAP(clock_gettime)(clockid,
>&rel))
>>              return (EINVAL);
>>  
>>      rel.tv_sec = abs->tv_sec - rel.tv_sec;
>> diff --git regress/lib/libc/timekeep/Makefile
>regress/lib/libc/timekeep/Makefile
>> new file mode 100644
>> index 00000000000..a7f3080290d
>> --- /dev/null
>> +++ regress/lib/libc/timekeep/Makefile
>> @@ -0,0 +1,5 @@
>> +#   $OpenBSD$
>> +
>> +PROGS=      test_clock_gettime test_time_skew test_gettimeofday
>> +
>> +.include <bsd.regress.mk>
>> diff --git regress/lib/libc/timekeep/test_clock_gettime.c
>regress/lib/libc/timekeep/test_clock_gettime.c
>> new file mode 100644
>> index 00000000000..859ec368215
>> --- /dev/null
>> +++ regress/lib/libc/timekeep/test_clock_gettime.c
>> @@ -0,0 +1,43 @@
>> +/*  $OpenBSD$ */
>> +/*
>> + * Copyright (c) 2020 Paul Irofti <p...@irofti.net>
>> + *
>> + * Permission to use, copy, modify, and distribute this software for
>any
>> + * purpose with or without fee is hereby granted, provided that the
>above
>> + * copyright notice and this permission notice appear in all copies.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
>WARRANTIES
>> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
>> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE
>LIABLE FOR
>> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
>DAMAGES
>> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
>IN AN
>> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
>OUT OF
>> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>> + */
>> +
>> +#include <assert.h>
>> +#include <time.h>
>> +
>> +#define ASSERT_EQ(a, b) assert((a) == (b))
>> +
>> +void
>> +check()
>> +{
>> +    struct timespec tp = {0};
>> +
>> +    ASSERT_EQ(0, clock_gettime(CLOCK_REALTIME, &tp));
>> +    ASSERT_EQ(0, clock_gettime(CLOCK_MONOTONIC, &tp));
>> +    ASSERT_EQ(0, clock_gettime(CLOCK_BOOTTIME, &tp));
>> +    ASSERT_EQ(0, clock_gettime(CLOCK_UPTIME, &tp));
>> +
>> +
>> +    ASSERT_EQ(0, clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tp));
>> +    ASSERT_EQ(0, clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp));
>> +
>> +}
>> +
>> +int main()
>> +{
>> +    check();
>> +    return 0;
>> +}
>> diff --git regress/lib/libc/timekeep/test_gettimeofday.c
>regress/lib/libc/timekeep/test_gettimeofday.c
>> new file mode 100644
>> index 00000000000..ea90a1be7e0
>> --- /dev/null
>> +++ regress/lib/libc/timekeep/test_gettimeofday.c
>> @@ -0,0 +1,37 @@
>> +/*  $OpenBSD$ */
>> +/*
>> + * Copyright (c) 2020 Paul Irofti <p...@irofti.net>
>> + *
>> + * Permission to use, copy, modify, and distribute this software for
>any
>> + * purpose with or without fee is hereby granted, provided that the
>above
>> + * copyright notice and this permission notice appear in all copies.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
>WARRANTIES
>> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
>> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE
>LIABLE FOR
>> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
>DAMAGES
>> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
>IN AN
>> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
>OUT OF
>> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>> + */
>> +
>> +#include <assert.h>
>> +#include <sys/time.h>
>> +
>> +#define ASSERT_EQ(a, b) assert((a) == (b))
>> +
>> +void
>> +check()
>> +{
>> +    struct timeval tv = {0};
>> +    struct timezone tzp;
>> +
>> +    ASSERT_EQ(0, gettimeofday(&tv, NULL));
>> +    ASSERT_EQ(0, gettimeofday(&tv, &tzp));
>> +}
>> +
>> +int main()
>> +{
>> +    check();
>> +    return 0;
>> +}
>> diff --git regress/lib/libc/timekeep/test_time_skew.c
>regress/lib/libc/timekeep/test_time_skew.c
>> new file mode 100644
>> index 00000000000..dfa9481c091
>> --- /dev/null
>> +++ regress/lib/libc/timekeep/test_time_skew.c
>> @@ -0,0 +1,55 @@
>> +/*  $OpenBSD$ */
>> +/*
>> + * Copyright (c) 2020 Paul Irofti <p...@irofti.net>
>> + *
>> + * Permission to use, copy, modify, and distribute this software for
>any
>> + * purpose with or without fee is hereby granted, provided that the
>above
>> + * copyright notice and this permission notice appear in all copies.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
>WARRANTIES
>> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
>> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE
>LIABLE FOR
>> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
>DAMAGES
>> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
>IN AN
>> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
>OUT OF
>> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>> + */
>> +
>> +#include <sys/time.h>
>> +
>> +#include <assert.h>
>> +#include <time.h>
>> +#include <stdlib.h>
>> +#include <stdio.h>
>> +
>> +#define ASSERT_EQ(a, b) assert((a) == (b))
>> +#define ASSERT_NE(a, b) assert((a) != (b))
>> +
>> +void
>> +check()
>> +{
>> +         struct timespec tp1, tp2, tout;
>> +
>> +         tout.tv_sec = 0;
>> +         tout.tv_nsec = 100000;
>> +
>> +         ASSERT_EQ(0, clock_gettime(CLOCK_MONOTONIC, &tp1));
>> +
>> +         nanosleep(&tout, NULL);
>> +
>> +         ASSERT_EQ(0, clock_gettime(CLOCK_MONOTONIC, &tp2));
>> +
>> +         /* tp1 should never be larger than tp2 */
>> +         ASSERT_NE(1, timespeccmp(&tp1, &tp2, >));
>> +}
>> +
>> +int
>> +main(void)
>> +{
>> +    int i;
>> +
>> +    for (i = 0; i < 1000; i++)
>> +            check();
>> +
>> +    return 0;
>> +}
>> diff --git sys/arch/alpha/alpha/clock.c sys/arch/alpha/alpha/clock.c
>> index 3f5f2c5b42b..6eaf8b107c6 100644
>> --- sys/arch/alpha/alpha/clock.c
>> +++ sys/arch/alpha/alpha/clock.c
>> @@ -64,7 +64,7 @@ int clk_irq = 0;
>>  
>>  u_int rpcc_get_timecount(struct timecounter *);
>>  struct timecounter rpcc_timecounter = {
>> -    rpcc_get_timecount, NULL, ~0u, 0, "rpcc", 0, NULL
>> +    rpcc_get_timecount, NULL, ~0u, 0, "rpcc", 0, NULL, 0
>>  };
>>  
>>  extern todr_chip_handle_t todr_handle;
>> diff --git sys/arch/alpha/include/timetc.h
>sys/arch/alpha/include/timetc.h
>> new file mode 100644
>> index 00000000000..e58a7fb4faa
>> --- /dev/null
>> +++ sys/arch/alpha/include/timetc.h
>> @@ -0,0 +1,23 @@
>> +/*  $OpenBSD$ */
>> +/*
>> + * Copyright (c) 2020 Paul Irofti <p...@irofti.net>
>> + *
>> + * Permission to use, copy, modify, and distribute this software for
>any
>> + * purpose with or without fee is hereby granted, provided that the
>above
>> + * copyright notice and this permission notice appear in all copies.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
>WARRANTIES
>> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
>> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE
>LIABLE FOR
>> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
>DAMAGES
>> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
>IN AN
>> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
>OUT OF
>> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>> + */
>> +
>> +#ifndef _MACHINE_TIMETC_H_
>> +#define _MACHINE_TIMETC_H_
>> +
>> +#define     TC_LAST 0
>> +
>> +#endif      /* _MACHINE_TIMETC_H_ */
>> diff --git sys/arch/amd64/amd64/tsc.c sys/arch/amd64/amd64/tsc.c
>> index 7a1dcb4ad75..5839fa15d6c 100644
>> --- sys/arch/amd64/amd64/tsc.c
>> +++ sys/arch/amd64/amd64/tsc.c
>> @@ -42,7 +42,7 @@ int64_t    tsc_drift_observed;
>>  volatile int64_t    tsc_sync_val;
>>  volatile struct cpu_info    *tsc_sync_cpu;
>>  
>> -uint                tsc_get_timecount(struct timecounter *tc);
>> +u_int               tsc_get_timecount(struct timecounter *tc);
>>  
>>  #include "lapic.h"
>>  #if NLAPIC > 0
>> @@ -50,7 +50,7 @@ extern u_int32_t lapic_per_second;
>>  #endif
>>  
>>  struct timecounter tsc_timecounter = {
>> -    tsc_get_timecount, NULL, ~0u, 0, "tsc", -1000, NULL
>> +    tsc_get_timecount, NULL, ~0u, 0, "tsc", -1000, NULL, TC_TSC
>>  };
>>  
>>  uint64_t
>> @@ -244,6 +244,7 @@ tsc_timecounter_init(struct cpu_info *ci,
>uint64_t cpufreq)
>>              printf("ERROR: %lld cycle TSC drift observed\n",
>>                  (long long)tsc_drift_observed);
>>              tsc_timecounter.tc_quality = -1000;
>> +            tsc_timecounter.tc_user = 0;
>>              tsc_is_invariant = 0;
>>      }
>>  
>> diff --git sys/arch/amd64/include/timetc.h
>sys/arch/amd64/include/timetc.h
>> new file mode 100644
>> index 00000000000..c2d40bcd1e7
>> --- /dev/null
>> +++ sys/arch/amd64/include/timetc.h
>> @@ -0,0 +1,24 @@
>> +/*  $OpenBSD$ */
>> +/*
>> + * Copyright (c) 2020 Paul Irofti <p...@irofti.net>
>> + *
>> + * Permission to use, copy, modify, and distribute this software for
>any
>> + * purpose with or without fee is hereby granted, provided that the
>above
>> + * copyright notice and this permission notice appear in all copies.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
>WARRANTIES
>> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
>> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE
>LIABLE FOR
>> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
>DAMAGES
>> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
>IN AN
>> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
>OUT OF
>> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>> + */
>> +
>> +#ifndef _MACHINE_TIMETC_H_
>> +#define _MACHINE_TIMETC_H_
>> +
>> +#define     TC_TSC  1
>> +#define     TC_LAST 2
>> +
>> +#endif      /* _MACHINE_TIMETC_H_ */
>> diff --git sys/arch/amd64/isa/clock.c sys/arch/amd64/isa/clock.c
>> index 613f7ee0e0f..00da0c6a8d0 100644
>> --- sys/arch/amd64/isa/clock.c
>> +++ sys/arch/amd64/isa/clock.c
>> @@ -116,7 +116,7 @@ u_int i8254_get_timecount(struct timecounter
>*tc);
>>  u_int i8254_simple_get_timecount(struct timecounter *tc);
>>  
>>  static struct timecounter i8254_timecounter = {
>> -    i8254_get_timecount, NULL, ~0u, TIMER_FREQ, "i8254", 0, NULL
>> +    i8254_get_timecount, NULL, ~0u, TIMER_FREQ, "i8254", 0, NULL, 0
>>  };
>>  
>>  int clockintr(void *);
>> diff --git sys/arch/arm/include/timetc.h
>sys/arch/arm/include/timetc.h
>> new file mode 100644
>> index 00000000000..e58a7fb4faa
>> --- /dev/null
>> +++ sys/arch/arm/include/timetc.h
>> @@ -0,0 +1,23 @@
>> +/*  $OpenBSD$ */
>> +/*
>> + * Copyright (c) 2020 Paul Irofti <p...@irofti.net>
>> + *
>> + * Permission to use, copy, modify, and distribute this software for
>any
>> + * purpose with or without fee is hereby granted, provided that the
>above
>> + * copyright notice and this permission notice appear in all copies.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
>WARRANTIES
>> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
>> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE
>LIABLE FOR
>> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
>DAMAGES
>> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
>IN AN
>> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
>OUT OF
>> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>> + */
>> +
>> +#ifndef _MACHINE_TIMETC_H_
>> +#define _MACHINE_TIMETC_H_
>> +
>> +#define     TC_LAST 0
>> +
>> +#endif      /* _MACHINE_TIMETC_H_ */
>> diff --git sys/arch/arm64/dev/agtimer.c sys/arch/arm64/dev/agtimer.c
>> index 11196b5c60d..1a2106ef94c 100644
>> --- sys/arch/arm64/dev/agtimer.c
>> +++ sys/arch/arm64/dev/agtimer.c
>> @@ -43,7 +43,7 @@ int32_t agtimer_frequency = TIMER_FREQUENCY;
>>  u_int agtimer_get_timecount(struct timecounter *);
>>  
>>  static struct timecounter agtimer_timecounter = {
>> -    agtimer_get_timecount, NULL, 0x7fffffff, 0, "agtimer", 0, NULL
>> +    agtimer_get_timecount, NULL, 0x7fffffff, 0, "agtimer", 0, NULL, 0
>>  };
>>  
>>  struct agtimer_pcpu_softc {
>> diff --git sys/arch/arm64/include/timetc.h
>sys/arch/arm64/include/timetc.h
>> new file mode 100644
>> index 00000000000..e58a7fb4faa
>> --- /dev/null
>> +++ sys/arch/arm64/include/timetc.h
>> @@ -0,0 +1,23 @@
>> +/*  $OpenBSD$ */
>> +/*
>> + * Copyright (c) 2020 Paul Irofti <p...@irofti.net>
>> + *
>> + * Permission to use, copy, modify, and distribute this software for
>any
>> + * purpose with or without fee is hereby granted, provided that the
>above
>> + * copyright notice and this permission notice appear in all copies.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
>WARRANTIES
>> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
>> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE
>LIABLE FOR
>> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
>DAMAGES
>> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
>IN AN
>> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
>OUT OF
>> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>> + */
>> +
>> +#ifndef _MACHINE_TIMETC_H_
>> +#define _MACHINE_TIMETC_H_
>> +
>> +#define     TC_LAST 0
>> +
>> +#endif      /* _MACHINE_TIMETC_H_ */
>> diff --git sys/arch/armv7/include/timetc.h
>sys/arch/armv7/include/timetc.h
>> new file mode 100644
>> index 00000000000..e58a7fb4faa
>> --- /dev/null
>> +++ sys/arch/armv7/include/timetc.h
>> @@ -0,0 +1,23 @@
>> +/*  $OpenBSD$ */
>> +/*
>> + * Copyright (c) 2020 Paul Irofti <p...@irofti.net>
>> + *
>> + * Permission to use, copy, modify, and distribute this software for
>any
>> + * purpose with or without fee is hereby granted, provided that the
>above
>> + * copyright notice and this permission notice appear in all copies.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
>WARRANTIES
>> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
>> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE
>LIABLE FOR
>> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
>DAMAGES
>> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
>IN AN
>> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
>OUT OF
>> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>> + */
>> +
>> +#ifndef _MACHINE_TIMETC_H_
>> +#define _MACHINE_TIMETC_H_
>> +
>> +#define     TC_LAST 0
>> +
>> +#endif      /* _MACHINE_TIMETC_H_ */
>> diff --git sys/arch/armv7/omap/gptimer.c
>sys/arch/armv7/omap/gptimer.c
>> index 7605845d5e2..061542d532f 100644
>> --- sys/arch/armv7/omap/gptimer.c
>> +++ sys/arch/armv7/omap/gptimer.c
>> @@ -117,7 +117,7 @@ int gptimer_irq = 0;
>>  u_int gptimer_get_timecount(struct timecounter *);
>>  
>>  static struct timecounter gptimer_timecounter = {
>> -    gptimer_get_timecount, NULL, 0x7fffffff, 0, "gptimer", 0, NULL
>> +    gptimer_get_timecount, NULL, 0x7fffffff, 0, "gptimer", 0, NULL, 0
>>  };
>>  
>>  volatile u_int32_t nexttickevent;
>> diff --git sys/arch/armv7/sunxi/sxitimer.c
>sys/arch/armv7/sunxi/sxitimer.c
>> index 14a243c78d0..41028f9a602 100644
>> --- sys/arch/armv7/sunxi/sxitimer.c
>> +++ sys/arch/armv7/sunxi/sxitimer.c
>> @@ -89,7 +89,7 @@ void       sxitimer_delay(u_int);
>>  u_int sxitimer_get_timecount(struct timecounter *);
>>  
>>  static struct timecounter sxitimer_timecounter = {
>> -    sxitimer_get_timecount, NULL, 0xffffffff, 0, "sxitimer", 0, NULL
>> +    sxitimer_get_timecount, NULL, 0xffffffff, 0, "sxitimer", 0, NULL, 0
>>  };
>>  
>>  bus_space_tag_t             sxitimer_iot;
>> diff --git sys/arch/hppa/dev/clock.c sys/arch/hppa/dev/clock.c
>> index 4c594ab5ec7..8cce6c3a893 100644
>> --- sys/arch/hppa/dev/clock.c
>> +++ sys/arch/hppa/dev/clock.c
>> @@ -47,7 +47,7 @@ int        cpu_hardclock(void *);
>>  u_int       itmr_get_timecount(struct timecounter *);
>>  
>>  struct timecounter itmr_timecounter = {
>> -    itmr_get_timecount, NULL, 0xffffffff, 0, "itmr", 0, NULL
>> +    itmr_get_timecount, NULL, 0xffffffff, 0, "itmr", 0, NULL, 0
>>  };
>>  
>>  extern todr_chip_handle_t todr_handle;
>> diff --git sys/arch/hppa/include/timetc.h
>sys/arch/hppa/include/timetc.h
>> new file mode 100644
>> index 00000000000..e58a7fb4faa
>> --- /dev/null
>> +++ sys/arch/hppa/include/timetc.h
>> @@ -0,0 +1,23 @@
>> +/*  $OpenBSD$ */
>> +/*
>> + * Copyright (c) 2020 Paul Irofti <p...@irofti.net>
>> + *
>> + * Permission to use, copy, modify, and distribute this software for
>any
>> + * purpose with or without fee is hereby granted, provided that the
>above
>> + * copyright notice and this permission notice appear in all copies.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
>WARRANTIES
>> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
>> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE
>LIABLE FOR
>> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
>DAMAGES
>> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
>IN AN
>> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
>OUT OF
>> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>> + */
>> +
>> +#ifndef _MACHINE_TIMETC_H_
>> +#define _MACHINE_TIMETC_H_
>> +
>> +#define     TC_LAST 0
>> +
>> +#endif      /* _MACHINE_TIMETC_H_ */
>> diff --git sys/arch/i386/include/timetc.h
>sys/arch/i386/include/timetc.h
>> new file mode 100644
>> index 00000000000..e58a7fb4faa
>> --- /dev/null
>> +++ sys/arch/i386/include/timetc.h
>> @@ -0,0 +1,23 @@
>> +/*  $OpenBSD$ */
>> +/*
>> + * Copyright (c) 2020 Paul Irofti <p...@irofti.net>
>> + *
>> + * Permission to use, copy, modify, and distribute this software for
>any
>> + * purpose with or without fee is hereby granted, provided that the
>above
>> + * copyright notice and this permission notice appear in all copies.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
>WARRANTIES
>> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
>> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE
>LIABLE FOR
>> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
>DAMAGES
>> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
>IN AN
>> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
>OUT OF
>> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>> + */
>> +
>> +#ifndef _MACHINE_TIMETC_H_
>> +#define _MACHINE_TIMETC_H_
>> +
>> +#define     TC_LAST 0
>> +
>> +#endif      /* _MACHINE_TIMETC_H_ */
>> diff --git sys/arch/i386/isa/clock.c sys/arch/i386/isa/clock.c
>> index 09a6db983f2..dd74bd425ad 100644
>> --- sys/arch/i386/isa/clock.c
>> +++ sys/arch/i386/isa/clock.c
>> @@ -129,7 +129,7 @@ u_int i8254_get_timecount(struct timecounter
>*tc);
>>  u_int i8254_simple_get_timecount(struct timecounter *tc);
>>  
>>  static struct timecounter i8254_timecounter = {
>> -    i8254_get_timecount, NULL, ~0u, TIMER_FREQ, "i8254", 0, NULL
>> +    i8254_get_timecount, NULL, ~0u, TIMER_FREQ, "i8254", 0, NULL, 0
>>  };
>>  struct mutex timer_mutex = MUTEX_INITIALIZER(IPL_HIGH);
>>  u_long rtclock_tval;
>> diff --git sys/arch/i386/pci/geodesc.c sys/arch/i386/pci/geodesc.c
>> index 9d9f061eef9..bb8e4c7f9ae 100644
>> --- sys/arch/i386/pci/geodesc.c
>> +++ sys/arch/i386/pci/geodesc.c
>> @@ -65,7 +65,9 @@ struct timecounter geodesc_timecounter = {
>>      0xffffffff,             /* counter_mask */
>>      27000000,               /* frequency */
>>      "GEOTSC",               /* name */
>> -    2000                    /* quality */
>> +    2000,                   /* quality */
>> +    NULL,                   /* private bits */
>> +    0                       /* expose to user */
>>  };
>>  
>>  int
>> diff --git sys/arch/i386/pci/gscpm.c sys/arch/i386/pci/gscpm.c
>> index 8b8aa4ac430..a6f324e66f3 100644
>> --- sys/arch/i386/pci/gscpm.c
>> +++ sys/arch/i386/pci/gscpm.c
>> @@ -55,7 +55,9 @@ struct timecounter gscpm_timecounter = {
>>      0xffffff,               /* counter_mask */
>>      3579545,                /* frequency */
>>      "GSCPM",                /* name */
>> -    1000                    /* quality */
>> +    1000,                   /* quality */
>> +    NULL,                   /* private bits */
>> +    0                       /* expose to user */
>>  };
>>  
>>  struct cfattach gscpm_ca = {
>> diff --git sys/arch/i386/pci/ichpcib.c sys/arch/i386/pci/ichpcib.c
>> index 6abf1627de2..629a86a14ff 100644
>> --- sys/arch/i386/pci/ichpcib.c
>> +++ sys/arch/i386/pci/ichpcib.c
>> @@ -63,7 +63,9 @@ struct timecounter ichpcib_timecounter = {
>>      0xffffff,               /* counter_mask */
>>      3579545,                /* frequency */
>>      "ICHPM",                /* name */
>> -    1000                    /* quality */
>> +    1000,                   /* quality */
>> +    NULL,                   /* private bits */
>> +    0                       /* expose to user */
>>  };
>>  
>>  struct cfattach ichpcib_ca = {
>> diff --git sys/arch/landisk/include/timetc.h
>sys/arch/landisk/include/timetc.h
>> new file mode 100644
>> index 00000000000..e58a7fb4faa
>> --- /dev/null
>> +++ sys/arch/landisk/include/timetc.h
>> @@ -0,0 +1,23 @@
>> +/*  $OpenBSD$ */
>> +/*
>> + * Copyright (c) 2020 Paul Irofti <p...@irofti.net>
>> + *
>> + * Permission to use, copy, modify, and distribute this software for
>any
>> + * purpose with or without fee is hereby granted, provided that the
>above
>> + * copyright notice and this permission notice appear in all copies.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
>WARRANTIES
>> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
>> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE
>LIABLE FOR
>> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
>DAMAGES
>> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
>IN AN
>> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
>OUT OF
>> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>> + */
>> +
>> +#ifndef _MACHINE_TIMETC_H_
>> +#define _MACHINE_TIMETC_H_
>> +
>> +#define     TC_LAST 0
>> +
>> +#endif      /* _MACHINE_TIMETC_H_ */
>> diff --git sys/arch/loongson/include/timetc.h
>sys/arch/loongson/include/timetc.h
>> new file mode 100644
>> index 00000000000..e58a7fb4faa
>> --- /dev/null
>> +++ sys/arch/loongson/include/timetc.h
>> @@ -0,0 +1,23 @@
>> +/*  $OpenBSD$ */
>> +/*
>> + * Copyright (c) 2020 Paul Irofti <p...@irofti.net>
>> + *
>> + * Permission to use, copy, modify, and distribute this software for
>any
>> + * purpose with or without fee is hereby granted, provided that the
>above
>> + * copyright notice and this permission notice appear in all copies.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
>WARRANTIES
>> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
>> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE
>LIABLE FOR
>> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
>DAMAGES
>> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
>IN AN
>> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
>OUT OF
>> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>> + */
>> +
>> +#ifndef _MACHINE_TIMETC_H_
>> +#define _MACHINE_TIMETC_H_
>> +
>> +#define     TC_LAST 0
>> +
>> +#endif      /* _MACHINE_TIMETC_H_ */
>> diff --git sys/arch/loongson/loongson/generic3a_machdep.c
>sys/arch/loongson/loongson/generic3a_machdep.c
>> index ac3f1db6ccd..53489b07549 100644
>> --- sys/arch/loongson/loongson/generic3a_machdep.c
>> +++ sys/arch/loongson/loongson/generic3a_machdep.c
>> @@ -98,7 +98,9 @@ struct timecounter rs780e_timecounter = {
>>      .tc_counter_mask = 0xffffffffu, /* truncated to 32 bits */
>>      .tc_frequency = HPET_FREQ,
>>      .tc_name = "hpet",
>> -    .tc_quality = 100
>> +    .tc_quality = 100,
>> +    .tc_priv = NULL,
>> +    .tc_user = 0,
>>  };
>>  
>>  /* Firmware entry points */
>> diff --git sys/arch/luna88k/include/timetc.h
>sys/arch/luna88k/include/timetc.h
>> new file mode 100644
>> index 00000000000..e58a7fb4faa
>> --- /dev/null
>> +++ sys/arch/luna88k/include/timetc.h
>> @@ -0,0 +1,23 @@
>> +/*  $OpenBSD$ */
>> +/*
>> + * Copyright (c) 2020 Paul Irofti <p...@irofti.net>
>> + *
>> + * Permission to use, copy, modify, and distribute this software for
>any
>> + * purpose with or without fee is hereby granted, provided that the
>above
>> + * copyright notice and this permission notice appear in all copies.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
>WARRANTIES
>> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
>> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE
>LIABLE FOR
>> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
>DAMAGES
>> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
>IN AN
>> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
>OUT OF
>> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>> + */
>> +
>> +#ifndef _MACHINE_TIMETC_H_
>> +#define _MACHINE_TIMETC_H_
>> +
>> +#define     TC_LAST 0
>> +
>> +#endif      /* _MACHINE_TIMETC_H_ */
>> diff --git sys/arch/luna88k/luna88k/clock.c
>sys/arch/luna88k/luna88k/clock.c
>> index a04120987e0..6580a4a46bf 100644
>> --- sys/arch/luna88k/luna88k/clock.c
>> +++ sys/arch/luna88k/luna88k/clock.c
>> @@ -112,7 +112,9 @@ struct timecounter clock_tc = {
>>      .tc_counter_mask = 0xffffffff,
>>      .tc_frequency = 0, /* will be filled in */
>>      .tc_name = "clock",
>> -    .tc_quality = 0
>> +    .tc_quality = 0,
>> +    .tc_priv = NULL,
>> +    .tc_user = 0,
>>  };
>>  
>>  /*
>> diff --git sys/arch/m88k/include/timetc.h
>sys/arch/m88k/include/timetc.h
>> new file mode 100644
>> index 00000000000..e58a7fb4faa
>> --- /dev/null
>> +++ sys/arch/m88k/include/timetc.h
>> @@ -0,0 +1,23 @@
>> +/*  $OpenBSD$ */
>> +/*
>> + * Copyright (c) 2020 Paul Irofti <p...@irofti.net>
>> + *
>> + * Permission to use, copy, modify, and distribute this software for
>any
>> + * purpose with or without fee is hereby granted, provided that the
>above
>> + * copyright notice and this permission notice appear in all copies.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
>WARRANTIES
>> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
>> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE
>LIABLE FOR
>> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
>DAMAGES
>> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
>IN AN
>> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
>OUT OF
>> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>> + */
>> +
>> +#ifndef _MACHINE_TIMETC_H_
>> +#define _MACHINE_TIMETC_H_
>> +
>> +#define     TC_LAST 0
>> +
>> +#endif      /* _MACHINE_TIMETC_H_ */
>> diff --git sys/arch/macppc/include/timetc.h
>sys/arch/macppc/include/timetc.h
>> new file mode 100644
>> index 00000000000..e58a7fb4faa
>> --- /dev/null
>> +++ sys/arch/macppc/include/timetc.h
>> @@ -0,0 +1,23 @@
>> +/*  $OpenBSD$ */
>> +/*
>> + * Copyright (c) 2020 Paul Irofti <p...@irofti.net>
>> + *
>> + * Permission to use, copy, modify, and distribute this software for
>any
>> + * purpose with or without fee is hereby granted, provided that the
>above
>> + * copyright notice and this permission notice appear in all copies.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
>WARRANTIES
>> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
>> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE
>LIABLE FOR
>> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
>DAMAGES
>> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
>IN AN
>> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
>OUT OF
>> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>> + */
>> +
>> +#ifndef _MACHINE_TIMETC_H_
>> +#define _MACHINE_TIMETC_H_
>> +
>> +#define     TC_LAST 0
>> +
>> +#endif      /* _MACHINE_TIMETC_H_ */
>> diff --git sys/arch/macppc/macppc/clock.c
>sys/arch/macppc/macppc/clock.c
>> index 4a44a92cfc0..8c3ad620be8 100644
>> --- sys/arch/macppc/macppc/clock.c
>> +++ sys/arch/macppc/macppc/clock.c
>> @@ -57,7 +57,7 @@ u_int32_t ns_per_tick = 320;
>>  static int32_t ticks_per_intr;
>>  
>>  static struct timecounter tb_timecounter = {
>> -    tb_get_timecount, NULL, 0x7fffffff, 0, "tb", 0, NULL
>> +    tb_get_timecount, NULL, 0x7fffffff, 0, "tb", 0, NULL, 0
>>  };
>>  
>>  /* calibrate the timecounter frequency for the listed models */
>> diff --git sys/arch/mips64/include/timetc.h
>sys/arch/mips64/include/timetc.h
>> new file mode 100644
>> index 00000000000..e58a7fb4faa
>> --- /dev/null
>> +++ sys/arch/mips64/include/timetc.h
>> @@ -0,0 +1,23 @@
>> +/*  $OpenBSD$ */
>> +/*
>> + * Copyright (c) 2020 Paul Irofti <p...@irofti.net>
>> + *
>> + * Permission to use, copy, modify, and distribute this software for
>any
>> + * purpose with or without fee is hereby granted, provided that the
>above
>> + * copyright notice and this permission notice appear in all copies.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
>WARRANTIES
>> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
>> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE
>LIABLE FOR
>> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
>DAMAGES
>> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
>IN AN
>> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
>OUT OF
>> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>> + */
>> +
>> +#ifndef _MACHINE_TIMETC_H_
>> +#define _MACHINE_TIMETC_H_
>> +
>> +#define     TC_LAST 0
>> +
>> +#endif      /* _MACHINE_TIMETC_H_ */
>> diff --git sys/arch/mips64/mips64/mips64_machdep.c
>sys/arch/mips64/mips64/mips64_machdep.c
>> index d4a42ed5acc..5c4dbadb5bb 100644
>> --- sys/arch/mips64/mips64/mips64_machdep.c
>> +++ sys/arch/mips64/mips64/mips64_machdep.c
>> @@ -327,7 +327,9 @@ struct timecounter cp0_timecounter = {
>>      0xffffffff,             /* counter_mask */
>>      0,                      /* frequency */
>>      "CP0",                  /* name */
>> -    0                       /* quality */
>> +    0,                      /* quality */
>> +    NULL,                   /* private bits */
>> +    0,                      /* expose to user */
>>  };
>>  
>>  u_int
>> diff --git sys/arch/octeon/include/timetc.h
>sys/arch/octeon/include/timetc.h
>> new file mode 100644
>> index 00000000000..e58a7fb4faa
>> --- /dev/null
>> +++ sys/arch/octeon/include/timetc.h
>> @@ -0,0 +1,23 @@
>> +/*  $OpenBSD$ */
>> +/*
>> + * Copyright (c) 2020 Paul Irofti <p...@irofti.net>
>> + *
>> + * Permission to use, copy, modify, and distribute this software for
>any
>> + * purpose with or without fee is hereby granted, provided that the
>above
>> + * copyright notice and this permission notice appear in all copies.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
>WARRANTIES
>> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
>> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE
>LIABLE FOR
>> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
>DAMAGES
>> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
>IN AN
>> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
>OUT OF
>> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>> + */
>> +
>> +#ifndef _MACHINE_TIMETC_H_
>> +#define _MACHINE_TIMETC_H_
>> +
>> +#define     TC_LAST 0
>> +
>> +#endif      /* _MACHINE_TIMETC_H_ */
>> diff --git sys/arch/octeon/octeon/machdep.c
>sys/arch/octeon/octeon/machdep.c
>> index 902e462d53f..d8377653abe 100644
>> --- sys/arch/octeon/octeon/machdep.c
>> +++ sys/arch/octeon/octeon/machdep.c
>> @@ -151,8 +151,9 @@ struct timecounter ioclock_timecounter = {
>>      .tc_name = "ioclock",
>>      .tc_quality = 0,                /* ioclock can be overridden
>>                                       * by cp0 counter */
>> -    .tc_priv = 0                    /* clock register,
>> +    .tc_priv = 0,                   /* clock register,
>>                                       * determined at runtime */
>> +    .tc_user = 0,                   /* expose to user */
>>  };
>>  
>>  static int
>> diff --git sys/arch/powerpc/include/timetc.h
>sys/arch/powerpc/include/timetc.h
>> new file mode 100644
>> index 00000000000..e58a7fb4faa
>> --- /dev/null
>> +++ sys/arch/powerpc/include/timetc.h
>> @@ -0,0 +1,23 @@
>> +/*  $OpenBSD$ */
>> +/*
>> + * Copyright (c) 2020 Paul Irofti <p...@irofti.net>
>> + *
>> + * Permission to use, copy, modify, and distribute this software for
>any
>> + * purpose with or without fee is hereby granted, provided that the
>above
>> + * copyright notice and this permission notice appear in all copies.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
>WARRANTIES
>> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
>> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE
>LIABLE FOR
>> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
>DAMAGES
>> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
>IN AN
>> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
>OUT OF
>> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>> + */
>> +
>> +#ifndef _MACHINE_TIMETC_H_
>> +#define _MACHINE_TIMETC_H_
>> +
>> +#define     TC_LAST 0
>> +
>> +#endif      /* _MACHINE_TIMETC_H_ */
>> diff --git sys/arch/powerpc64/include/timetc.h
>sys/arch/powerpc64/include/timetc.h
>> new file mode 100644
>> index 00000000000..e58a7fb4faa
>> --- /dev/null
>> +++ sys/arch/powerpc64/include/timetc.h
>> @@ -0,0 +1,23 @@
>> +/*  $OpenBSD$ */
>> +/*
>> + * Copyright (c) 2020 Paul Irofti <p...@irofti.net>
>> + *
>> + * Permission to use, copy, modify, and distribute this software for
>any
>> + * purpose with or without fee is hereby granted, provided that the
>above
>> + * copyright notice and this permission notice appear in all copies.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
>WARRANTIES
>> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
>> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE
>LIABLE FOR
>> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
>DAMAGES
>> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
>IN AN
>> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
>OUT OF
>> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>> + */
>> +
>> +#ifndef _MACHINE_TIMETC_H_
>> +#define _MACHINE_TIMETC_H_
>> +
>> +#define     TC_LAST 0
>> +
>> +#endif      /* _MACHINE_TIMETC_H_ */
>> diff --git sys/arch/sgi/include/timetc.h
>sys/arch/sgi/include/timetc.h
>> new file mode 100644
>> index 00000000000..e58a7fb4faa
>> --- /dev/null
>> +++ sys/arch/sgi/include/timetc.h
>> @@ -0,0 +1,23 @@
>> +/*  $OpenBSD$ */
>> +/*
>> + * Copyright (c) 2020 Paul Irofti <p...@irofti.net>
>> + *
>> + * Permission to use, copy, modify, and distribute this software for
>any
>> + * purpose with or without fee is hereby granted, provided that the
>above
>> + * copyright notice and this permission notice appear in all copies.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
>WARRANTIES
>> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
>> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE
>LIABLE FOR
>> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
>DAMAGES
>> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
>IN AN
>> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
>OUT OF
>> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>> + */
>> +
>> +#ifndef _MACHINE_TIMETC_H_
>> +#define _MACHINE_TIMETC_H_
>> +
>> +#define     TC_LAST 0
>> +
>> +#endif      /* _MACHINE_TIMETC_H_ */
>> diff --git sys/arch/sgi/sgi/ip27_machdep.c
>sys/arch/sgi/sgi/ip27_machdep.c
>> index ba7fa558b96..2a2cc144242 100644
>> --- sys/arch/sgi/sgi/ip27_machdep.c
>> +++ sys/arch/sgi/sgi/ip27_machdep.c
>> @@ -111,7 +111,9 @@ struct timecounter ip27_hub_timecounter = {
>>      .tc_counter_mask = 0xffffffff,  /* truncated to 32 bits. */
>>      .tc_frequency = 1250000,
>>      .tc_name = "hubrt",
>> -    .tc_quality = 100
>> +    .tc_quality = 100,
>> +    .tc_priv = 0,
>> +    .tc_user = 0,
>>  };
>>  
>>  volatile uint64_t   ip27_spinup_a0;
>> diff --git sys/arch/sgi/xbow/xheart.c sys/arch/sgi/xbow/xheart.c
>> index 56b29915c70..827775512ac 100644
>> --- sys/arch/sgi/xbow/xheart.c
>> +++ sys/arch/sgi/xbow/xheart.c
>> @@ -83,7 +83,9 @@ struct timecounter xheart_timecounter = {
>>      .tc_counter_mask = 0xffffffff,  /* truncate 52-bit counter to 32-bit
>*/
>>      .tc_frequency = 12500000,
>>      .tc_name = "heart",
>> -    .tc_quality = 100
>> +    .tc_quality = 100,
>> +    .tc_priv = NULL,
>> +    .tc_user = 0,
>>  };
>>  
>>  extern uint32_t ip30_lights_frob(uint32_t, struct trapframe *);
>> diff --git sys/arch/sh/include/timetc.h sys/arch/sh/include/timetc.h
>> new file mode 100644
>> index 00000000000..e58a7fb4faa
>> --- /dev/null
>> +++ sys/arch/sh/include/timetc.h
>> @@ -0,0 +1,23 @@
>> +/*  $OpenBSD$ */
>> +/*
>> + * Copyright (c) 2020 Paul Irofti <p...@irofti.net>
>> + *
>> + * Permission to use, copy, modify, and distribute this software for
>any
>> + * purpose with or without fee is hereby granted, provided that the
>above
>> + * copyright notice and this permission notice appear in all copies.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
>WARRANTIES
>> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
>> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE
>LIABLE FOR
>> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
>DAMAGES
>> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
>IN AN
>> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
>OUT OF
>> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>> + */
>> +
>> +#ifndef _MACHINE_TIMETC_H_
>> +#define _MACHINE_TIMETC_H_
>> +
>> +#define     TC_LAST 0
>> +
>> +#endif      /* _MACHINE_TIMETC_H_ */
>> diff --git sys/arch/sparc64/dev/psycho.c
>sys/arch/sparc64/dev/psycho.c
>> index e24f804dff6..1a7a1afa8c2 100644
>> --- sys/arch/sparc64/dev/psycho.c
>> +++ sys/arch/sparc64/dev/psycho.c
>> @@ -127,7 +127,7 @@ extern struct sparc_pci_chipset
>_sparc_pci_chipset;
>>  u_int stick_get_timecount(struct timecounter *);
>>  
>>  struct timecounter stick_timecounter = {
>> -    stick_get_timecount, NULL, ~0u, 0, "stick", 1000, NULL
>> +    stick_get_timecount, NULL, ~0u, 0, "stick", 1000, NULL, 0
>>  };
>>  
>>  /*
>> diff --git sys/arch/sparc64/include/timetc.h
>sys/arch/sparc64/include/timetc.h
>> new file mode 100644
>> index 00000000000..e58a7fb4faa
>> --- /dev/null
>> +++ sys/arch/sparc64/include/timetc.h
>> @@ -0,0 +1,23 @@
>> +/*  $OpenBSD$ */
>> +/*
>> + * Copyright (c) 2020 Paul Irofti <p...@irofti.net>
>> + *
>> + * Permission to use, copy, modify, and distribute this software for
>any
>> + * purpose with or without fee is hereby granted, provided that the
>above
>> + * copyright notice and this permission notice appear in all copies.
>> + *
>> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
>WARRANTIES
>> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
>> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE
>LIABLE FOR
>> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
>DAMAGES
>> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
>IN AN
>> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
>OUT OF
>> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>> + */
>> +
>> +#ifndef _MACHINE_TIMETC_H_
>> +#define _MACHINE_TIMETC_H_
>> +
>> +#define     TC_LAST 0
>> +
>> +#endif      /* _MACHINE_TIMETC_H_ */
>> diff --git sys/arch/sparc64/sparc64/clock.c
>sys/arch/sparc64/sparc64/clock.c
>> index fd5e8a9c15b..5c2e47d386b 100644
>> --- sys/arch/sparc64/sparc64/clock.c
>> +++ sys/arch/sparc64/sparc64/clock.c
>> @@ -109,13 +109,13 @@ struct cfdriver clock_cd = {
>>  u_int tick_get_timecount(struct timecounter *);
>>  
>>  struct timecounter tick_timecounter = {
>> -    tick_get_timecount, NULL, ~0u, 0, "tick", 0, NULL
>> +    tick_get_timecount, NULL, ~0u, 0, "tick", 0, NULL, 0
>>  };
>>  
>>  u_int sys_tick_get_timecount(struct timecounter *);
>>  
>>  struct timecounter sys_tick_timecounter = {
>> -    sys_tick_get_timecount, NULL, ~0u, 0, "sys_tick", 1000, NULL
>> +    sys_tick_get_timecount, NULL, ~0u, 0, "sys_tick", 1000, NULL, 0
>>  };
>>  
>>  /*
>> diff --git sys/dev/acpi/acpihpet.c sys/dev/acpi/acpihpet.c
>> index d0ee72cec9b..13177a909da 100644
>> --- sys/dev/acpi/acpihpet.c
>> +++ sys/dev/acpi/acpihpet.c
>> @@ -45,7 +45,9 @@ static struct timecounter hpet_timecounter = {
>>      0xffffffff,             /* counter_mask (32 bits) */
>>      0,                      /* frequency */
>>      0,                      /* name */
>> -    1000                    /* quality */
>> +    1000,                   /* quality */
>> +    NULL,                   /* private bits */
>> +    0,                      /* expose to user */
>>  };
>>  
>>  #define HPET_TIMERS 3
>> diff --git sys/dev/acpi/acpitimer.c sys/dev/acpi/acpitimer.c
>> index cdc8c99a17a..89b5a397e47 100644
>> --- sys/dev/acpi/acpitimer.c
>> +++ sys/dev/acpi/acpitimer.c
>> @@ -36,7 +36,9 @@ static struct timecounter acpi_timecounter = {
>>      0x00ffffff,             /* counter_mask (24 bits) */
>>      ACPI_FREQUENCY,         /* frequency */
>>      0,                      /* name */
>> -    1000                    /* quality */
>> +    1000,                   /* quality */
>> +    NULL,                   /* private bits */
>> +    0,                      /* expose to user */
>>  };
>>  
>>  struct acpitimer_softc {
>> diff --git sys/dev/pci/amdpm.c sys/dev/pci/amdpm.c
>> index 6df82858016..9610d5bc1f0 100644
>> --- sys/dev/pci/amdpm.c
>> +++ sys/dev/pci/amdpm.c
>> @@ -82,7 +82,9 @@ static struct timecounter amdpm_timecounter = {
>>      0xffffff,               /* counter_mask */
>>      AMDPM_FREQUENCY,        /* frequency */
>>      "AMDPM",                /* name */
>> -    1000                    /* quality */
>> +    1000,                   /* quality */
>> +    NULL,                   /* private bits */
>> +    0,                      /* expose to user */
>>  };
>>  
>>  #define     AMDPM_CONFREG   0x40
>> diff --git sys/dev/pci/viapm.c sys/dev/pci/viapm.c
>> index db806eedf80..ce33cd175e6 100644
>> --- sys/dev/pci/viapm.c
>> +++ sys/dev/pci/viapm.c
>> @@ -177,7 +177,9 @@ static struct timecounter viapm_timecounter = {
>>      0xffffff,               /* counter_mask */
>>      VIAPM_FREQUENCY,        /* frequency */
>>      "VIAPM",                /* name */
>> -    1000                    /* quality */
>> +    1000,                   /* quality */
>> +    NULL,                   /* private bits */
>> +    0,                      /* expose to user */
>>  };
>>  
>>  struct timeout viapm_timeout;
>> diff --git sys/dev/pv/hyperv.c sys/dev/pv/hyperv.c
>> index b32facdacb1..b9ee2feec4c 100644
>> --- sys/dev/pv/hyperv.c
>> +++ sys/dev/pv/hyperv.c
>> @@ -141,7 +141,7 @@ struct {
>>  };
>>  
>>  struct timecounter hv_timecounter = {
>> -    hv_gettime, 0, 0xffffffff, 10000000, "hyperv", 9001
>> +    hv_gettime, 0, 0xffffffff, 10000000, "hyperv", 9001, NULL, 0
>>  };
>>  
>>  struct cfdriver hyperv_cd = {
>> diff --git sys/dev/pv/pvclock.c sys/dev/pv/pvclock.c
>> index 6b242f7448d..b80e4d2a484 100644
>> --- sys/dev/pv/pvclock.c
>> +++ sys/dev/pv/pvclock.c
>> @@ -74,7 +74,7 @@ struct cfdriver pvclock_cd = {
>>  };
>>  
>>  struct timecounter pvclock_timecounter = {
>> -    pvclock_get_timecount, NULL, ~0u, 0, NULL, -2000, NULL
>> +    pvclock_get_timecount, NULL, ~0u, 0, NULL, -2000, NULL, 0
>>  };
>>  
>>  int
>> diff --git sys/kern/exec_elf.c sys/kern/exec_elf.c
>> index 9b5b8eb3acf..59bc923a6fb 100644
>> --- sys/kern/exec_elf.c
>> +++ sys/kern/exec_elf.c
>> @@ -124,7 +124,7 @@ extern char *syscallnames[];
>>  /*
>>   * How many entries are in the AuxInfo array we pass to the process?
>>   */
>> -#define ELF_AUX_ENTRIES     8
>> +#define ELF_AUX_ENTRIES     9
>>  
>>  /*
>>   * This is the OpenBSD ELF emul
>> @@ -860,6 +860,10 @@ exec_elf_fixup(struct proc *p, struct
>exec_package *epp)
>>              a->au_v = ap->arg_entry;
>>              a++;
>>  
>> +            a->au_id = AUX_openbsd_timekeep;
>> +            a->au_v = p->p_p->ps_timekeep;
>> +            a++;
>> +
>>              a->au_id = AUX_null;
>>              a->au_v = 0;
>>              a++;
>> diff --git sys/kern/kern_exec.c sys/kern/kern_exec.c
>> index 20480c2fc28..222450607d5 100644
>> --- sys/kern/kern_exec.c
>> +++ sys/kern/kern_exec.c
>> @@ -64,6 +64,11 @@
>>  #include <uvm/uvm_extern.h>
>>  #include <machine/tcb.h>
>>  
>> +#include <sys/timetc.h>
>> +
>> +struct uvm_object *timekeep_object;
>> +struct timekeep* timekeep;
>> +
>>  void        unveil_destroy(struct process *ps);
>>  
>>  const struct kmem_va_mode kv_exec = {
>> @@ -76,6 +81,11 @@ const struct kmem_va_mode kv_exec = {
>>   */
>>  int exec_sigcode_map(struct process *, struct emul *);
>>  
>> +/*
>> + * Map the shared timekeep page.
>> + */
>> +int exec_timekeep_map(struct process *);
>> +
>>  /*
>>   * If non-zero, stackgap_random specifies the upper limit of the
>random gap size
>>   * added to the fixed stack position. Must be n^2.
>> @@ -684,6 +694,9 @@ sys_execve(struct proc *p, void *v, register_t
>*retval)
>>      /* map the process's signal trampoline code */
>>      if (exec_sigcode_map(pr, pack.ep_emul))
>>              goto free_pack_abort;
>> +    /* map the process's timekeep page */
>> +    if (exec_timekeep_map(pr))
>> +            goto free_pack_abort;
>>  
>>  #ifdef __HAVE_EXEC_MD_MAP
>>      /* perform md specific mappings that process might need */
>> @@ -863,3 +876,40 @@ exec_sigcode_map(struct process *pr, struct emul
>*e)
>>  
>>      return (0);
>>  }
>> +
>> +int
>> +exec_timekeep_map(struct process *pr)
>> +{
>> +    size_t timekeep_sz = sizeof(struct timekeep);
>> +
>> +    /*
>> +     * Similar to the sigcode object, except that there is a single
>> +     * timekeep object, and not one per emulation.
>> +     */
>> +    if (timekeep_object == NULL) {
>> +            vaddr_t va;
>> +
>> +            timekeep_object = uao_create(timekeep_sz, 0);
>> +            uao_reference(timekeep_object);
>> +
>> +            if (uvm_map(kernel_map, &va, round_page(timekeep_sz),
>timekeep_object,
>> +                0, 0, UVM_MAPFLAG(PROT_READ | PROT_WRITE, PROT_READ |
>PROT_WRITE,
>> +                MAP_INHERIT_SHARE, MADV_RANDOM, 0))) {
>> +                    uao_detach(timekeep_object);
>> +                    return (ENOMEM);
>> +            }
>> +
>> +            timekeep = (struct timekeep *)va;
>> +            timekeep->tk_version = TK_VERSION;
>> +    }
>> +
>> +    uao_reference(timekeep_object);
>> +    if (uvm_map(&pr->ps_vmspace->vm_map, &pr->ps_timekeep,
>round_page(timekeep_sz),
>> +        timekeep_object, 0, 0, UVM_MAPFLAG(PROT_READ, PROT_READ,
>> +        MAP_INHERIT_COPY, MADV_RANDOM, 0))) {
>> +            uao_detach(timekeep_object);
>> +            return (ENOMEM);
>> +    }
>> +
>> +    return (0);
>> +}
>> diff --git sys/kern/kern_tc.c sys/kern/kern_tc.c
>> index 88d4a3379f9..47efbdd0b78 100644
>> --- sys/kern/kern_tc.c
>> +++ sys/kern/kern_tc.c
>> @@ -63,7 +63,7 @@ dummy_get_timecount(struct timecounter *tc)
>>  }
>>  
>>  static struct timecounter dummy_timecounter = {
>> -    dummy_get_timecount, 0, ~0u, 1000000, "dummy", -1000000
>> +    dummy_get_timecount, 0, ~0u, 1000000, "dummy", -1000000, NULL, 0
>>  };
>>  
>>  /*
>> @@ -479,6 +479,34 @@ tc_setclock(const struct timespec *ts)
>>  #endif
>>  }
>>  
>> +void
>> +tc_update_timekeep(void)
>> +{
>> +    static struct timecounter *last_tc = NULL;
>> +    struct timehands *th;
>> +
>> +    if (timekeep == NULL)
>> +            return;
>> +
>> +    th = timehands;
>> +    timekeep->tk_generation = 0;
>> +    membar_producer();
>> +    timekeep->tk_scale = th->th_scale;
>> +    timekeep->tk_offset_count = th->th_offset_count;
>> +    timekeep->tk_offset = th->th_offset;
>> +    timekeep->tk_naptime = th->th_naptime;
>> +    timekeep->tk_boottime = th->th_boottime;
>> +    if (last_tc != th->th_counter) {
>> +            timekeep->tk_counter_mask = th->th_counter->tc_counter_mask;
>> +            timekeep->tk_user = th->th_counter->tc_user;
>> +            last_tc = th->th_counter;
>> +    }
>> +    membar_producer();
>> +    timekeep->tk_generation = th->th_generation;
>> +
>> +    return;
>> +}
>> +
>>  /*
>>   * Initialize the next struct timehands in the ring and make
>>   * it the active timehands.  Along the way we might switch to a
>different
>> @@ -631,6 +659,8 @@ tc_windup(struct bintime *new_boottime, struct
>bintime *new_offset,
>>      time_uptime = th->th_offset.sec;
>>      membar_producer();
>>      timehands = th;
>> +
>> +    tc_update_timekeep();
>>  }
>>  
>>  /* Report or change the active timecounter hardware. */
>> diff --git sys/sys/exec_elf.h sys/sys/exec_elf.h
>> index a40e0510273..3084ed595a6 100644
>> --- sys/sys/exec_elf.h
>> +++ sys/sys/exec_elf.h
>> @@ -691,7 +691,8 @@ enum AuxID {
>>      AUX_sun_uid = 2000,             /* euid */
>>      AUX_sun_ruid = 2001,            /* ruid */
>>      AUX_sun_gid = 2002,             /* egid */
>> -    AUX_sun_rgid = 2003             /* rgid */
>> +    AUX_sun_rgid = 2003,            /* rgid */
>> +    AUX_openbsd_timekeep = 4000,    /* userland clock_gettime */
>>  };
>>  
>>  struct elf_args {
>> diff --git sys/sys/proc.h sys/sys/proc.h
>> index 357c0c0d52c..c6d54572bdd 100644
>> --- sys/sys/proc.h
>> +++ sys/sys/proc.h
>> @@ -242,6 +242,7 @@ struct process {
>>      char    ps_comm[MAXCOMLEN+1];
>>  
>>      vaddr_t ps_strings;             /* User pointers to argv/env */
>> +    vaddr_t ps_timekeep;            /* User pointer to timekeep */
>>      vaddr_t ps_sigcode;             /* User pointer to the signal code */
>>      vaddr_t ps_sigcoderet;          /* User pointer to sigreturn retPC */
>>      u_long  ps_sigcookie;
>> diff --git sys/sys/time.h sys/sys/time.h
>> index e758a64ce07..bcd3acd034d 100644
>> --- sys/sys/time.h
>> +++ sys/sys/time.h
>> @@ -163,7 +163,7 @@ struct clockinfo {
>>  };
>>  #endif /* __BSD_VISIBLE */
>>  
>> -#if defined(_KERNEL) || defined(_STANDALONE)
>> +#if defined(_KERNEL) || defined(_STANDALONE) || defined (_LIBC)
>>  #include <sys/_time.h>
>>  
>>  /* Time expressed as seconds and fractions of a second + operations
>on it. */
>> @@ -171,6 +171,9 @@ struct bintime {
>>      time_t  sec;
>>      uint64_t frac;
>>  };
>> +#endif
>> +
>> +#if defined(_KERNEL) || defined(_STANDALONE)
>>  
>>  #define bintimecmp(btp, ctp, cmp)                                   \
>>      ((btp)->sec == (ctp)->sec ?                                     \
>> diff --git sys/sys/timetc.h sys/sys/timetc.h
>> index ce81c3475a0..c5ad27695ba 100644
>> --- sys/sys/timetc.h
>> +++ sys/sys/timetc.h
>> @@ -24,10 +24,11 @@
>>  #ifndef _SYS_TIMETC_H_
>>  #define     _SYS_TIMETC_H_
>>  
>> -#ifndef _KERNEL
>> +#if !defined(_KERNEL) && !defined(_LIBC)
>>  #error "no user-serviceable parts inside"
>>  #endif
>>  
>> +#include <machine/timetc.h>
>>  #include <sys/queue.h>
>>  
>>  /*-
>> @@ -80,6 +81,8 @@ struct timecounter {
>>               */
>>      void                    *tc_priv;               /* [I] */
>>              /* Pointer to the timecounter's private parts. */
>> +    int                     tc_user;                /* [I] */
>> +            /* Expose this timecounter to userland. */
>>      SLIST_ENTRY(timecounter) tc_next;               /* [I] */
>>              /* Pointer to the next timecounter. */
>>      int64_t                 tc_freq_adj;            /* [tw] */
>> @@ -88,11 +91,32 @@ struct timecounter {
>>              /* Precision of the counter.  Computed in tc_init(). */
>>  };
>>  
>> +struct timekeep {
>> +    /* set at initialization */
>> +    uint32_t        tk_version;             /* version number */
>> +
>> +    /* timehands members */
>> +    uint64_t        tk_scale;
>> +    u_int           tk_offset_count;
>> +    struct bintime  tk_offset;
>> +    struct bintime  tk_naptime;
>> +    struct bintime  tk_boottime;
>> +    volatile u_int  tk_generation;
>> +
>> +    /* timecounter members */
>> +    int             tk_user;
>> +    u_int           tk_counter_mask;
>> +};
>> +#define TK_VERSION  0
>> +
>>  struct rwlock;
>>  extern struct rwlock tc_lock;
>>  
>>  extern struct timecounter *timecounter;
>>  
>> +extern struct uvm_object *timekeep_object;
>> +extern struct timekeep *timekeep;
>> +
>>  u_int64_t tc_getfrequency(void);
>>  u_int64_t tc_getprecision(void);
>>  void        tc_init(struct timecounter *tc);
>> 

Reply via email to