Re: Fwd: [PATCH v4.15.7 1/1] on Intel, VDSO should handle CLOCK_MONOTONIC_RAW and export 'tsc_calibration' pointer

2018-03-10 Thread Jason Vas Dias
Hi Thomas -

Thanks very much for your help & guidance in previous mail:

RE: On 08/03/2018, Thomas Gleixner  wrote:
> 
> The right way to do that is to put the raw conversion values and the raw
> seconds base value into the vdso data and implement the counterpart of
> getrawmonotonic64(). And if that is done, then it can be done for _ALL_
> clocksources which support VDSO access and not just for the TSC.
>

I have done this now with a new patch, sent in mail with subject :
  
'[PATCH v4.16-rc4 1/1] x86/vdso: on Intel, VDSO should handle 
CLOCK_MONOTONIC_RAW' 

which should address all the concerns you raise.

> I already  know how that works, really.

I never doubted or meant to impugn that !

I am beginning to know a little how that works also, thanks in great
part to your help last week - thanks for your patience.

I was impatient last week to get access to low latency timers for a work
project, and was trying to read the unadjusted clock .

> instead of making completely false claims about the correctness of the kernel
> timekeeping infrastructure.

I really didn't mean to make any such claims - I'm sorry if I did .  I was just 
trying
to say that by the time the results of clock_gettime(CLOCK_MONOTONIC_RAW,&ts) 
were
available to the caller they were not of much use because of the
latencies often dwarfing the time differences .

Anyway, I hope sometime you will consider putting such a patch in the
kernel.

I have developed a verson for ARM also, but that depends on making
CNTPCT + CNTFRQ registers readable in user-space, which is not meant
to be secure and is not normally done , but does work - but it is
against the Texas Instruments (ti-linux) kernel and can be enabled
with a new KConfig option, and brings latencies down from > 300ns
to < 20ns . Maybe I should post that also to kernel.org, or to
ti.com ?

I have a separate patch for the vdso_tsc_calibration export of the
tsc_khz and calibration which no longer returns pointers into the VDSO -
I can post this as a patch if you like.

Thanks & Best Regards,
Jason Vas Dias 

diff -up linux-4.16-rc4/arch/x86/entry/vdso/vclock_gettime.c.4.16-rc4 linux-4.16-rc4/arch/x86/entry/vdso/vclock_gettime.c
--- linux-4.16-rc4/arch/x86/entry/vdso/vclock_gettime.c.4.16-rc4	2018-03-04 22:54:11.0 +
+++ linux-4.16-rc4/arch/x86/entry/vdso/vclock_gettime.c	2018-03-11 05:08:31.137681337 +
@@ -182,6 +182,29 @@ notrace static u64 vread_tsc(void)
 	return last;
 }
 
