2002-06-20 22:54:37

by john stultz

[permalink] [raw]
Subject: [RFC] [PATCH] tsc_disable_B2 with "soft" rdtsc

Hello all,

Here is my next rev of the tsc-disable patch. This one corrects a
Configure.in typo (Caught by Gabriel Paubert), and probably more
controversial, implements a soft rdtsc instruction via do_gettimeofday.

This avoids the earlier "box won't boot" problems with i686 optimized
glibc's that called rdtsc. The rdtsc instruction will now be caught, and
faked returning to the user program the same value of gettimeofday. Yes,
its pretty hackish, but it works, albeit slowly.

Anyway, as always, comments and flames are welcome.
-john


Attachments:
linux-2.4.19-pre10_tsc-disable_B2.patch (5.89 kB)

2002-06-22 01:31:23

by Kasper Dupont

[permalink] [raw]
Subject: Re: [RFC] [PATCH] tsc_disable_B2 with "soft" rdtsc

john stultz wrote:
>
> Hello all,
>
> Here is my next rev of the tsc-disable patch. This one corrects a
> Configure.in typo (Caught by Gabriel Paubert), and probably more
> controversial, implements a soft rdtsc instruction via do_gettimeofday.
>
> This avoids the earlier "box won't boot" problems with i686 optimized
> glibc's that called rdtsc. The rdtsc instruction will now be caught, and
> faked returning to the user program the same value of gettimeofday. Yes,
> its pretty hackish, but it works, albeit slowly.

+#ifdef CONFIG_X86_NUMA
+ /* "soft" rdtsc implementation */
+ if(!cpu_has_tsc)
+ {
+ char rdtsc_inst[2] = {0x0f, 0x31}; /*rdtsc opcode*/
+ char* inst_ptr = (char*)regs->eip;
+ if((inst_ptr[0] == rdtsc_inst[0])
+ &&(inst_ptr[1] == rdtsc_inst[1])){

Any particular reason for puting the opcode in an
array and verify against that instead of just
verifying inst_ptr[i] against the constants?

+ struct timeval tv;
+ do_gettimeofday(&tv);
+ regs->eax = tv.tv_usec;
+ regs->edx = tv.tv_sec;

Looks like the soft tsc is going to be jumping
rather than runing. It is going to be increasing
at a constat rate most of the time, but will make
a big jump ahead every second. Couldn't the jump
easilly be made a lot smaller by using:
regs->eax = tv.tv_usec<<2;

Of course this is not completely accurate either,
are we willing to pay the price for a more
accurate version?

+ regs->eip += 2; /*= size of opcode*/
+ return;
+ }
+ }
+#endif

--
Kasper Dupont -- der bruger for meget tid p? usenet.
For sending spam use mailto:[email protected]