| 587 | } |
| 588 | |
| 589 | static bool IsSvmSupported() |
| 590 | { |
| 591 | CPUID_REGS Regs = {}; |
| 592 | |
| 593 | // Check the 'AuthenticAMD' vendor name: |
| 594 | __cpuid(Regs.Raw, CPUID::Generic::CPUID_MAXIMUM_FUNCTION_NUMBER_AND_VENDOR_ID); |
| 595 | if (Regs.Regs.Ebx != 'htuA' || Regs.Regs.Edx != 'itne' || Regs.Regs.Ecx != 'DMAc') return false; |
| 596 | |
| 597 | // Check the AMD SVM (AMD-V) support: |
| 598 | constexpr unsigned int CPUID_FN80000001_ECX_SVM = 1 << 2; |
| 599 | __cpuid(Regs.Raw, CPUID::Generic::CPUID_EXTENDED_FEATURE_INFORMATION); |
| 600 | if ((Regs.Regs.Ecx & CPUID_FN80000001_ECX_SVM) == 0) return false; |
| 601 | |
| 602 | // Check the Nested Paging support (AMD-RVI): |
| 603 | constexpr unsigned int CPUID_FN8000000A_EDX_NESTED_PAGING = 1 << 0; |
| 604 | __cpuid(Regs.Raw, CPUID::AMD::CPUID_SVM_FEATURES); |
| 605 | if ((Regs.Regs.Edx & CPUID_FN8000000A_EDX_NESTED_PAGING) == 0) return false; |
| 606 | |
| 607 | // Check that the EFER.SVME is writeable (we can enable the SVM): |
| 608 | VM_CR VmCr = {}; |
| 609 | VmCr.Value = __readmsr(static_cast<unsigned long>(AMD_MSR::MSR_VM_CR)); |
| 610 | if (VmCr.Bitmap.SVMDIS) return false; |
| 611 | |
| 612 | return true; |
| 613 | } |
| 614 | } |
| 615 | |
| 616 | namespace VMX |