FreeBSD上的{rd,wr}msr_safe
这几天改 FreeBSD 的 coretemp(4) 遇到了一个问题。直接使用 rdmsr 的话,如果那个 MSR 不存在,则会触发 #GP(0),不了解 CPU 型号的情况下直接去杵肯定是不行的。后来翻了一下 cpuctl(4) 的代码发现 FreeBSD 上也有 rdmsr_safe。它的实现并不复杂( sys/amd64/amd64/support.S):
movq PCPU(CURPCB),%r8 // %r8 = PCPU(CURPCB); 将当前CPU的编号保存到r8。
movq $msr_onfault,PCB_ONFAULT(%r8) // 设置发生异常时调用msr_onfault。
然后是翻译 AMD64 ABI:
|
|
最后恢复先前的异常处理状态。
movq %rax,PCB_ONFAULT(%r8)
ret
msr_onfault是一个很简单的处理程序,它将异常处理指针清零,然后将rax置为EFAULT,并直接返回。