Changeset 54201 in vbox for trunk/src/VBox/HostDrivers
- Timestamp:
- Feb 13, 2015 5:13:28 PM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostDrivers/Support/SUPDrv.c
r54181 r54201 216 216 { "SUPR0SuspendVTxOnCpu", (void *)SUPR0SuspendVTxOnCpu }, 217 217 { "SUPR0ResumeVTxOnCpu", (void *)SUPR0ResumeVTxOnCpu }, 218 { "SUPR0GetKernelFeatures", (void *)SUPR0GetKernelFeatures }, 218 219 { "SUPR0GetPagingMode", (void *)SUPR0GetPagingMode }, 219 { "SUPR0GetKernelFeatures", (void *)SUPR0GetKernelFeatures }, 220 { "SUPR0GetSvmUsability", (void *)SUPR0GetSvmUsability }, 221 { "SUPR0GetVmxUsability", (void *)SUPR0GetVmxUsability }, 220 222 { "SUPR0LockMem", (void *)SUPR0LockMem }, 221 223 { "SUPR0LowAlloc", (void *)SUPR0LowAlloc }, … … 3741 3743 3742 3744 /** 3745 * Checks if Intel VT-x feature is usable on this CPU. 3746 * 3747 * @returns VBox status code. 3748 * @param fIsSmxModeAmbiguous Where to write whether the SMX mode causes 3749 * ambiguity that makes us unsure whether we 3750 * really can use VT-x or not. 3751 * 3752 * @remarks Must be called with preemption disabled. 3753 */ 3754 SUPR0DECL(int) SUPR0GetVmxUsability(bool *pfIsSmxModeAmbiguous) 3755 { 3756 Assert(!RTThreadPreemptIsEnabled(NIL_RTTHREAD)); 3757 3758 uint64_t u64FeatMsr = ASMRdMsr(MSR_IA32_FEATURE_CONTROL); 3759 bool const fMaybeSmxMode = RT_BOOL(ASMGetCR4() & X86_CR4_SMXE); 3760 bool fMsrLocked = RT_BOOL(u64FeatMsr & MSR_IA32_FEATURE_CONTROL_LOCK); 3761 bool fSmxVmxAllowed = RT_BOOL(u64FeatMsr & MSR_IA32_FEATURE_CONTROL_SMX_VMXON); 3762 bool fVmxAllowed = RT_BOOL(u64FeatMsr & MSR_IA32_FEATURE_CONTROL_VMXON); 3763 bool fIsSmxModeAmbiguous = false; 3764 int rc = VERR_INTERNAL_ERROR_5; 3765 3766 /* Check if the LOCK bit is set but excludes the required VMXON bit. */ 3767 if (fMsrLocked) 3768 { 3769 if (fVmxAllowed && fSmxVmxAllowed) 3770 rc = VINF_SUCCESS; 3771 else if (!fVmxAllowed && !fSmxVmxAllowed) 3772 rc = VERR_VMX_MSR_ALL_VMXON_DISABLED; 3773 else if (!fMaybeSmxMode) 3774 { 3775 if (fVmxAllowed) 3776 rc = VINF_SUCCESS; 3777 else 3778 rc = VERR_VMX_MSR_VMXON_DISABLED; 3779 } 3780 else 3781 { 3782 /* 3783 * CR4.SMXE is set but this doesn't mean the CPU is necessarily in SMX mode. We shall assume 3784 * that it is -not- and that it is a stupid BIOS/OS setting CR4.SMXE for no good reason. 3785 * See @bugref{6873}. 3786 */ 3787 Assert(fMaybeSmxMode == true); 3788 fIsSmxModeAmbiguous = true; 3789 rc = VINF_SUCCESS; 3790 } 3791 } 3792 else 3793 { 3794 /* 3795 * MSR is not yet locked; we can change it ourselves here. 3796 * Once the lock bit is set, this MSR can no longer be modified. 3797 * 3798 * Set both the VMXON and SMX_VMXON bits as we can't determine SMX mode 3799 * accurately. See @bugref{6873}. 3800 */ 3801 u64FeatMsr |= MSR_IA32_FEATURE_CONTROL_LOCK 3802 | MSR_IA32_FEATURE_CONTROL_SMX_VMXON 3803 | MSR_IA32_FEATURE_CONTROL_VMXON; 3804 ASMWrMsr(MSR_IA32_FEATURE_CONTROL, u64FeatMsr); 3805 3806 /* Verify. */ 3807 u64FeatMsr = ASMRdMsr(MSR_IA32_FEATURE_CONTROL); 3808 fMsrLocked = RT_BOOL(u64FeatMsr & MSR_IA32_FEATURE_CONTROL_LOCK); 3809 fSmxVmxAllowed = fMsrLocked && RT_BOOL(u64FeatMsr & MSR_IA32_FEATURE_CONTROL_SMX_VMXON); 3810 fVmxAllowed = fMsrLocked && RT_BOOL(u64FeatMsr & MSR_IA32_FEATURE_CONTROL_VMXON); 3811 if (fSmxVmxAllowed && fVmxAllowed) 3812 rc = VINF_SUCCESS; 3813 else 3814 rc = VERR_VMX_MSR_LOCKING_FAILED; 3815 } 3816 3817 if (pfIsSmxModeAmbiguous) 3818 *pfIsSmxModeAmbiguous = fIsSmxModeAmbiguous; 3819 3820 return rc; 3821 } 3822 3823 3824 /** 3825 * Checks if AMD-V SVM feature is usable on this CPU. 3826 * 3827 * @returns VBox status code. 3828 * @param fInitSvm If usable, try to initialize SVM on this CPU. 3829 * 3830 * @remarks Must be called with preemption disabled. 3831 */ 3832 SUPR0DECL(int) SUPR0GetSvmUsability(bool fInitSvm) 3833 { 3834 int rc; 3835 uint64_t fVmCr; 3836 uint64_t fEfer; 3837 3838 Assert(!RTThreadPreemptIsEnabled(NIL_RTTHREAD)); 3839 fVmCr = ASMRdMsr(MSR_K8_VM_CR); 3840 if (!(fVmCr & MSR_K8_VM_CR_SVM_DISABLE)) 3841 { 3842 rc = VINF_SUCCESS; 3843 if (fInitSvm) 3844 { 3845 /* Turn on SVM in the EFER MSR. */ 3846 fEfer = ASMRdMsr(MSR_K6_EFER); 3847 if (fEfer & MSR_K6_EFER_SVME) 3848 rc = VERR_SVM_IN_USE; 3849 else 3850 { 3851 ASMWrMsr(MSR_K6_EFER, fEfer | MSR_K6_EFER_SVME); 3852 3853 /* Paranoia. */ 3854 fEfer = ASMRdMsr(MSR_K6_EFER); 3855 if (fEfer & MSR_K6_EFER_SVME) 3856 { 3857 /* Restore previous value. */ 3858 ASMWrMsr(MSR_K6_EFER, fEfer & ~MSR_K6_EFER_SVME); 3859 } 3860 else 3861 rc = VERR_SVM_ILLEGAL_EFER_MSR; 3862 } 3863 } 3864 } 3865 else 3866 rc = VERR_SVM_DISABLED; 3867 return rc; 3868 } 3869 3870 3871 /** 3743 3872 * Queries the AMD-V and VT-x capabilities of the calling CPU. 3744 3873 * … … 3789 3918 ) 3790 3919 { 3791 /** @todo Unify code with hmR0InitIntelCpu(). */ 3792 uint64_t u64FeatMsr = ASMRdMsr(MSR_IA32_FEATURE_CONTROL); 3793 bool const fMaybeSmxMode = RT_BOOL(ASMGetCR4() & X86_CR4_SMXE); 3794 bool fMsrLocked = RT_BOOL(u64FeatMsr & MSR_IA32_FEATURE_CONTROL_LOCK); 3795 bool fSmxVmxAllowed = RT_BOOL(u64FeatMsr & MSR_IA32_FEATURE_CONTROL_SMX_VMXON); 3796 bool fVmxAllowed = RT_BOOL(u64FeatMsr & MSR_IA32_FEATURE_CONTROL_VMXON); 3797 3798 /* Check if the LOCK bit is set but excludes the required VMXON bit. */ 3799 if (fMsrLocked) 3800 { 3801 if (fVmxAllowed && fSmxVmxAllowed) 3802 rc = VINF_SUCCESS; 3803 else if (!fVmxAllowed && !fSmxVmxAllowed) 3804 rc = VERR_VMX_MSR_ALL_VMXON_DISABLED; 3805 else if (!fMaybeSmxMode) 3806 { 3807 if (fVmxAllowed) 3808 rc = VINF_SUCCESS; 3809 else 3810 rc = VERR_VMX_MSR_VMXON_DISABLED; 3811 } 3812 else 3813 { 3814 /* 3815 * CR4.SMXE is set but this doesn't mean the CPU is necessarily in SMX mode. We shall assume 3816 * that it is -not- and that it is a stupid BIOS/OS setting CR4.SMXE for no good reason. 3817 * See @bugref{6873}. 3818 */ 3819 Assert(fMaybeSmxMode == true); 3820 fIsSmxModeAmbiguous = true; 3821 rc = VINF_SUCCESS; 3822 } 3823 } 3824 else 3825 { 3826 /* 3827 * MSR is not yet locked; we can change it ourselves here. 3828 * Once the lock bit is set, this MSR can no longer be modified. 3829 * 3830 * Set both the VMXON and SMX_VMXON bits as we can't determine SMX mode 3831 * accurately. See @bugref{6873}. 3832 */ 3833 u64FeatMsr |= MSR_IA32_FEATURE_CONTROL_LOCK 3834 | MSR_IA32_FEATURE_CONTROL_SMX_VMXON 3835 | MSR_IA32_FEATURE_CONTROL_VMXON; 3836 ASMWrMsr(MSR_IA32_FEATURE_CONTROL, u64FeatMsr); 3837 3838 /* Verify. */ 3839 u64FeatMsr = ASMRdMsr(MSR_IA32_FEATURE_CONTROL); 3840 fMsrLocked = RT_BOOL(u64FeatMsr & MSR_IA32_FEATURE_CONTROL_LOCK); 3841 fSmxVmxAllowed = fMsrLocked && RT_BOOL(u64FeatMsr & MSR_IA32_FEATURE_CONTROL_SMX_VMXON); 3842 fVmxAllowed = fMsrLocked && RT_BOOL(u64FeatMsr & MSR_IA32_FEATURE_CONTROL_VMXON); 3843 if (fSmxVmxAllowed && fVmxAllowed) 3844 rc = VINF_SUCCESS; 3845 else 3846 rc = VERR_VMX_MSR_LOCKING_FAILED; 3847 } 3848 3920 rc = SUPR0GetVmxUsability(&fIsSmxModeAmbiguous); 3849 3921 if (rc == VINF_SUCCESS) 3850 3922 { … … 3871 3943 ASMCpuId(0x80000000, &uExtMaxId, &uDummy, &uDummy, &uDummy); 3872 3944 ASMCpuId(0x80000001, &uDummy, &uDummy, &fExtFeaturesEcx, &uDummy); 3945 3946 /* Check if SVM is available. */ 3873 3947 if ( ASMIsValidExtRange(uExtMaxId) 3874 3948 && uExtMaxId >= 0x8000000a … … 3878 3952 ) 3879 3953 { 3880 /* Check if SVM is disabled */ 3881 uint64_t u64FeatMsr = ASMRdMsr(MSR_K8_VM_CR); 3882 if (!(u64FeatMsr & MSR_K8_VM_CR_SVM_DISABLE)) 3954 rc = SUPR0GetSvmUsability(false /* fInitSvm */); 3955 if (RT_SUCCESS(rc)) 3883 3956 { 3884 3957 uint32_t fSvmFeatures; … … 3889 3962 if (fSvmFeatures & AMD_CPUID_SVM_FEATURE_EDX_NESTED_PAGING) 3890 3963 *pfCaps |= SUPVTCAPS_NESTED_PAGING; 3891 3892 rc = VINF_SUCCESS;3893 3964 } 3894 else3895 rc = VERR_SVM_DISABLED;3896 3965 } 3897 3966 else
Note:
See TracChangeset
for help on using the changeset viewer.