使英特尔TSC抵消工作的问题

时间:2017-07-15 11:00:54

标签: windows assembly x86 intel hypervisor

我遇到了使用我的Hypervisor进行TSC抵消的问题。根据intel手册,您必须确保VM不会退出rdtsc,因此我禁用了rdtsc_exiting。我还启用了use tsc offsetting控件。以这种方式设置VMCS应该允许我写入tsc_offset控制字段来改变VM(客户操作系统)读取TSC的方式。

我在退出处理程序中将控制权交还给VM之前就做了,我将-2000写入TSC偏移字段。

__vmx_vmwrite(Vmcs::kTscOffset, -2000);

我使用此作为我的VmWrite实现:

inline unsigned char __vmx_vmwrite(_In_ size_t field, _In_ size_t field_value) {
  FlagRegister flags = {};
  __asm {
    pushad
    push field_value
    mov eax, field

    _emit 0x0F
    _emit 0x79
    _emit 0x04
    _emit 0x24  // VMWRITE EAX, [ESP]

    pushfd
    pop flags.all

    add esp, 4
    popad
  }
  if (flags.fields.cf) {
    return 2;
  }
  if (flags.fields.zf) {
    return 1;
  }
  return 0;
}

根据intel手册,这应该足以使用TSC抵消。所以为了测试我写了这个小测试程序(在我的情况下CPUID正在做一个VMEXIT):

auto a1 = __rdtsc();
__cpuid(cpuInfo, 0);
auto a2 = __rdtsc();
result = static_cast<int>(a2 - a1);

在准系统机器上,这需要大约120个CPU周期。从我的VM中运行并且rdtsc退出禁用(未启用偏移)时,需要2200个周期才能完成。

最后一个测试然后实现我上面描述的并运行相同的测试。在我的情况下,最终会有相同的2200个周期。

知道Guest OS为什么忽略我放入的任何偏移量?

0 个答案:

没有答案