刺激战场
六合彩
贵宾厅
  • 1915阅读
  • 2回复

检测CPU的VMX支持 --- intel版 [复制链接]

上一主题 下一主题
离线天道酬勤
 

只看楼主 倒序阅读 使用道具 楼主  发表于: 2016-02-04
— 本帖被 天道酬勤 从 驱动保护 移动到本区(2016-05-19) —
如何检测当前CPU是否支持 VMX 呢?
这里就简单说一下这个。

也不是我写的,我只是来自大自然的搬运工 以下内容的版权为 intel 公司




  1. VMMs need to ensure that the processor is running in pr otected mode with paging before entering VMX operation.
  2. The following list describes the minimal steps required to enter VMX root operation with a VMM running at CPL = 0.
  3. • Check VMX support in processor using CPUID.
  4. • Determine the VMX capabilities supported by the processor through the VMX capability MSRs. See Section
  5. 31.5.1 and Appendix A.
  6. • Create a VMXON region in non-pageable memory of a size specified by IA32_VMX_BASIC MSR and aligned to a
  7. 4-KByte boundary. Software should read the capability MS Rs to determine width of the physical addresses that
  8. may be used for the VMXON region and ensure the entire VMXON region can be addressed by addresses with
  9. that width. Also, software must ensure that the VMXON region is hosted in cache-coherent memory.
  10. • Initialize the version identifier in the VMXON region (the first 31 bits) with the VMCS revision identifier reported
  11. by capability MSRs. Clear bit 31 of the first 4 bytes of the VMXON region.
  12. • Ensure the current processor operating mode meets the required CR0 fixed bits (CR0.PE = 1, CR0.PG = 1).
  13. Other required CR0 fixed bits can be detected through the IA32_VMX_CR0_FIXED0 and
  14. IA32_VMX_CR0_FIXED1 MSRs.
  15. • Enable VMX operation by setting CR4.VMXE = 1. Ensure the resultant CR4 value supports all the CR4 fixed bits
  16. reported in the IA32_VMX_CR4_FIX ED0 and IA32_VMX_CR4_FIXED1 MSRs.
  17. • Ensure that the IA32_FEATURE_CONTROL MSR (MSR index  3AH) has been properly programmed and that its
  18. lock bit is set (Bit 0 = 1). This MSR is gene rally configured by the BIOS using WRMSR.
  19. • Execute VMXON with the physical address of the VMXON region as the operand. Check successful execution of
  20. VMXON by checking if RFLAGS.CF = 0.
  21. Upon successful execution of the steps above, the processor is in VMX root operation.
  22. A VMM executing in VMX root operation and CPL = 0 leaves VMX operation by executing VMXOFF and verifies
  23. successful execution by checking  if RFLAGS.CF = 0 and RFLAGS.ZF = 0.
  24. If an SMM monitor has been configur ed to service SMIs while in VMX operation (see Section 34.15), the SMM
  25. monitor needs to be torn down before the executive monitor can leave VMX operation (see Section 34.15.7).
  26. VMXOFF fails for the executive monitor (a VMM that entered VMX operation by way of issuing VMXON) if SMM
  27. monitor is configured.
复制代码



这里仅仅翻译我们感兴趣的部分,检测部分。

Check VMX support in processor using CPUID.  ==》 通过 CPUID 指令检测 当前处理器是否支持 VMX

检测 ecx 的第5位 用于判断当前 CPU 是否支持 vmx, intel 手册中 Table 3-20.  Feature Information Returned in the ECX Register 有相关记录

有关 CPUID 指令的使用 来自百度百科

  1. cpuid使用eax作为输入参数,eax,ebx,ecx,edx作为输出参数,举个例子:
  2. __asm
  3. {
  4. mov eax, 1
  5. cpuid
  6. ...
  7. }
复制代码




• Enable VMX operation by setting CR4.VMXE = 1. Ensure the resultant CR4 value supports all the CR4 fixed bits
reported in the IA32_VMX_CR4_FIX ED0 and IA32_VMX_CR4_FIXED1 MSRs.


通过 CR4.VMXE( bit 13) 是否为 1 来判断 VMX 指令集是否启用,


//
//  VMXE
//  VMX-Enable Bit (bit 13 of CR4) — Enables VMX operation when set. See Chapter 23, “Introduction to
//  Virtual-Machine Extensions.”
//
//  人话就是,当 CR4.VMXE == 1 时, VMX 操作集被启用,也就是 CPU 支持 VMX 操作集。
//



• Ensure that the IA32_FEATURE_CONTROL MSR (MSR index 3AH) has been properly programmed and that its
lock bit is set (Bit 0 = 1). This MSR is gene rally configured by the BIOS using WRMSR.
通过 MSR index 3AH(即 IA32_FEATURE_CONTROL )这么一个状态寄存器的值的 0 位 来判断 锁是否开启。
简单的说就是 0位 为0时 指令 VMXON 会引起一个 general-protection exception,为1时,这个寄存器的值不能改,改的话也会触发 general-protection exception,
系统可以通过此位来为 BIOS 提供一个选项,去支持或者禁用 VMX 。
在当前平台启用VMX支持,BIOS必须设置 bit 1、bit 2之一或两者都设置,以及锁(bit 0)

Bit 1 enables VMXON in SMX operation.  

Bit 2 enables VMXON outside SMX operation.
这两个我不知道自己的翻译对不对, 就是 是否启用 在 VMXON 外部 或者 内部的 SMX 操作,如果没启用却操作了 也是会报出 全局保护 异常的。


