K.Sasada's Home Page

こめんとのついか

こめんとこめんと!

message

please set comment :).

_18(Wed)

仮想マシン上で TSC (time stamp counter) がどうなるか、という話。

てっきり、CPU の物理 TSC が返るのかと思ったら、ちゃんと VT-x では trap するようになっているようで。

#if defined(__GNUC__) && defined(__i386__)
typedef unsigned long long tick_t;

static inline tick_t
tick(void)
{
    unsigned long long int x;
    __asm__ __volatile__ ("rdtsc" : "=A" (x));
    return x;
}

#elif defined(__GNUC__) && defined(__x86_64__)
typedef unsigned long long tick_t;

static __inline__ tick_t
tick(void)
{
    unsigned long hi, lo;
    __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
    return ((unsigned long long)lo)|( ((unsigned long long)hi)<<32);
}

#elif defined(_WIN32) && defined(_MSC_VER)
#include <intrin.h>
typedef unsigned __int64 tick_t;

static tick_t
tick(void)
{
    return __rdtsc();
}

#else /* use clock */
typedef clock_t tick_t;
static inline tick_t
tick(void)
{
    return clock();
}
#endif

int main()
{
    volatile int n = 0x100000;
    int i;

    for (i=0; i<n; i++) {
	tick();
    }
}

#if 0
$ gcc -O0 rdtsc.c && time ./a.out

仮想マシン(VirtualBox on Windows):
real    0m1.744s
user    0m1.740s
sys     0m0.000s

同じマシンでのVC:
real    0m0.049s
user    0m0.000s
sys     0m0.015s

別の実機(Debian/Squeeze):
real    0m0.039s
user    0m0.040s
sys     0m0.000s
#endif

明らかに結果が違う。

Stack overflow で、Why is RDTSC a virtualized instruction on modern processors? では、同じような質問をされているんだけど、accuracy が重要なんだよ、とか、そういう話。

side-channel attack というか、VM 上で動いているかどうかの判定に使われないようにする、っていうのも、結局 rdtsc が 30 倍程度遅くなることがわかってしまうので、無理なんじゃないかなぁ。

offsetting を VM-exitting ごとに適切に再設定すれば、RDTSC 命令自体は、CPU 1 命令で済むのかと思ったけど、offsetting の仕様を適切に理解できていない気もする。


元々、clock_gettime() がえらい遅い、ということで調べ始めたのだけど。VM 上の時間取得は大変(鬼門)だなぁ。準仮想化のターゲットにしないのかしら(ホスト側の設定値がそのまま見える、的な)。


好きにコメントを編集してください。ただし、あまり他の人のコメントを書き換えることは感心しません。



back

tton 記述が使えます。YukiWikiな記述してりゃ問題ありません。

「行頭に#code」 と、「行頭に#end」 で挟むと、その間の行は pre で囲まれます。プログラムのソースを書くときに使ってください。

例:

#code

(なんかプログラム書く)

#end

リンクは

[[なまえ|http://www.example.org]]

とか

[[http://www.example.org]]

で貼れます。

$Date: 2003/04/28 10:27:51 $