Changeset 75440 in vbox
- Timestamp:
- Nov 14, 2018 6:23:13 AM (6 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 9 edited
-
include/VBox/vmm/cpum.h (modified) (2 diffs)
-
include/VBox/vmm/hm.h (modified) (2 diffs)
-
src/VBox/VMM/Makefile.kmk (modified) (3 diffs)
-
src/VBox/VMM/VMMAll/CPUMAllSvm.cpp (added)
-
src/VBox/VMM/VMMAll/CPUMAllVmx.cpp (added)
-
src/VBox/VMM/VMMAll/HMSVMAll.cpp (modified) (1 diff)
-
src/VBox/VMM/VMMAll/HMVMXAll.cpp (modified) (2 diffs)
-
src/VBox/VMM/VMMAll/IEMAllCImplSvmInstr.cpp.h (modified) (2 diffs)
-
src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp.h (modified) (3 diffs)
-
src/VBox/VMM/VMMR0/HMSVMR0.cpp (modified) (3 diffs)
-
src/VBox/VMM/VMMR0/HMVMXR0.cpp (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/vmm/cpum.h
r75413 r75440 32 32 #include <VBox/vmm/stam.h> 33 33 #include <VBox/vmm/vmapi.h> 34 #include <VBox/vmm/hm_svm.h> 35 #include <VBox/vmm/hm_vmx.h> 34 36 35 37 RT_C_DECLS_BEGIN … … 2069 2071 VMMDECL(void) CPUMRawSetEFlags(PVMCPU pVCpu, uint32_t fEfl); 2070 2072 2073 /** @name SVM helpers. 2074 * @{ */ 2075 VMM_INT_DECL(int) CPUMSvmGetMsrpmOffsetAndBit(uint32_t idMsr, uint16_t *pbOffMsrpm, uint8_t *puMsrpmBit); 2076 VMM_INT_DECL(bool) CPUMSvmIsIOInterceptActive(void *pvIoBitmap, uint16_t u16Port, SVMIOIOTYPE enmIoType, uint8_t cbReg, 2077 uint8_t cAddrSizeBits, uint8_t iEffSeg, bool fRep, bool fStrIo, 2078 PSVMIOIOEXITINFO pIoExitInfo); 2079 /** @} */ 2080 2081 /** @name VMX helpers. 2082 * @{ */ 2083 VMM_INT_DECL(int) CPUMVmxGetMsrPermission(void const *pvMsrBitmap, uint32_t idMsr, PVMXMSREXITREAD penmRead, 2084 PVMXMSREXITWRITE penmWrite); 2085 VMM_INT_DECL(bool) CPUMVmxGetIoBitmapPermission(void const *pvIoBitmapA, void const *pvIoBitmapB, uint16_t uPort, 2086 uint8_t cbAccess); 2087 /** @} */ 2088 2071 2089 /** @name Changed flags. 2072 2090 * These flags are used to keep track of which important register that -
trunk/include/VBox/vmm/hm.h
r74695 r75440 141 141 142 142 /** @name All-context VMX helpers. 143 * These are VMX functions (based on VMX specs.) that may be used by IEM/REM and 144 * not VirtualBox functions that are used for hardware-assisted VMX. Those are 145 * declared below under the !IN_RC section. 143 * 144 * These are hardware-assisted VMX functions (used by IEM/REM/CPUM and HM). Helpers 145 * based purely on the Intel VT-x specification (used by IEM/REM and HM) can be 146 * found in CPUM. 146 147 * @{ */ 147 148 VMM_INT_DECL(int) HMVmxGetHostMsrs(PVM pVM, PVMXMSRS pVmxMsrs); … … 150 151 VMM_INT_DECL(int) HMVmxEntryIntInfoInjectTrpmEvent(PVMCPU pVCpu, uint32_t uEntryIntInfo, uint32_t uErrCode, 151 152 uint32_t cbInstr, RTGCUINTPTR GCPtrFaultAddress); 152 VMM_INT_DECL(int) HMVmxGetMsrPermission(void const *pvMsrBitmap, uint32_t idMsr, PVMXMSREXITREAD penmRead,153 PVMXMSREXITWRITE penmWrite);154 VMM_INT_DECL(bool) HMVmxGetIoBitmapPermission(void const *pvIoBitmapA, void const *pvIoBitmapB, uint16_t uPort,155 uint8_t cbAccess);156 153 /** @} */ 157 154 158 155 /** @name All-context SVM helpers. 159 156 * 160 * These are SVM functions (based on AMD specs.) that may be used by IEM/REM and161 * not VirtualBox functions that are used for hardware-assisted SVM. Those are162 * declared below under the !IN_RC section.157 * These are hardware-assisted SVM functions (used by IEM/REM/CPUM and HM). Helpers 158 * based purely on the AMD SVM specification (used by IEM/REM and HM) can be found 159 * in CPUM. 163 160 * @{ */ 164 161 VMM_INT_DECL(TRPMEVENT) HMSvmEventToTrpmEventType(PCSVMEVENT pSvmEvent); 165 VMM_INT_DECL(int) HMSvmGetMsrpmOffsetAndBit(uint32_t idMsr, uint16_t *pbOffMsrpm, uint8_t *puMsrpmBit);166 VMM_INT_DECL(bool) HMSvmIsIOInterceptActive(void *pvIoBitmap, uint16_t u16Port, SVMIOIOTYPE enmIoType, uint8_t cbReg,167 uint8_t cAddrSizeBits, uint8_t iEffSeg, bool fRep, bool fStrIo,168 PSVMIOIOEXITINFO pIoExitInfo);169 162 /** @} */ 170 163 -
trunk/src/VBox/VMM/Makefile.kmk
r75173 r75440 171 171 VMMAll/CPUMAllRegs.cpp \ 172 172 VMMAll/CPUMAllMsrs.cpp \ 173 VMMAll/CPUMAllSvm.cpp \ 174 VMMAll/CPUMAllVmx.cpp \ 173 175 VMMAll/CPUMStack.cpp \ 174 176 VMMAll/DBGFAll.cpp \ … … 560 562 VMMAll/CPUMAllRegs.cpp \ 561 563 VMMAll/CPUMAllMsrs.cpp \ 564 VMMAll/CPUMAllSvm.cpp \ 565 VMMAll/CPUMAllVmx.cpp \ 562 566 VMMAll/DBGFAll.cpp \ 563 567 VMMAll/IEMAll.cpp \ … … 711 715 VMMAll/CPUMAllRegs.cpp \ 712 716 VMMAll/CPUMAllMsrs.cpp \ 717 VMMAll/CPUMAllSvm.cpp \ 718 VMMAll/CPUMAllVmx.cpp \ 713 719 VMMAll/CPUMStack.cpp \ 714 720 VMMAll/DBGFAll.cpp \ -
trunk/src/VBox/VMM/VMMAll/HMSVMAll.cpp
r73606 r75440 325 325 326 326 /** 327 * Gets the MSR permission bitmap byte and bit offset for the specified MSR.328 *329 * @returns VBox status code.330 * @param idMsr The MSR being requested.331 * @param pbOffMsrpm Where to store the byte offset in the MSR permission332 * bitmap for @a idMsr.333 * @param puMsrpmBit Where to store the bit offset starting at the byte334 * returned in @a pbOffMsrpm.335 */336 VMM_INT_DECL(int) HMSvmGetMsrpmOffsetAndBit(uint32_t idMsr, uint16_t *pbOffMsrpm, uint8_t *puMsrpmBit)337 {338 Assert(pbOffMsrpm);339 Assert(puMsrpmBit);340 341 /*342 * MSRPM Layout:343 * Byte offset MSR range344 * 0x000 - 0x7ff 0x00000000 - 0x00001fff345 * 0x800 - 0xfff 0xc0000000 - 0xc0001fff346 * 0x1000 - 0x17ff 0xc0010000 - 0xc0011fff347 * 0x1800 - 0x1fff Reserved348 *349 * Each MSR is represented by 2 permission bits (read and write).350 */351 if (idMsr <= 0x00001fff)352 {353 /* Pentium-compatible MSRs. */354 uint32_t const bitoffMsr = idMsr << 1;355 *pbOffMsrpm = bitoffMsr >> 3;356 *puMsrpmBit = bitoffMsr & 7;357 return VINF_SUCCESS;358 }359 360 if ( idMsr >= 0xc0000000361 && idMsr <= 0xc0001fff)362 {363 /* AMD Sixth Generation x86 Processor MSRs. */364 uint32_t const bitoffMsr = (idMsr - 0xc0000000) << 1;365 *pbOffMsrpm = 0x800 + (bitoffMsr >> 3);366 *puMsrpmBit = bitoffMsr & 7;367 return VINF_SUCCESS;368 }369 370 if ( idMsr >= 0xc0010000371 && idMsr <= 0xc0011fff)372 {373 /* AMD Seventh and Eighth Generation Processor MSRs. */374 uint32_t const bitoffMsr = (idMsr - 0xc0010000) << 1;375 *pbOffMsrpm = 0x1000 + (bitoffMsr >> 3);376 *puMsrpmBit = bitoffMsr & 7;377 return VINF_SUCCESS;378 }379 380 *pbOffMsrpm = 0;381 *puMsrpmBit = 0;382 return VERR_OUT_OF_RANGE;383 }384 385 386 /**387 * Determines whether an IOIO intercept is active for the nested-guest or not.388 *389 * @param pvIoBitmap Pointer to the nested-guest IO bitmap.390 * @param u16Port The IO port being accessed.391 * @param enmIoType The type of IO access.392 * @param cbReg The IO operand size in bytes.393 * @param cAddrSizeBits The address size bits (for 16, 32 or 64).394 * @param iEffSeg The effective segment number.395 * @param fRep Whether this is a repeating IO instruction (REP prefix).396 * @param fStrIo Whether this is a string IO instruction.397 * @param pIoExitInfo Pointer to the SVMIOIOEXITINFO struct to be filled.398 * Optional, can be NULL.399 */400 VMM_INT_DECL(bool) HMSvmIsIOInterceptActive(void *pvIoBitmap, uint16_t u16Port, SVMIOIOTYPE enmIoType, uint8_t cbReg,401 uint8_t cAddrSizeBits, uint8_t iEffSeg, bool fRep, bool fStrIo,402 PSVMIOIOEXITINFO pIoExitInfo)403 {404 Assert(cAddrSizeBits == 16 || cAddrSizeBits == 32 || cAddrSizeBits == 64);405 Assert(cbReg == 1 || cbReg == 2 || cbReg == 4 || cbReg == 8);406 407 /*408 * The IOPM layout:409 * Each bit represents one 8-bit port. That makes a total of 0..65535 bits or410 * two 4K pages.411 *412 * For IO instructions that access more than a single byte, the permission bits413 * for all bytes are checked; if any bit is set to 1, the IO access is intercepted.414 *415 * Since it's possible to do a 32-bit IO access at port 65534 (accessing 4 bytes),416 * we need 3 extra bits beyond the second 4K page.417 */418 static const uint16_t s_auSizeMasks[] = { 0, 1, 3, 0, 0xf, 0, 0, 0 };419 420 uint16_t const offIopm = u16Port >> 3;421 uint16_t const fSizeMask = s_auSizeMasks[(cAddrSizeBits >> SVM_IOIO_OP_SIZE_SHIFT) & 7];422 uint8_t const cShift = u16Port - (offIopm << 3);423 uint16_t const fIopmMask = (1 << cShift) | (fSizeMask << cShift);424 425 uint8_t const *pbIopm = (uint8_t *)pvIoBitmap;426 Assert(pbIopm);427 pbIopm += offIopm;428 uint16_t const u16Iopm = *(uint16_t *)pbIopm;429 if (u16Iopm & fIopmMask)430 {431 if (pIoExitInfo)432 {433 static const uint32_t s_auIoOpSize[] =434 { SVM_IOIO_32_BIT_OP, SVM_IOIO_8_BIT_OP, SVM_IOIO_16_BIT_OP, 0, SVM_IOIO_32_BIT_OP, 0, 0, 0 };435 436 static const uint32_t s_auIoAddrSize[] =437 { 0, SVM_IOIO_16_BIT_ADDR, SVM_IOIO_32_BIT_ADDR, 0, SVM_IOIO_64_BIT_ADDR, 0, 0, 0 };438 439 pIoExitInfo->u = s_auIoOpSize[cbReg & 7];440 pIoExitInfo->u |= s_auIoAddrSize[(cAddrSizeBits >> 4) & 7];441 pIoExitInfo->n.u1Str = fStrIo;442 pIoExitInfo->n.u1Rep = fRep;443 pIoExitInfo->n.u3Seg = iEffSeg & 7;444 pIoExitInfo->n.u1Type = enmIoType;445 pIoExitInfo->n.u16Port = u16Port;446 }447 return true;448 }449 450 /** @todo remove later (for debugging as VirtualBox always traps all IO451 * intercepts). */452 AssertMsgFailed(("iemSvmHandleIOIntercept: We expect an IO intercept here!\n"));453 return false;454 }455 456 457 /**458 327 * Returns whether HM has cached the nested-guest VMCB. 459 328 * -
trunk/src/VBox/VMM/VMMAll/HMVMXAll.cpp
r75301 r75440 442 442 443 443 /** 444 * Gets the descripti on of a VMX instruction/Vm-exit diagnostic.444 * Gets the descriptive name of a VMX instruction/VM-exit diagnostic code. 445 445 * 446 446 * @returns The descriptive string. … … 879 879 } 880 880 881 882 /**883 * Gets the permission bits for the specified MSR in the specified MSR bitmap.884 *885 * @returns VBox status code.886 * @param pvMsrBitmap Pointer to the MSR bitmap.887 * @param idMsr The MSR.888 * @param penmRead Where to store the read permissions. Optional, can be889 * NULL.890 * @param penmWrite Where to store the write permissions. Optional, can be891 * NULL.892 */893 VMM_INT_DECL(int) HMVmxGetMsrPermission(void const *pvMsrBitmap, uint32_t idMsr, PVMXMSREXITREAD penmRead,894 PVMXMSREXITWRITE penmWrite)895 {896 AssertPtrReturn(pvMsrBitmap, VERR_INVALID_PARAMETER);897 898 int32_t iBit;899 uint8_t const *pbMsrBitmap = (uint8_t *)pvMsrBitmap;900 901 /*902 * MSR Layout:903 * Byte index MSR range Interpreted as904 * 0x000 - 0x3ff 0x00000000 - 0x00001fff Low MSR read bits.905 * 0x400 - 0x7ff 0xc0000000 - 0xc0001fff High MSR read bits.906 * 0x800 - 0xbff 0x00000000 - 0x00001fff Low MSR write bits.907 * 0xc00 - 0xfff 0xc0000000 - 0xc0001fff High MSR write bits.908 *909 * A bit corresponding to an MSR within the above range causes a VM-exit910 * if the bit is 1 on executions of RDMSR/WRMSR.911 *912 * If an MSR falls out of the MSR range, it always cause a VM-exit.913 *914 * See Intel spec. 24.6.9 "MSR-Bitmap Address".915 */916 if (idMsr <= 0x00001fff)917 iBit = idMsr;918 else if ( idMsr >= 0xc0000000919 && idMsr <= 0xc0001fff)920 {921 iBit = (idMsr - 0xc0000000);922 pbMsrBitmap += 0x400;923 }924 else925 {926 if (penmRead)927 *penmRead = VMXMSREXIT_INTERCEPT_READ;928 if (penmWrite)929 *penmWrite = VMXMSREXIT_INTERCEPT_WRITE;930 Log(("HMVmxGetMsrPermission: Warning! Out of range MSR %#RX32\n", idMsr));931 return VINF_SUCCESS;932 }933 934 /* Validate the MSR bit position. */935 Assert(iBit <= 0x1fff);936 937 /* Get the MSR read permissions. */938 if (penmRead)939 {940 if (ASMBitTest(pbMsrBitmap, iBit))941 *penmRead = VMXMSREXIT_INTERCEPT_READ;942 else943 *penmRead = VMXMSREXIT_PASSTHRU_READ;944 }945 946 /* Get the MSR write permissions. */947 if (penmWrite)948 {949 if (ASMBitTest(pbMsrBitmap + 0x800, iBit))950 *penmWrite = VMXMSREXIT_INTERCEPT_WRITE;951 else952 *penmWrite = VMXMSREXIT_PASSTHRU_WRITE;953 }954 955 return VINF_SUCCESS;956 }957 958 959 /**960 * Gets the permission bits for the specified I/O port from the given I/O bitmaps.961 *962 * @returns @c true if the I/O port access must cause a VM-exit, @c false otherwise.963 * @param pvIoBitmapA Pointer to I/O bitmap A.964 * @param pvIoBitmapB Pointer to I/O bitmap B.965 * @param uPort The I/O port being accessed.966 * @param cbAccess The size of the I/O access in bytes (1, 2 or 4 bytes).967 */968 VMM_INT_DECL(bool) HMVmxGetIoBitmapPermission(void const *pvIoBitmapA, void const *pvIoBitmapB, uint16_t uPort, uint8_t cbAccess)969 {970 Assert(cbAccess == 1 || cbAccess == 2 || cbAccess == 4);971 972 /*973 * If the I/O port access wraps around the 16-bit port I/O space,974 * we must cause a VM-exit.975 *976 * See Intel spec. 25.1.3 "Instructions That Cause VM Exits Conditionally".977 */978 /** @todo r=ramshankar: Reading 1, 2, 4 bytes at ports 0xffff, 0xfffe and 0xfffc979 * respectively are valid and do not constitute a wrap around from what I980 * understand. Verify this later. */981 uint32_t const uPortLast = uPort + cbAccess;982 if (uPortLast > 0x10000)983 return true;984 985 /* Read the appropriate bit from the corresponding IO bitmap. */986 void const *pvIoBitmap = uPort < 0x8000 ? pvIoBitmapA : pvIoBitmapB;987 return ASMBitTest(pvIoBitmap, uPort);988 }989 -
trunk/src/VBox/VMM/VMMAll/IEMAllCImplSvmInstr.cpp.h
r74792 r75440 985 985 SVMIOIOEXITINFO IoExitInfo; 986 986 void *pvIoBitmap = pVCpu->cpum.GstCtx.hwvirt.svm.CTX_SUFF(pvIoBitmap); 987 bool const fIntercept = HMSvmIsIOInterceptActive(pvIoBitmap, u16Port, enmIoType, cbReg, cAddrSizeBits, iEffSeg, fRep, fStrIo,988 &IoExitInfo);987 bool const fIntercept = CPUMSvmIsIOInterceptActive(pvIoBitmap, u16Port, enmIoType, cbReg, cAddrSizeBits, iEffSeg, fRep, 988 fStrIo, &IoExitInfo); 989 989 if (fIntercept) 990 990 { … … 1034 1034 uint16_t offMsrpm; 1035 1035 uint8_t uMsrpmBit; 1036 int rc = HMSvmGetMsrpmOffsetAndBit(idMsr, &offMsrpm, &uMsrpmBit);1036 int rc = CPUMSvmGetMsrpmOffsetAndBit(idMsr, &offMsrpm, &uMsrpmBit); 1037 1037 if (RT_SUCCESS(rc)) 1038 1038 { -
trunk/src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp.h
r75412 r75440 2986 2986 Assert(pbIoBitmapA); 2987 2987 Assert(pbIoBitmapB); 2988 return HMVmxGetIoBitmapPermission(pbIoBitmapA, pbIoBitmapB, u16Port, cbAccess);2988 return CPUMVmxGetIoBitmapPermission(pbIoBitmapA, pbIoBitmapB, u16Port, cbAccess); 2989 2989 } 2990 2990 … … 6726 6726 { 6727 6727 VMXMSREXITREAD enmRead; 6728 int rc = HMVmxGetMsrPermission(pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pvMsrBitmap), idMsr, &enmRead,6729 NULL /* penmWrite */);6728 int rc = CPUMVmxGetMsrPermission(pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pvMsrBitmap), idMsr, &enmRead, 6729 NULL /* penmWrite */); 6730 6730 AssertRC(rc); 6731 6731 if (enmRead == VMXMSREXIT_INTERCEPT_READ) … … 6735 6735 { 6736 6736 VMXMSREXITWRITE enmWrite; 6737 int rc = HMVmxGetMsrPermission(pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pvMsrBitmap), idMsr, NULL /* penmRead */,6738 &enmWrite);6737 int rc = CPUMVmxGetMsrPermission(pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pvMsrBitmap), idMsr, NULL /* penmRead */, 6738 &enmWrite); 6739 6739 AssertRC(rc); 6740 6740 if (enmWrite == VMXMSREXIT_INTERCEPT_WRITE) -
trunk/src/VBox/VMM/VMMR0/HMSVMR0.cpp
r75146 r75440 872 872 uint16_t offMsrpm; 873 873 uint8_t uMsrpmBit; 874 int rc = HMSvmGetMsrpmOffsetAndBit(idMsr, &offMsrpm, &uMsrpmBit);874 int rc = CPUMSvmGetMsrpmOffsetAndBit(idMsr, &offMsrpm, &uMsrpmBit); 875 875 AssertRC(rc); 876 876 … … 5156 5156 const bool fStrIo = pIoExitInfo->n.u1Str; 5157 5157 5158 return HMSvmIsIOInterceptActive(pvIoBitmap, u16Port, enmIoType, cbReg, cAddrSizeBits, iEffSeg, fRep, fStrIo,5159 NULL /* pIoExitInfo */);5158 return CPUMSvmIsIOInterceptActive(pvIoBitmap, u16Port, enmIoType, cbReg, cAddrSizeBits, iEffSeg, fRep, fStrIo, 5159 NULL /* pIoExitInfo */); 5160 5160 } 5161 5161 … … 5248 5248 uint16_t offMsrpm; 5249 5249 uint8_t uMsrpmBit; 5250 int rc = HMSvmGetMsrpmOffsetAndBit(idMsr, &offMsrpm, &uMsrpmBit);5250 int rc = CPUMSvmGetMsrpmOffsetAndBit(idMsr, &offMsrpm, &uMsrpmBit); 5251 5251 if (RT_SUCCESS(rc)) 5252 5252 { -
trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp
r75265 r75440 1738 1738 VMXMSREXITREAD enmRead; 1739 1739 VMXMSREXITWRITE enmWrite; 1740 rc = HMVmxGetMsrPermission(pVCpu->hm.s.vmx.pvMsrBitmap, pGuestMsr->u32Msr, &enmRead, &enmWrite);1740 rc = CPUMVmxGetMsrPermission(pVCpu->hm.s.vmx.pvMsrBitmap, pGuestMsr->u32Msr, &enmRead, &enmWrite); 1741 1741 AssertMsgReturnVoid(rc == VINF_SUCCESS, ("HMVmxGetMsrPermission! failed. rc=%Rrc\n", rc)); 1742 1742 if (pGuestMsr->u32Msr == MSR_K6_EFER) … … 11963 11963 VMXMSREXITREAD enmRead; 11964 11964 VMXMSREXITWRITE enmWrite; 11965 int rc2 = HMVmxGetMsrPermission(pVCpu->hm.s.vmx.pvMsrBitmap, idMsr, &enmRead, &enmWrite);11965 int rc2 = CPUMVmxGetMsrPermission(pVCpu->hm.s.vmx.pvMsrBitmap, idMsr, &enmRead, &enmWrite); 11966 11966 AssertRCReturn(rc2, rc2); 11967 11967 if (enmRead == VMXMSREXIT_PASSTHRU_READ) … … 12108 12108 VMXMSREXITREAD enmRead; 12109 12109 VMXMSREXITWRITE enmWrite; 12110 int rc2 = HMVmxGetMsrPermission(pVCpu->hm.s.vmx.pvMsrBitmap, idMsr, &enmRead, &enmWrite);12110 int rc2 = CPUMVmxGetMsrPermission(pVCpu->hm.s.vmx.pvMsrBitmap, idMsr, &enmRead, &enmWrite); 12111 12111 AssertRCReturn(rc2, rc2); 12112 12112 if (enmWrite == VMXMSREXIT_PASSTHRU_WRITE)
Note:
See TracChangeset
for help on using the changeset viewer.