接下来贴几段代码片段,因为是片段所以 中间的函数实现都忽略了,那些函数的话通过名字自己去写也是很容易的



  1. //
  2. // 检测当前CUP是否支持虚拟化 , 摘录自 vmxice
  3. //
  4. NTSTATUS CheckForVirtualizationSupport()
  5. {
  6.         ULONG eax, ebx, ecx, edx;
  7.         /* vmx supported by cpu ? */
  8.         _CpuId(0, &eax, &ebx, &ecx, &edx);
  9.         if (eax < 1)
  10.         {
  11.                 DbgPrint("error: extended CPUID functions not implemented\n");
  12.                 return STATUS_UNSUCCESSFUL;
  13.         }

  14.         /* Intel Genuine */
  15.         if (!(ebx == 0x756e6547 && ecx == 0x6c65746e && edx == 0x49656e69))
  16.         {
  17.                 DbgPrint("error: not an INTEL processor\n");
  18.                 return STATUS_UNSUCCESSFUL;
  19.         }

  20.         _CpuId(0x1, &eax, &ebx, &ecx, &edx);
  21.         //
  22.         // 检测 ecx 的第5位 用于判断当前 CPU 是否支持 vmx, intel 手册中 Table 3-20.  Feature Information Returned in the ECX Register 有相关记录
  23.         //
  24.         if (!IsBitSet(ecx, 5))
  25.         {
  26.                 DbgPrint("error: VMX not supported\n");
  27.                 return STATUS_UNSUCCESSFUL;
  28.         }

  29.         return STATUS_SUCCESS;
  30. }
复制代码


  1. //
  2. // 检查BIOS是否打开Intel-VT,摘录自 Dichlorvos0.72
  3. //

  4. #define X86_CR4_VMXE                0x2000  /* enable VMX */
  5. //                          10000000000000

  6. NTSTATUS CheckBiosIsEnabled()
  7. {
  8.     ULONG cr4;
  9.     ULONG64 msr;

  10.     //
  11.     // 检测Cpu是否支持vmxon指令
  12.     //
  13.     SetCr4( GetCr4() | X86_CR4_VMXE );
  14.     cr4 = GetCr4();

  15.     if( !( cr4 & X86_CR4_VMXE ) )
  16.     {
  17.         KdPrint( ( "Ddvp-> vmoxn指令支持没有打开...\n" ) );
  18.         return STATUS_UNSUCCESSFUL;
  19.     }

  20.     //
  21.     // 检测BIOS是否开启VT
  22.     //
  23.     msr = ReadMsr( MSR_IA32_FEATURE_CONTROL );
  24.     //
  25.     // 4 实际上是  100 也就是  ( bit 2 )
  26.     //
  27.     if( !( msr & 4 ) )
  28.     {
  29.         KdPrint( ( "Ddvp-> BIOS MSR_IA32_FEATURE_CONTROL寄存器值:%p !\n", msr ) );
  30.         return STATUS_UNSUCCESSFUL;
  31.     }

  32.     return STATUS_SUCCESS;
  33. }
复制代码


  1. //
  2. // 检查BIOS是否支持 Intel-VT 并启用,摘录自 new blue pill
  3. //

  4. #define X86_CR4_VMXE                0x2000  /* enable VMX */

  5. NTSTATUS NTAPI VmxEnable (
  6.   PVOID VmxonVA
  7. )
  8. {
  9.   ULONG64 cr4;
  10.   ULONG64 vmxmsr;
  11.   ULONG64 flags;
  12.   PHYSICAL_ADDRESS VmxonPA;

  13.   set_in_cr4 (X86_CR4_VMXE);
  14.   cr4 = get_cr4 ();
  15.   _KdPrint (("VmxEnable(): CR4 after VmxEnable: 0x%llx\n", cr4));
  16.   if (!(cr4 & X86_CR4_VMXE))
  17.     return STATUS_NOT_SUPPORTED;

  18.   vmxmsr = MsrRead (MSR_IA32_FEATURE_CONTROL);
  19.   if (!(vmxmsr & 4)) {
  20.     _KdPrint (("VmxEnable(): VMX is not supported: IA32_FEATURE_CONTROL is 0x%llx\n", vmxmsr));
  21.     return STATUS_NOT_SUPPORTED;
  22.   }

  23.   vmxmsr = MsrRead (MSR_IA32_VMX_BASIC);
  24.   *((ULONG64 *) VmxonVA) = (vmxmsr & 0xffffffff);       //set up vmcs_revision_id
  25.   VmxonPA = MmGetPhysicalAddress (VmxonVA);
  26.   _KdPrint (("VmxEnable(): VmxonPA:  0x%llx\n", VmxonPA.QuadPart));
  27.   VmxTurnOn (MmGetPhysicalAddress (VmxonVA));
  28.   flags = RegGetRflags ();
  29.   _KdPrint (("VmxEnable(): vmcs_revision_id: 0x%x  Eflags: 0x%x \n", vmxmsr, flags));
  30.   return STATUS_SUCCESS;
  31. }
复制代码

后面两个片段中的方法是一样的,可能是 Dichlorvos0.72 的作者参考后者的缘故,这里不清楚,不多说。


终于鼓捣完了,虽然仍旧没什么卵用。
离线im86165507

只看该作者 沙发  发表于: 2016-02-04
离线v2680267313

只看该作者 板凳  发表于: 2016-04-30
用户被禁言,该主题自动屏蔽!
快速回复
限100 字节
如果您在写长篇帖子又不马上发表,建议存为草稿
 
上一个 下一个