+notrace static u64 vread_tsc_raw(void)
+{
+u64 tsc, last=gtod->raw_cycle_last;
+if( likely( gtod->has_rdtscp ) ) {
+u32 tsc_lo, tsc_hi,
+tsc_cpu __attribute__((unused));
+asm volatile
+( "rdtscp"
+/* ^- has built-in cancellation point / pipeline stall "barrier" */
+: "=a" (tsc_lo)
+, "=d" (tsc_hi)
+, "=c" (tsc_cpu)
+); // since all variables 32-bit, eax, edx, ecx used - NOT rax, rdx, rcx 
+tsc  = u64)tsc_hi) & 0xUL) << 32) | (((u64)tsc_lo) & 0xUL);
+} else {
+tsc  = rdtsc_ordered();
+}
+	if (likely(tsc >= last))
+		return tsc;
+asm volatile ("");
+return last;
+}
+
 notrace static inline u64 vgetsns(int *mode)
 {
 	u64 v;
@@ -203,6 +226,27 @@ notrace static inline u64 vgetsns(int *m
 	return v * gtod->mult;
 }
 
+notrace static inline u64 vgetsns_raw(int *mode)
+{
+	u64 v;
+	cycles_t cycles;
+
+	if (gtod->vclock_mode == VCLOCK_TSC)
+		cycles = vread_tsc_raw();
+#ifdef CONFIG_PARAVIRT_CLOCK
+	else if (gtod->vclock_mode == VCLOCK_PVCLOCK)
+		cycles = vread_pvclock(mode);
+#endif
+#ifdef CONFIG_HYPERV_TSCPAGE
+	else if (gtod->vclock_mode == VCLOCK_HVCLOCK)
+		cycles = vread_hvclock(mode);
+#endif
+	else
+		return 0;
+	v = (cycles - gtod->raw_cycle_last) & gtod->raw_mask;
+	return v * gtod->raw_mult;
+}
+
 /* Code size doesn't matter (vdso is 4k anyway) and this is faster. */
 notrace static int __always_inline do_realtime(struct timespec *ts)
 {
@@ -246,6 +290,27 @@ notrace static int __always_inline do_mo
 	return mode;
 }
 
+notrace static int __always_inline do_monotonic_raw( struct timespec *ts)
+{
+	unsigned long seq;
+	u64 ns;
+	int mode;
+
+	do {
+		seq = gtod_read_begin(gtod);
+		mode = gtod->vclock_mode;
+		ts->tv_sec = gtod->monotonic_time_raw_sec;
+		ns = gtod->monotonic_time_raw_nsec;
+		ns += vgetsns_raw(&mode);
+		ns >>= gtod->raw_shift;
+	} while (unlikely(gtod_read_retry(gtod, seq)));
+
+	ts->tv_sec += __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns);
+	ts->tv_nsec = ns;
+
+	return mode;
+}
+
 notrace static void do_realtime_coarse(struct timespec *ts)
 {
 	unsigned long seq;
@@ -277,6 +342,10 @@ notrace int __vdso_clock_gettime(clockid
 		if (do_monotonic(ts) == VCLOCK_NONE)
 			goto fallback;
 		break;
+	case CLOCK_MONOTONIC_RAW:
+		if (do_monotonic_raw(ts) == VCLOCK_NONE)
+		

Re: Fwd: [PATCH v4.15.7 1/1] on Intel, VDSO should handle CLOCK_MONOTONIC_RAW and export 'tsc_calibration' pointer

2018-03-08 Thread Thomas Gleixner
On Thu, 8 Mar 2018, Jason Vas Dias wrote:
> On 08/03/2018, Thomas Gleixner  wrote:
> I'd appreciate clarification on few points :
> 
> > Well, you did not expose the raw conversion data in vsyscall_gtod_data. You
> > are using:
> >
> > + tsc*= gtod->mult;
> > + tsc   >>= gtod->shift;
> >
> > That's is the adjusted mult/shift value which can change when NTP/PTP is
> > enabled and you _cannot_ use it unprotected.
> ...
> > vsyscall_gtod_data does not have the raw
> > information and it simply can be added.
> 
> 
> By "the raw information" here,  do you mean :
>   o   the 'tsc_khz'  "Refined TSC clocksource calibration" ?
>   o   or some other data ?

The raw conversion data which is used in getrawmonotonic64() as I pointed
out several times now.

> The shift and mult values are calculated from
> tsc_khz by :
> 
> tsc_refine_calibration_work() , in arch/x86/kernel/tsc.c , @ line 1164:
> { ...
>   tsc_khz = freq;
>   pr_info("Refined TSC clocksource calibration: %lu.%03lu MHz\n",
>   (unsigned long)tsc_khz / 1000,
>   (unsigned long)tsc_khz % 1000);

There is really no point in copying tons of code in your replies. I already
know how that works, really.

> I understand that the vsyscall_gtod_data contains the adjusted mult & shift ,
> but since this is the only data available there, and the kernel
> syscall implementation
> of clock_gettime(CLOCK_MONOTONIC_RAW) does seem to access
> these same adjusted shift & mult values - as I showed in previous post,
> kernel/time/timekeeping.c's getmonotonicraw64() does use these same
> mult and shift values:

It really does not and if you can't be bothered to actually look at the
difference of:

void getrawmonotonic64(struct timespec64 *ts)
{
...
nsecs = timekeeping_get_ns(&tk->tkr_raw);

versus:

void ktime_get_ts64(struct timespec64 *ts)
{
...
nsec = timekeeping_get_ns(&tk->tkr_mono);

then I really can't help it.

> Are the vdso gtod->mult and gtod->shift values somehow different from
>   'tkr->mult' and 'tkr->shift' ?

They are the adjusted values used for CLOCK_MONOTONIC and they are updated
when the kernel side timekeeper->tkr_mono data is updated. What's not
stored in the VDSO data right now is the raw data. As I told you a
gazillion times now, it can be stored there and then the VDSO based mono
raw accessor can be implemented similar to the monotonic/realtime
implementations.

> I thought they were actually pointers to the same calibration data.

Care to look at how the vdso data is updated?

> Yes, as noted in previous posts, the 'mult' value does seem to
> change by small increments . I guess this is purely because of NTP / PTP ?
> So the syscall implementation of clock_gettime(CLOCK_MONOTONIC_RAW,&ts)
> actually does return an NTP / PTP adjusted value ?
> Then it is  even worse than I thought - not only does it
> have an unusably high latency, but it does not do what
> it is documented to do at all, if those mult/shift values
> are changed by NTP/PTP / CPU frequency adjustments.

Once again: CLOCK_MONOTONIC_RAW does exactly what is documented and the
conversion values are not the same as those for CLOCK_MONOTONIC.

> I do strongly believe that if the VDSO is going to support accessing the TSC
> from user-space,
> it should provide some access to the  TSC calibration values that would
> permit user-space TSC readers to convert the TSC value to nanoseconds
> accurately and efficiently, in a way not prone to NTP or PTP adjustments ;

You surely are free to believe what you want.

> otherwise the VDSO do_monotonic_raw must be used, and as it has nowhere
> to cache previous values, it must do the long division every time,
> which enforces
> a latency of >= @ 100ns.

I told you before that there is neither a requirement to store anything nor
a requirement to use a long division. I gave you the pointers to the
monotonic/realtime accessors which do neither store anything nor do long
divisions.

> My  user-space TSC reader in 'test_vdso_tsc.c' (sent as attachments to
> previous mails)  uses the pointer returned by
> __vdso_linux_tsc_calibration() , and a
> cached previous value, to achieve latencies of 10-20ns .

I don't care about that as this is a completely different thing. Providing
the raw TSC conversion factors to user space might be a worthwhile
exercise, but has nothing to do with the VDSO based clock_gettime()
implementation at all. And as I pointed out in the other reply, it's not
going to happen in a prone to be broken way.

> I can't see how the contents pointed to by the pointer returned by
> __vdso_linux_tsc_calibration()
> will be "garbage" , as long as the clock source remains TSC .

There is no guarantee that the clock source remains TSC. And I don't care
about your 'controlled' system at all. Interfaces have to be usable on all
systems and cannot be implemented on a 'might work if you know what you are
doing' basis. That's not the way the kernel implements interfaces ev

Re: Fwd: [PATCH v4.15.7 1/1] on Intel, VDSO should handle CLOCK_MONOTONIC_RAW and export 'tsc_calibration' pointer

2018-03-08 Thread Jason Vas Dias
On 08/03/2018, Thomas Gleixner  wrote:
> On Tue, 6 Mar 2018, Jason Vas Dias wrote:
>> I will prepare a new patch that meets submission + coding style guidelines
>> and
>> does not expose pointers within the vsyscall_gtod_data region to
>> user-space code -
>> but I don't really understand why not, since only the gtod->mult value
>> will
>> change as long as the clocksource remains TSC, and updates to it by the
>> kernel
>> are atomic and partial values cannot be read .
>>
>> The code in the patch reverts to old behavior for clocks which are not
>> the
>> TSC and provides a way for users to determine if the  clock is still the
>> TSC
>> by calling '__vdso_linux_tsc_calibration()', which would return NULL if
>> the clock is not the TSC .
>>
>> I have never seen Linux on a modern intel box spontaneously decide to
>> switch from the TSC clocksource after calibration succeeds and
>> it has decided to use the TSC as the system / platform clock source -
>> what would make it do this ?
>>
>> But for the highly controlled systems I am doing performance testing on,
>> I can guarantee that the clocksource does not change.
>
> We are not writing code for a particular highly controlled system. We
> expose functionality which operates under all circumstances. There are
> various reasons why TSC can be disabled at runtime, crappy BIOS/SMI,
> sockets getting out of sync .
>
>> There is no way user code can write those pointers or do anything other
>> than read them, so I see no harm in exposing them to user-space ; then
>> user-space programs can issue rdtscp and use the same calibration values
>> as the kernel, and use some cached 'previous timespec value' to avoid
>> doing the long division every time.
>>
>> If the shift & mult are not accurate TSC calibration values, then the
>> kernel should put other more accurate calibration values in the gtod .
>
> The raw calibration values are as accurate as the kernel can make them. But
> they can be rather far off from converting to real nanoseconds for various
> reasons. The NTP/PTP adjusted conversion is matching real units and is
> obviously more accurate.
>
>> > Please look at the kernel side implementation of
>> > clock_gettime(CLOCK_MONOTONIC_RAW).
>> > The VDSO side can be implemented in the
>> > same way.
>> > All what is required is to expose the relevant information in the
>> > existing vsyscall_gtod_data data structure.
>>
>> I agree - that is my point entirely , & what I was trying to do .
>
> Well, you did not expose the raw conversion data in vsyscall_gtod_data. You
> are using:
>
> + tsc*= gtod->mult;
> + tsc   >>= gtod->shift;
>
> That's is the adjusted mult/shift value which can change when NTP/PTP is
> enabled and you _cannot_ use it unprotected.
>
>> void getrawmonotonic64(struct timespec64 *ts)
>> {
>>  struct timekeeper *tk = &tk_core.timekeeper;
>>  unsigned long seq;
>>  u64 nsecs;
>>
>>  do {
>>  seq = read_seqcount_begin(&tk_core.seq);
>> #   ^-- I think this is the source of the locking
>> #and the very long latencies !
>
> This protects tk->raw_sec from changing which would result in random time
> stamps. Yes, it can cause slightly larger latencies when the timekeeper is
> updated on another CPU concurrently, but that's not the main reason why
> this is slower in general than the VDSO functions. The syscall overhead is
> there for every invocation and it's substantial.
>
>> So in fact, when the clock source is TSC, the value recorded in 'ts'
>> by clock_gettime(CLOCK_MONOTONIC_RAW, &ts) is very similar to
>>   u64 tsc = rdtscp();
>>   tsc *= gtod->mult;
>>   tsc >>= gtod->shift;
>>   ts.tv_sec=tsc / NSEC_PER_SEC;
>>   ts.tv_nsec=tsc % NSEC_PER_SEC;
>>
>> which is the algorithm I was using in the VDSO fast TSC reader,
>> do_monotonic_raw() .
>
> Except that you are using the adjusted conversion values and not the raw
> ones. So your VDSO implementation of monotonic raw access is just wrong and
> not matching the syscall based implementation in any way.
>
>> The problem with doing anything more in the VDSO is that there
>> is of course nowhere in the VDSO to store any data, as it has
>> no data section or writable pages . So some kind of writable
>> page would need to be added to the vdso , complicating its
>> vdso/vma.c, etc., which is not desirable.
>
> No, you don't need any writeable memory in the VDSO. Look at how the
> CLOCK_MONOTONIC and CLOCK_REALTIME functions are implemented in the VDSO.
>
>> But it is equally not desirable to have the clock_gettime
>> system call have a latency exceeding 300ns for CLOCK_MONOTONIC_RAW
>
> I said before and I do it once more: CLOCK_MONOTONIC_RAW can be implemented
> in the VDSO by adding the relevant data to vsyscall_gtod_data and by using
> the proper accessor functions which are there for a reason.
>
>> clocks, nor to measure all the adjustments & previous value dependencies
>> that the curr

Re: Fwd: [PATCH v4.15.7 1/1] on Intel, VDSO should handle CLOCK_MONOTONIC_RAW and export 'tsc_calibration' pointer

2018-03-08 Thread Thomas Gleixner
On Tue, 6 Mar 2018, Jason Vas Dias wrote:
> I will prepare a new patch that meets submission + coding style guidelines and
> does not expose pointers within the vsyscall_gtod_data region to
> user-space code -
> but I don't really understand why not, since only the gtod->mult value will
> change as long as the clocksource remains TSC, and updates to it by the kernel
> are atomic and partial values cannot be read .
> 
> The code in the patch reverts to old behavior for clocks which are not the
> TSC and provides a way for users to determine if the  clock is still the TSC
> by calling '__vdso_linux_tsc_calibration()', which would return NULL if
> the clock is not the TSC .
> 
> I have never seen Linux on a modern intel box spontaneously decide to
> switch from the TSC clocksource after calibration succeeds and
> it has decided to use the TSC as the system / platform clock source -
> what would make it do this ?
> 
> But for the highly controlled systems I am doing performance testing on,
> I can guarantee that the clocksource does not change.

We are not writing code for a particular highly controlled system. We
expose functionality which operates under all circumstances. There are
various reasons why TSC can be disabled at runtime, crappy BIOS/SMI,
sockets getting out of sync .

> There is no way user code can write those pointers or do anything other
> than read them, so I see no harm in exposing them to user-space ; then
> user-space programs can issue rdtscp and use the same calibration values
> as the kernel, and use some cached 'previous timespec value' to avoid
> doing the long division every time.
> 
> If the shift & mult are not accurate TSC calibration values, then the
> kernel should put other more accurate calibration values in the gtod .

The raw calibration values are as accurate as the kernel can make them. But
they can be rather far off from converting to real nanoseconds for various
reasons. The NTP/PTP adjusted conversion is matching real units and is
obviously more accurate.

> > Please look at the kernel side implementation of
> > clock_gettime(CLOCK_MONOTONIC_RAW).
> > The VDSO side can be implemented in the
> > same way.
> > All what is required is to expose the relevant information in the
> > existing vsyscall_gtod_data data structure.
> 
> I agree - that is my point entirely , & what I was trying to do .

Well, you did not expose the raw conversion data in vsyscall_gtod_data. You
are using:

+ tsc*= gtod->mult;
+ tsc   >>= gtod->shift;

That's is the adjusted mult/shift value which can change when NTP/PTP is
enabled and you _cannot_ use it unprotected.

> void getrawmonotonic64(struct timespec64 *ts)
> {
>   struct timekeeper *tk = &tk_core.timekeeper;
>   unsigned long seq;
>   u64 nsecs;
> 
>   do {
>   seq = read_seqcount_begin(&tk_core.seq);
> #   ^-- I think this is the source of the locking
> #and the very long latencies !

This protects tk->raw_sec from changing which would result in random time
stamps. Yes, it can cause slightly larger latencies when the timekeeper is
updated on another CPU concurrently, but that's not the main reason why
this is slower in general than the VDSO functions. The syscall overhead is
there for every invocation and it's substantial.

> So in fact, when the clock source is TSC, the value recorded in 'ts'
> by clock_gettime(CLOCK_MONOTONIC_RAW, &ts) is very similar to
>   u64 tsc = rdtscp();
>   tsc *= gtod->mult;
>   tsc >>= gtod->shift;
>   ts.tv_sec=tsc / NSEC_PER_SEC;
>   ts.tv_nsec=tsc % NSEC_PER_SEC;
> 
> which is the algorithm I was using in the VDSO fast TSC reader,
> do_monotonic_raw() .

Except that you are using the adjusted conversion values and not the raw
ones. So your VDSO implementation of monotonic raw access is just wrong and
not matching the syscall based implementation in any way.

> The problem with doing anything more in the VDSO is that there
> is of course nowhere in the VDSO to store any data, as it has
> no data section or writable pages . So some kind of writable
> page would need to be added to the vdso , complicating its
> vdso/vma.c, etc., which is not desirable.

No, you don't need any writeable memory in the VDSO. Look at how the
CLOCK_MONOTONIC and CLOCK_REALTIME functions are implemented in the VDSO.

> But it is equally not desirable to have the clock_gettime
> system call have a latency exceeding 300ns for CLOCK_MONOTONIC_RAW

I said before and I do it once more: CLOCK_MONOTONIC_RAW can be implemented
in the VDSO by adding the relevant data to vsyscall_gtod_data and by using
the proper accessor functions which are there for a reason.

> clocks, nor to measure all the adjustments & previous value dependencies
> that the current implementation is prone to .

I have no idea what you are talking about. If done right,
CLOCK_MONOTONIC_RAW does not have any adjustments.

> But there is no other communicat

Fwd: [PATCH v4.15.7 1/1] on Intel, VDSO should handle CLOCK_MONOTONIC_RAW and export 'tsc_calibration' pointer

2018-03-06 Thread Jason Vas Dias
On 06/03/2018, Thomas Gleixner  wrote:
> Jason,
>
> On Mon, 5 Mar 2018, Jason Vas Dias wrote:
>
> thanks for providing this. A few formal nits first.
>
> Please read Documentation/process/submitting-patches.rst
>
> Patches need a concise subject line and the subject line wants a prefix, in
> this case 'x86/vdso'.
>
> Please don't put anything past the patch. Your delimiters are human
> readable, but cannot be handled by tools.
>
> Also please follow the kernel coding style guide lines.
>
>> It also provides a new function in the VDSO :
>>
>> struct linux_timestamp_conversion
>> { u32 mult;
>> u32 shift;
>> };
>> extern
>> const struct linux_timestamp_conversion *
>> __vdso_linux_tsc_calibration(void);
>>
>> which can be used by user-space rdtsc / rdtscp issuers
>> by using code such as in
>> tools/testing/selftests/vDSO/parse_vdso.c
>> to call vdso_sym("LINUX_2.6", "__vdso_linux_tsc_calibration"),
>> which returns a pointer to the function in the VDSO, which
>> returns the address of the 'mult' field in the vsyscall_gtod_data.
>
> No, that's just wrong. The VDSO data is solely there for the VDSO accessor
> functions and not to be exposed to random user space.
>
>> Thus user-space programs can use rdtscp and interpret its return values
>> in exactly the same way the kernel would, but without entering the
>> kernel.
>
> The VDSO clock_gettime() functions are providing exactly this mechanism.
>
>> As pointed out in Bug # 198961 :
>> https://bugzilla.kernel.org/show_bug.cgi?id=198961
>> which contains extra test programs and the full story behind this
>> change,
>> using CLOCK_MONOTONIC_RAW without the patch results in
>> a minimum measurable time (latency) of @ 300 - 700ns because of
>> the syscall used by vdso_fallback_gtod() .
>>
>> With the patch, the latency falls to @ 100ns .
>>
>> The latency would be @ 16 - 32 ns if the do_monotonic_raw()
>> handler could record its previous TSC value and seconds return value
>> somewhere, but since the VDSO has no data region or writable page,
>> of course it cannot .
>
> And even if it could, it's not as simple as you want it to be. Clocksources
> can change during runtime and without effective protection the values are
> just garbage.
>
>> Hence, to enable effective use of TSC by user space programs, Linux must
>> provide a way for them to discover the calibration mult and shift values
>> the kernel uses for the clock source ; only by doing so can user-space
>> get values that are comparable to kernel generated values.
>
> Linux must not do anything. It can provide a vdso implementation of
> CLOCK_MONOTONIC_RAW, which does not enter the kernel, but not exposure to
> data which is not reliably accessible by random user space code.
>
>> And I'd really like to know: why does the gtod->mult value change ?
>> After TSC calibration, it and the shift are calculated to render the
>> best approximation of a nanoseconds value from the TSC value.
>>
>> The TSC is MEANT to be monotonic and to continue in sleep states
>> on modern Intel CPUs . So why does the gtod->mult change ?
>
> You are missing the fact that gtod->mult/shift are used for CLOCK_MONOTONIC
> and CLOCK_REALTIME, which are adjusted by NTP/PTP to provide network
> synchronized time. That means CLOCK_MONOTONIC is providing accurate
> and slope compensated nanoseconds.
>
> The raw TSC conversion, even if it is sane hardware, provides just some
> approximation of nanoseconds which can be off by quite a margin.
>
>> But the mult value does change. Currently there is no way for user-space
>> programs to discover that such a change has occurred, or when . With this
>> very tiny simple patch, they could know instantly when such changes
>> occur, and could implement TSC readers that perform the full conversion
>> with latencies of 15-30ns (on my CPU).
>
> No. Accessing the mult/shift pair without protection is racy and can lead
> to completely erratic results.
>
>> +notrace static int __always_inline do_monotonic_raw( struct timespec
>> *ts)
>> +{
>> + volatile u32 tsc_lo=0, tsc_hi=0, tsc_cpu=0; // so same instrs
>> generated for 64-bit as for 32-bit builds
>> + u64 ns;
>> + register u64 tsc=0;
>> + if (gtod->vclock_mode == VCLOCK_TSC)
>> + { asm volatile
>> + ( "rdtscp"
>> + : "=a" (tsc_lo)
>> + , "=d" (tsc_hi)
>> + , "=c" (tsc_cpu)
>> + ); // : eax, edx, ecx used - NOT rax, rdx, rcx
>
> If you look at the existing VDSO time getters then you'll notice that
> they use accessor functions and not open coded asm constructs.
>
>> + tsc = u64)tsc_hi) & 0xUL) << 32) | (((u64)tsc_lo)
>> & 0xUL);
>> + tsc *= gtod->mult;
>> + tsc >>= gtod->shift;
>> + ts->tv_sec = __iter_div_u64_rem(tsc, NSEC_PER_SEC, &ns);
>> + ts->tv_nsec = ns;
>
> This is horrible. Please look at the kernel side implementation of
> clock_gettime(CLOCK_MONOTONIC_RAW). The VDSO side can be implemented in the
> same way. All what is required is to expose the relevant information in the
> existing vsyscall_gtod_data data stru