我正在尝试分析代码以在x86-64处理器上执行。我指的是this英特尔白皮书,还涉及其他SO线程,讨论了使用RDTSCP与CPUID + RDTSC here和here的话题。
在上述白皮书中,使用CPUID + RDTSC的方法被称为不可靠,并且使用统计数据也得到了证明。
CPUID + RDTSC不可靠的原因可能是什么?
同一白皮书中的图1(最小值行为图)和图2(方差行为图)中的图也具有“方波”图案。 什么解释了这种模式?
答案 0 :(得分:2)
我认为他们发现测量间隔内的CPUID会导致总时间的额外变化。他们在 3.2使用RDTSCP指令进行的改进中建议的修复程序突出显示了这样一个事实,即当他们使用CPUID
/ RDTSC
启动和RDTSCP
的定时间隔内没有CPUID。 / CPUID
停止。
如果执行CPUID的时间取决于您进行的查询,也许他们可以在执行CPUID之前确保EAX = 0或EAX = 1,以选择要读取的数据的CPUID叶(http://www.sandpile.org/x86/cpuid.htm#level_0000_0000h)。除此之外,我不确定为什么会这样。
请注意,英特尔白皮书中的内联汇编很烂:如果使用诸如mov
之类的适当输出约束,则不需要这些"=a"(low), "=d"(high)
指令。有关更好的方法,请参见Get CPU cycle count?。
答案 1 :(得分:0)
CPUID + RDTSC不可靠的另一个原因是由于VM侧通道攻击。
在VM内运行CPUID指令将导致VM EXIT时,发生这种情况,因此VM可以根据需要处理CPUID并操纵CPUID指令。
进行此操作会增加额外的时间,并且使用RDTSC会返回“高”值,因为此时将执行“整个VM CPUID操作”。
然后可以使用该值来检测我们是否在VM内部运行。
可以通过扩展或虚拟化TSC的VM阻止这种行为,从而使RDTSC不可靠