我试图在用户模式下执行特权指令rdmsr ,我希望得到某种特权错误,但是我得到一个segfault。 我已经检查了这个asm并且根据手册 (1171页),将PERFEVTSEL0加载到了ecx ,这应该是PERFEVTSEL0 。
我想在黑客攻击一个内核模块之前解决这个问题,因为我不希望这个segfault炸毁我的内核。
更新:我在Intel(R) Xeon(R) cpu X3470 。
为什么系统调用unlink太慢?
在Windows上的C代码比在Linux上慢
Windows Xperf diskio操作不会显示一个程序在性能跟踪会话期间读取的文件
#define _GNU_SOURCE #include <stdio.h> #include <stdlib.h> #include <inttypes.h> #include <sched.h> #include <assert.h> uint64_t read_msr(int ecx) { unsigned int a,d; __asm __volatile("rdmsr" : "=a"(a),"=d"(d) : "c"(ecx)); return ((uint64_t)a) | (((uint64_t)d) << 32); } int main(int ac,char **av) { uint64_t start,end; cpu_set_t cpuset; unsigned int c = 0x186; int i = 0; cpu_ZERO(&cpuset); cpu_SET(i,&cpuset); assert(sched_setaffinity(0,sizeof(cpuset),&cpuset) == 0); printf("%lun",read_msr(c)); return 0; }
multithreading开销与相互独立的线程
在Linux上,access()比stat()更快吗?
CreateFileMapping,MapViewOfFile,如何避免阻塞系统内存
我将试图回答的问题:为什么上面的代码会导致SIGSEGV而不是SIGILL ,虽然代码没有内存错误,但是一个非法的指令(从非特权用户速度调用的特权指令)?
我希望得到一个SIGILL与si_code ILL_PRVOPC而不是一个段错误,也是。 你的问题目前是3岁,今天我偶然发现了同样的行为。 我也很失望:-(
段错误的原因是什么?
原因似乎是Linux内核代码决定发送SIGSEGV 。 这里是负责任的功能: http : //elixir.free-electrons.com/linux/v4.9/source/arch/x86/kernel/traps.c#L487看看功能的最后一行。
在你的后续问题中 ,你得到了其他汇编指令的列表,它们被传播为用户空间的SIGSEGV ,尽管它们实际上是一般的保护错误。 我发现你的问题,因为我触发了与cli的行为。
从Linux内核4.9开始,我不知道有什么可靠的方法来区分内存错误(我希望是SIGSEGV )和用户空间的特权指令错误。
这些案件可能是非常黑客和不可移动的。 当特权指令导致SIGSEGV , siginfo_t si_code被设置为一个值,该值不会直接在man 2 sigaction的SIGSEGV部分中列出。 记录的值是SEGV_MAPERR , SEGV_ACCERR , SEGV_PKUERR ,但我得到我系统上的SI_KERNEL (0x80)。 根据手册页, SI_KERNEL是一个“可以放在任何信号的si_code中”的代码。 在strace中,您会看到SIGSEGV {si_signo=SIGSEGV,si_code=SI_KERNEL,si_addr=0} 。 负责的内核代码在这里 。
这个字符串也可以用grep dmesg 。
请永远不要使用这两种方法来区分生产系统中的GPF和内存错误。
你的代码的具体解决方案:只是不要从用户空间运行rdmsr 。 但是,如果你正在寻找一个通用的方法来弄清楚为什么一个程序收到一个SIGSEGV这个答案是非常令人不满意的。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。