2012-04-20 11 views
1

私の主な目的は、プログラムがクラッシュしたときにLBRレジスタによって維持される最後の16の分岐のアドレス値を取得することです。カーネルモジュールからx86 MSRを読む

1)msr-tools これにより、コマンドラインからmsr値を読み取ることができます。私はそれをCプログラム自体からシステムコールし、値を読み取ろうとします。しかし、レジスタ値は、プログラム自体のアドレスに関係していないようです。ほとんどの場合、レジスタはシステムコード内の他のブランチから汚染されている可能性があります。私はリング0と遠くのジャンプの分岐の録音をオフにしようとしました。しかし、それは役に立たない。まだ無関係の値を取得しています。

2)カーネルモジュール経由でアクセスする Ok私は、msrレジスタに直接アクセスし、おそらくレジスタの汚染を回避するために非常に単純なモジュールを書きました(私はこれまでにこれまでやったことがありません)。

#define LBR 0x1d9 //IA32_DEBUGCTL MSR 
        //I first set this to some non 0 value using wrmsr (msr-tools) 
static void __init do_rdmsr(unsigned msr, unsigned unused2) 
{ 
    uint64_t msr_value; 
    __asm__ __volatile__ ("     rdmsr" 
        : "=A" (msr_value) 
        : "c" (msr) 
        ); 

    printk(KERN_EMERG "%lu \n",msr_value); 
} 
static int hello_init(void) 
{ 
    printk(KERN_EMERG "Value is "); 
    do_rdmsr (LBR,0); 
    return 0; 
} 

static void hello_exit(void) 
{ 
    printk(KERN_EMERG "End\n"); 
} 

module_init(hello_init); 
module_exit(hello_exit); 

しかし、問題は、私はちょうど

Value is 0 

を取得し、出力を読み取るためには、dmesgを使用するたびに(私は他のレジスタのためにしようとしたということです - - ここで

は私が持っているものだ、常にそれ0として来る

ここに私が忘れているものはありますか? ヘルプがありますか?おかげ

+0

__asm__ステートメントが無効です。 'rdmsr'はEAX:EDXのペアを返します。詳細は私の答えを見てください。 –

答えて

1

は、次を使用します。

unsigned long long x86_get_msr(int msr) 
{ 
    unsigned long msrl = 0, msrh = 0; 

    /* NOTE: rdmsr is always return EDX:EAX pair value */ 
    asm volatile ("rdmsr" : "=a"(msrl), "=d"(msrh) : "c"(msr)); 

    return ((unsigned long long)msrh << 32) | msrl; 
} 
+0

申し訳ありませんが、私はあなたの提案を試みました。しかし、私はまだ結果としてゼロになっています。 __asm__ __volatile__( "rdmsr": "=" "(msrh))" d(msrh): "c(msr)); msr_value =((符号なしlong long)msrh < <32)| msrl; のprintk(KERN_EMERG、MSR、msr_value) "X%LLXする\ n%読み取る"; } ' 0x1d9ことが常に '[60033.285400]読み取り1D9 0' ない確認を印刷私は紛失している可能性があります – sg88

+0

私は0x01D9 MSRで同じ0の値を持っているので、私は前にuninitializedされていないため、IA32_DEBUGCTLが空であると仮定します.LIBRを有効にしようとすると、IA32_DEBUGCTLにIA32_DEBUGCTLの値を読んでください。 –

+0

あなたああ、それは大丈夫です。 0はほんの一例に過ぎませんでした。 0x1D9の値を何に設定しても、それでも0が読み込まれます。 – sg88

関連する問題