我的主要目标是在程序崩溃时获得由LBR寄存器维护的最后16个分支的地址值。我试过两种方法到现在-
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);但问题是,每次我使用dmesg读取输出时,我得到的只是
Value is 0 (我已经尝试过其他寄存器-它总是为0)
我是不是忘了什么?有什么帮助吗?谢谢
发布于 2012-04-23 15:08:26
使用以下内容:
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;
}发布于 2021-11-06 07:52:59
你可以用伊利亚·马特维奇科夫的答案。或者..。或者是:
#include <asm/msr.h>
int err;
unsigned int msr, cpu;
unsigned long long val;
/* rdmsr without exception handling */
val = rdmsrl(msr);
/* rdmsr with exception handling */
err = rdmsrl_safe(msr, &val);
/* rdmsr on a given CPU (instead of current one) */
err = rdmsrl_safe_on_cpu(cpu, msr, &val);而且还有更多的函数,例如:
int msr_set_bit(u32 msr, u8 bit)int msr_clear_bit(u32 msr, u8 bit)void rdmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr *msrs)int rdmsr_safe_regs_on_cpu(unsigned int cpu, u32 regs[8])看一看/lib/modules/<uname -r>/build/arch/x86/include/asm/msr.h
https://stackoverflow.com/questions/10253325
复制相似问题