儲存庫 vbox 的更動 65366
- 時間撮記:
- 2017-1-18 下午07:34:34 (8 年 以前)
- 位置:
- trunk/src/VBox/ValidationKit/bootsectors
- 檔案:
-
- 修改 4 筆資料
圖例:
- 未更動
- 新增
- 刪除
-
trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-basic-2-pf.c32
r64776 r65366 82 82 /** The size of the test area (at least two pages). */ 83 83 uint32_t cbTest; 84 /** cbTest expressed as a page count. */ 85 uint16_t cTestPages; 86 /** The number of PTEs in the first PTE, i.e. what we can 87 * safely access via PgInfo.u.Pae.pPte/PgInfo.u.Legacy.pPte. */ 88 uint16_t cTest1stPtes; 89 /** The number of PDEs for cTestPages. */ 90 uint16_t cTestPdes; 84 91 /** 16-bit data selector for pbTest. */ 85 92 uint16_t uSel16TestData; 86 93 /** 16-bit code selector for pbTest. */ 87 94 uint16_t uSel16TestCode; 95 /** The size of the PDE backup. */ 96 uint16_t cbPdeBackup; 97 /** The size of the PTE backup. */ 98 uint16_t cbPteBackup; 88 99 /** Test paging information for pbTest. */ 89 100 BS3PAGINGINFO4ADDR PgInfo; … … 91 102 /** Set if we can use the INVLPG instruction. */ 92 103 bool fUseInvlPg; 104 105 /** Reflects CR0.WP. */ 106 bool fWp; 107 /** Reflects EFER.NXE & CR4.PAE. */ 108 bool fNxe; 93 109 94 110 /** Trap context frame. */ … … 97 113 BS3REGCTX ExpectCtx; 98 114 115 /** The PML4E backup. */ 116 uint64_t u64Pml4eBackup; 117 /** The PDPTE backup. */ 118 uint64_t u64PdpteBackup; 119 /** The PDE backup. */ 120 uint64_t au64PdeBackup[16]; 121 /** The PTE backup. */ 122 uint64_t au64PteBackup[X86_PG_PAE_ENTRIES]; 123 99 124 } BS3CPUBASIC2PFSTATE; 100 125 /** Pointer to state for the \#PF test. */ 101 126 typedef BS3CPUBASIC2PFSTATE *PBS3CPUBASIC2PFSTATE; 127 128 129 /** 130 * Paging modification worker. 131 */ 132 typedef struct BS3CPUBASIC2PFMODPT 133 { 134 const char *pszName; 135 uint32_t fPresent : 1; 136 uint32_t fUser : 1; 137 uint32_t fWriteable : 1; 138 uint32_t fNoExecute : 1; 139 uint32_t fReserved : 1; 140 uint32_t uModifyArg : 24; 141 void (*pfnModify)(PBS3CPUBASIC2PFSTATE pThis, unsigned iStore, struct BS3CPUBASIC2PFMODPT const *pEntry); 142 bool (*pfnApplicable)(PBS3CPUBASIC2PFSTATE pThis, struct BS3CPUBASIC2PFMODPT const *pEntry); 143 } BS3CPUBASIC2PFMODPT; 144 typedef BS3CPUBASIC2PFMODPT const *PCBS3CPUBASIC2PFMODPT; 145 146 147 /** 148 * Memory accessor. 149 */ 150 typedef struct BS3CPUBASIC2PFACCESSOR 151 { 152 /** Accessor name. */ 153 const char *pszName; 154 /** The accessor. */ 155 void (*pfnAccessor)(PBS3CPUBASIC2PFSTATE pThis, PBS3REGCTX pCtx, uint8_t bXcpt, uint8_t uPfErrCd, bool fPageLevel); 156 /** The X86_TRAP_PF_XXX access flags this access sets. */ 157 uint32_t fAccess; 158 159 } BS3CPUBASIC2PFACCESSOR; 160 typedef const BS3CPUBASIC2PFACCESSOR *PCBS3CPUBASIC2PFACCESSOR; 102 161 103 162 … … 262 321 263 322 323 /** 324 * Restores all the paging entries from backup and flushes everything. 325 */ 326 static void bs3CpuBasic2Pf_FlushAll(void) 327 { 328 if ((g_uBs3CpuDetected & BS3CPU_TYPE_MASK) >= BS3CPU_80486) 329 { 330 uint32_t uCr4 = ASMGetCR4(); 331 if (uCr4 & (X86_CR4_PGE | X86_CR4_PCIDE)) 332 { 333 ASMSetCR4(uCr4 & ~(X86_CR4_PGE | X86_CR4_PCIDE)); 334 ASMSetCR4(uCr4); 335 return; 336 } 337 } 338 339 ASMReloadCR3(); 340 } 341 342 343 /** 344 * Restores all the paging entries from backup and flushes everything. 345 * 346 * @param pThis Test state data. 347 */ 348 static void bs3CpuBasic2Pf_RestoreFromBackups(PBS3CPUBASIC2PFSTATE pThis) 349 { 350 Bs3MemCpy(pThis->PgInfo.u.Legacy.pPte, pThis->au64PteBackup, pThis->cbPteBackup); 351 Bs3MemCpy(pThis->PgInfo.u.Legacy.pPde, pThis->au64PdeBackup, pThis->cbPdeBackup); 352 if (pThis->PgInfo.cEntries > 2) 353 pThis->PgInfo.u.Pae.pPdpe->u = pThis->u64PdpteBackup; 354 if (pThis->PgInfo.cEntries > 3) 355 pThis->PgInfo.u.Pae.pPml4e->u = pThis->u64Pml4eBackup; 356 bs3CpuBasic2Pf_FlushAll(); 357 } 358 359 360 /** @name BS3CPUBASIC2PFACCESSOR::pfnAccessor Implementations 361 * @{ */ 362 264 363 static void bs3CpuBasic2Pf_DoExec(PBS3CPUBASIC2PFSTATE pThis, PBS3REGCTX pCtx, uint8_t bXcpt, uint8_t uPfErrCd, bool fPageLevel) 265 364 { … … 267 366 unsigned off; 268 367 269 for (off = X86_PAGE_SIZE - 4; off < X86_PAGE_SIZE + 2; off++)368 for (off = X86_PAGE_SIZE - 5; off < X86_PAGE_SIZE + 2; off++) 270 369 { 271 370 /* Emit a little bit of code (using the original allocation mapping) and point pCtx to it. */ … … 295 394 Bs3TrapSetJmpAndRestore(pCtx, &pThis->TrapCtx); 296 395 //Bs3TestPrintf("off=%#06x bXcpt=%#x uErrCd=%#RX64\n", off, pThis->TrapCtx.bXcpt, pThis->TrapCtx.uErrCd); 297 if ( bXcpt == X86_XCPT_PF)298 {299 unsigned offAddPC = !fPageLevel || off >= X86_PAGE_SIZE ? 0 : X86_PAGE_SIZE - off;300 bs3CpuBasic2Pf_CompareSimplePf(pThis, pCtx, offAddPC, uPfErrCd, (uintptr_t)pThis->pbTest + offAddPC);301 }396 if ( bXcpt != X86_XCPT_PF 397 || (fPageLevel && off < X86_PAGE_SIZE - 4)) 398 bs3CpuBasic2Pf_CompareSimpleUd(pThis, pCtx, 3); 399 else if (!fPageLevel || off >= X86_PAGE_SIZE) 400 bs3CpuBasic2Pf_CompareSimplePf(pThis, pCtx, 0, uPfErrCd, (uintptr_t)pThis->pbTest + off); 302 401 else 303 bs3CpuBasic2Pf_CompareSimpleUd(pThis, pCtx, 3); 304 402 bs3CpuBasic2Pf_CompareSimplePf(pThis, pCtx, 403 off + 3 == X86_PAGE_SIZE || off + 4 == X86_PAGE_SIZE 404 ? RT_MIN(X86_PAGE_SIZE, off + 3) - off : 0, 405 uPfErrCd, (uintptr_t)pThis->pbTest + RT_MIN(X86_PAGE_SIZE, off + 4)); 305 406 } 306 407 } … … 382 483 unsigned off = X86_PAGE_SIZE * (i + 1) - pThis->cbAccess; 383 484 unsigned offEnd = X86_PAGE_SIZE * (i + 1) + (i == 0 ? 8 : 7); 485 384 486 for (; off < offEnd; off++) 385 487 { … … 398 500 { 399 501 pThis->ExpectCtx.rax.u = uExpectRax; 400 bs3CpuBasic2Pf_CompareCtx(pThis, &pThis->ExpectCtx, pThis->pCmnMode->MovLoad.offUd2, bXcpt, 0 /*uErrCd*/);502 bs3CpuBasic2Pf_CompareCtx(pThis, &pThis->ExpectCtx, pThis->pCmnMode->MovLoad.offUd2, X86_XCPT_UD, 0 /*uErrCd*/); 401 503 pThis->ExpectCtx.rax = pCtx->rax; 402 504 } … … 482 584 || (fPageLevel && off <= X86_PAGE_SIZE - pThis->cbAccess) ) 483 585 { 484 bs3CpuBasic2Pf_CompareCtx(pThis, &pThis->ExpectCtx, pThis->pCmnMode->MovStore.offUd2, bXcpt, 0 /*uErrCd*/);586 bs3CpuBasic2Pf_CompareCtx(pThis, &pThis->ExpectCtx, pThis->pCmnMode->MovStore.offUd2, X86_XCPT_UD, 0 /*uErrCd*/); 485 587 if (*(uint64_t *)&pThis->pbOrgTest[off] != uExpectStored) 486 588 Bs3TestFailedF("%u - %s: Stored %#RX64, expected %#RX64", … … 580 682 { 581 683 pThis->ExpectCtx.rax.u = uExpectedRax; 582 bs3CpuBasic2Pf_CompareCtx(pThis, &pThis->ExpectCtx, pThis->pCmnMode->Xchg.offUd2, bXcpt, 0 /*uErrCd*/);684 bs3CpuBasic2Pf_CompareCtx(pThis, &pThis->ExpectCtx, pThis->pCmnMode->Xchg.offUd2, X86_XCPT_UD, 0 /*uErrCd*/); 583 685 if (*(uint64_t *)&pThis->pbOrgTest[off] != uExpectStored) 584 686 Bs3TestFailedF("%u - %s: Stored %#RX64, expected %#RX64", … … 702 804 pThis->ExpectCtx.rax.u = uExpectedRax; 703 805 pThis->ExpectCtx.rflags.u32 = uExpectedFlags; 704 bs3CpuBasic2Pf_CompareCtx(pThis, &pThis->ExpectCtx, pThis->pCmnMode->CmpXchg.offUd2, bXcpt, 0 /*uErrCd*/);806 bs3CpuBasic2Pf_CompareCtx(pThis, &pThis->ExpectCtx, pThis->pCmnMode->CmpXchg.offUd2, X86_XCPT_UD, 0 /*uErrCd*/); 705 807 if (*(uint64_t *)&pThis->pbOrgTest[off] != uExpectStored) 706 808 Bs3TestFailedF("%u - %s: Stored %#RX64, expected %#RX64", … … 729 831 730 832 833 static void bs3CpuBasic2Pf_DoCmpXchgMiss(PBS3CPUBASIC2PFSTATE pThis, PBS3REGCTX pCtx, uint8_t bXcpt, uint8_t uPfErrCd, 834 bool fPageLevel) 835 { 836 bs3CpuBasic2Pf_DoCmpXchg(pThis, pCtx, bXcpt, uPfErrCd, fPageLevel, true /*fMissmatch*/ ); 837 } 838 839 840 static void bs3CpuBasic2Pf_DoCmpXchgMatch(PBS3CPUBASIC2PFSTATE pThis, PBS3REGCTX pCtx, uint8_t bXcpt, uint8_t uPfErrCd, 841 bool fPageLevel) 842 { 843 bs3CpuBasic2Pf_DoCmpXchg(pThis, pCtx, bXcpt, uPfErrCd, fPageLevel, false /*fMissmatch*/ ); 844 } 845 846 847 static BS3CPUBASIC2PFACCESSOR const g_aAccessors[] = 848 { 849 { "DoExec", bs3CpuBasic2Pf_DoExec, X86_TRAP_PF_ID }, 850 { "DoMovLoad", bs3CpuBasic2Pf_DoMovLoad, 0 }, 851 { "DoMovStore", bs3CpuBasic2Pf_DoMovStore, X86_TRAP_PF_RW }, 852 { "DoXchg", bs3CpuBasic2Pf_DoXchg, X86_TRAP_PF_RW }, 853 { "DoCmpXchgMiss", bs3CpuBasic2Pf_DoCmpXchgMiss, X86_TRAP_PF_RW }, 854 { "DoCmpXhcgMatch", bs3CpuBasic2Pf_DoCmpXchgMatch, X86_TRAP_PF_RW }, 855 }; 856 857 /** @} */ 858 859 860 /** @name BS3CPUBASIC2PFMODPT::pfnModify implementations. 861 * @{ */ 862 863 864 static void bs3CpuBasic2Pf_ClearMask(PBS3CPUBASIC2PFSTATE pThis, unsigned iStore, PCBS3CPUBASIC2PFMODPT pEntry) 865 { 866 if (pThis->PgInfo.cbEntry == 4) 867 g_aStoreMethods[iStore].pfnStore(pThis->PgInfo.u.Legacy.pPte + 1, 868 pThis->PgInfo.u.Legacy.pPte[1].u & ~(uint32_t)pEntry->uModifyArg, 869 pThis->PgInfo.u.Legacy.pPte[1].u); 870 else 871 g_aStoreMethods[iStore].pfnStore(pThis->PgInfo.u.Pae.pPte + 1, 872 pThis->PgInfo.u.Pae.pPte[1].au32[0] & ~(uint32_t)pEntry->uModifyArg, 873 pThis->PgInfo.u.Pae.pPte[1].au32[0]); 874 } 875 876 static void bs3CpuBasic2Pf_SetBit(PBS3CPUBASIC2PFSTATE pThis, unsigned iStore, PCBS3CPUBASIC2PFMODPT pEntry) 877 { 878 if (pThis->PgInfo.cbEntry == 4) 879 g_aStoreMethods[iStore].pfnStore(pThis->PgInfo.u.Legacy.pPte + 1, 880 pThis->PgInfo.u.Legacy.pPte[1].u | RT_BIT_32(pEntry->uModifyArg), 881 pThis->PgInfo.u.Legacy.pPte[1].u); 882 else if (pEntry->uModifyArg < 32) 883 g_aStoreMethods[iStore].pfnStore(pThis->PgInfo.u.Pae.pPte + 1, 884 pThis->PgInfo.u.Pae.pPte[1].au32[0] | RT_BIT_32(pEntry->uModifyArg), 885 pThis->PgInfo.u.Pae.pPte[1].au32[0]); 886 else 887 g_aStoreMethods[iStore].pfnStore(&pThis->PgInfo.u.Pae.pPte[1].au32[1], 888 pThis->PgInfo.u.Pae.pPte[1].au32[1] | RT_BIT_32(pEntry->uModifyArg - 32), 889 pThis->PgInfo.u.Pae.pPte[1].au32[1]); 890 } 891 892 static void bs3CpuBasic2Pf_ClearBit(PBS3CPUBASIC2PFSTATE pThis, unsigned iStore, PCBS3CPUBASIC2PFMODPT pEntry) 893 { 894 if (pThis->PgInfo.cbEntry == 4) 895 g_aStoreMethods[iStore].pfnStore(pThis->PgInfo.u.Legacy.pPte + 1, 896 pThis->PgInfo.u.Legacy.pPte[1].u & ~RT_BIT_32(pEntry->uModifyArg), 897 pThis->PgInfo.u.Legacy.pPte[1].u); 898 else if (pEntry->uModifyArg < 32) 899 g_aStoreMethods[iStore].pfnStore(pThis->PgInfo.u.Pae.pPte + 1, 900 pThis->PgInfo.u.Pae.pPte[1].au32[0] & ~RT_BIT_32(pEntry->uModifyArg), 901 pThis->PgInfo.u.Pae.pPte[1].au32[0]); 902 else 903 g_aStoreMethods[iStore].pfnStore(&pThis->PgInfo.u.Pae.pPte[1].au32[1], 904 pThis->PgInfo.u.Pae.pPte[1].au32[1] & ~RT_BIT_32(pEntry->uModifyArg - 32), 905 pThis->PgInfo.u.Pae.pPte[1].au32[1]); 906 } 907 908 909 static void bs3CpuBasic2Pf_NoChange(PBS3CPUBASIC2PFSTATE pThis, unsigned iStore, PCBS3CPUBASIC2PFMODPT pEntry) 910 { 911 RT_NOREF3(pThis, iStore, pEntry); 912 } 913 914 /** @} */ 915 916 917 /** @name BS3CPUBASIC2PFMODPT::pfnApplicable implementations. 918 * @{ */ 919 920 static bool bs3CpuBasic2Pf_IsPteBitReserved(PBS3CPUBASIC2PFSTATE pThis, PCBS3CPUBASIC2PFMODPT pEntry) 921 { 922 if (pThis->PgInfo.cbEntry == 8) 923 { 924 if (pThis->PgInfo.cEntries == 3) 925 { 926 if ((uint32_t)(pEntry->uModifyArg - 52U) < (uint32_t)(12 - pThis->fNxe)) 927 return true; 928 } 929 else if (pEntry->uModifyArg == 63 && !pThis->fNxe) 930 return true; 931 } 932 return false; 933 } 934 935 static bool bs3CpuBasic2Pf_IsPteBitSoftwareUsable(PBS3CPUBASIC2PFSTATE pThis, PCBS3CPUBASIC2PFMODPT pEntry) 936 { 937 if (pThis->PgInfo.cbEntry == 8) 938 { 939 if (pThis->PgInfo.cEntries != 3) 940 { 941 if ((uint32_t)(pEntry->uModifyArg - 52U) < (uint32_t)11) 942 return true; 943 } 944 } 945 return false; 946 } 947 948 949 static bool bs3CpuBasic2Pf_IsNxe(PBS3CPUBASIC2PFSTATE pThis, PCBS3CPUBASIC2PFMODPT pEntry) 950 { 951 return pThis->fNxe && pThis->PgInfo.cbEntry == 8; 952 } 953 954 /** @} */ 955 956 957 static const BS3CPUBASIC2PFMODPT g_aPteWorkers[] = 958 { 959 /* { pszName, P U W NX RSV ModiyfArg pfnModify, pfnApplicable }, */ 960 { "org", 1, 1, 1, 0, 0, 0, bs3CpuBasic2Pf_NoChange, NULL }, 961 { "!US", 1, 0, 1, 0, 0, X86_PTE_US, bs3CpuBasic2Pf_ClearMask, NULL }, 962 { "!RW", 1, 1, 0, 0, 0, X86_PTE_RW, bs3CpuBasic2Pf_ClearMask, NULL }, 963 { "!RW+!US", 1, 0, 0, 0, 0, X86_PTE_RW | X86_PTE_US, bs3CpuBasic2Pf_ClearMask, NULL }, 964 { "!P", 0, 0, 0, 0, 0, X86_PTE_P, bs3CpuBasic2Pf_ClearMask, NULL }, 965 { "NX", 1, 1, 1, 1, 0, 63, bs3CpuBasic2Pf_SetBit, bs3CpuBasic2Pf_IsNxe }, 966 { "RSV[52]", 0, 0, 0, 0, 1, 52, bs3CpuBasic2Pf_SetBit, bs3CpuBasic2Pf_IsPteBitReserved }, 967 { "RSV[53]", 0, 0, 0, 0, 1, 53, bs3CpuBasic2Pf_SetBit, bs3CpuBasic2Pf_IsPteBitReserved }, 968 { "RSV[54]", 0, 0, 0, 0, 1, 54, bs3CpuBasic2Pf_SetBit, bs3CpuBasic2Pf_IsPteBitReserved }, 969 { "RSV[55]", 0, 0, 0, 0, 1, 55, bs3CpuBasic2Pf_SetBit, bs3CpuBasic2Pf_IsPteBitReserved }, 970 { "RSV[56]", 0, 0, 0, 0, 1, 56, bs3CpuBasic2Pf_SetBit, bs3CpuBasic2Pf_IsPteBitReserved }, 971 { "RSV[57]", 0, 0, 0, 0, 1, 57, bs3CpuBasic2Pf_SetBit, bs3CpuBasic2Pf_IsPteBitReserved }, 972 { "RSV[58]", 0, 0, 0, 0, 1, 58, bs3CpuBasic2Pf_SetBit, bs3CpuBasic2Pf_IsPteBitReserved }, 973 { "RSV[59]", 0, 0, 0, 0, 1, 59, bs3CpuBasic2Pf_SetBit, bs3CpuBasic2Pf_IsPteBitReserved }, 974 { "RSV[60]", 0, 0, 0, 0, 1, 60, bs3CpuBasic2Pf_SetBit, bs3CpuBasic2Pf_IsPteBitReserved }, 975 { "RSV[61]", 0, 0, 0, 0, 1, 61, bs3CpuBasic2Pf_SetBit, bs3CpuBasic2Pf_IsPteBitReserved }, 976 { "RSV[62]", 0, 0, 0, 0, 1, 62, bs3CpuBasic2Pf_SetBit, bs3CpuBasic2Pf_IsPteBitReserved }, 977 { "RSV[62]", 0, 0, 0, 0, 1, 62, bs3CpuBasic2Pf_SetBit, bs3CpuBasic2Pf_IsPteBitReserved }, 978 { "RSV[63]", 0, 0, 0, 0, 1, 63, bs3CpuBasic2Pf_SetBit, bs3CpuBasic2Pf_IsPteBitReserved }, 979 { "!RSV[52]", 1, 1, 1, 0, 0, 52, bs3CpuBasic2Pf_SetBit, bs3CpuBasic2Pf_IsPteBitSoftwareUsable }, 980 { "!RSV[53]", 1, 1, 1, 0, 0, 53, bs3CpuBasic2Pf_SetBit, bs3CpuBasic2Pf_IsPteBitSoftwareUsable }, 981 { "!RSV[54]", 1, 1, 1, 0, 0, 54, bs3CpuBasic2Pf_SetBit, bs3CpuBasic2Pf_IsPteBitSoftwareUsable }, 982 { "!RSV[55]", 1, 1, 1, 0, 0, 55, bs3CpuBasic2Pf_SetBit, bs3CpuBasic2Pf_IsPteBitSoftwareUsable }, 983 { "!RSV[56]", 1, 1, 1, 0, 0, 56, bs3CpuBasic2Pf_SetBit, bs3CpuBasic2Pf_IsPteBitSoftwareUsable }, 984 { "!RSV[57]", 1, 1, 1, 0, 0, 57, bs3CpuBasic2Pf_SetBit, bs3CpuBasic2Pf_IsPteBitSoftwareUsable }, 985 { "!RSV[58]", 1, 1, 1, 0, 0, 58, bs3CpuBasic2Pf_SetBit, bs3CpuBasic2Pf_IsPteBitSoftwareUsable }, 986 { "!RSV[59]", 1, 1, 1, 0, 0, 59, bs3CpuBasic2Pf_SetBit, bs3CpuBasic2Pf_IsPteBitSoftwareUsable }, 987 { "!RSV[60]", 1, 1, 1, 0, 0, 60, bs3CpuBasic2Pf_SetBit, bs3CpuBasic2Pf_IsPteBitSoftwareUsable }, 988 { "!RSV[61]", 1, 1, 1, 0, 0, 61, bs3CpuBasic2Pf_SetBit, bs3CpuBasic2Pf_IsPteBitSoftwareUsable }, 989 { "!RSV[62]", 1, 1, 1, 0, 0, 62, bs3CpuBasic2Pf_SetBit, bs3CpuBasic2Pf_IsPteBitSoftwareUsable }, 990 991 }; 992 993 731 994 /** 732 995 * Worker for bs3CpuBasic2_RaiseXcpt0e_c32 that does the actual testing. … … 736 999 * @returns Error count. 737 1000 * @param pThis Test state data. 738 */ 739 static uint8_t bs3CpuBasic2_RaiseXcpt0eWorker(PBS3CPUBASIC2PFSTATE register pThis) 1001 * @param fNxe Whether NX is enabled. 1002 */ 1003 static uint8_t bs3CpuBasic2_RaiseXcpt0eWorker(PBS3CPUBASIC2PFSTATE register pThis, bool const fWp, bool const fNxe) 740 1004 { 741 1005 unsigned iRing; 1006 unsigned iStore; 1007 unsigned iAccessor; 1008 // uint32_t const fPfId = fNxe ? X86_TRAP_PF_ID : 0; 1009 uint32_t const fPfIdMask = fNxe ? UINT32_MAX : ~X86_TRAP_PF_ID; 742 1010 BS3REGCTX aCtxts[4]; 1011 1012 pThis->fWp = fWp; 1013 pThis->fNxe = fNxe; 743 1014 744 1015 /** @todo figure out V8086 testing. */ … … 779 1050 */ 780 1051 for (iRing = 0; iRing < 4; iRing++) 781 { 782 /* 1. we can execute the test page. */ 783 bs3CpuBasic2Pf_DoExec(pThis, &aCtxts[iRing], X86_XCPT_UD, UINT8_MAX, true /*fPageLevel*/); 784 /* 2. we can read from the test page. */ 785 bs3CpuBasic2Pf_DoMovLoad(pThis, &aCtxts[iRing], X86_XCPT_UD, UINT8_MAX, true /*fPageLevel*/); 786 /* 3. we can write to the test page. */ 787 bs3CpuBasic2Pf_DoMovStore(pThis, &aCtxts[iRing], X86_XCPT_UD, UINT8_MAX, true /*fPageLevel*/); 788 /* 4. we can do locked read+write (a few variants). */ 789 bs3CpuBasic2Pf_DoXchg(pThis, &aCtxts[iRing], X86_XCPT_UD, UINT8_MAX, true /*fPageLevel*/); 790 bs3CpuBasic2Pf_DoCmpXchg(pThis, &aCtxts[iRing], X86_XCPT_UD, UINT8_MAX, true /*fPageLevel*/, false /*fMissmatch*/); 791 bs3CpuBasic2Pf_DoCmpXchg(pThis, &aCtxts[iRing], X86_XCPT_UD, UINT8_MAX, true /*fPageLevel*/, true /*fMissmatch*/); 792 } 1052 for (iAccessor = 0; iAccessor < RT_ELEMENTS(g_aAccessors); iAccessor++) 1053 g_aAccessors[iAccessor].pfnAccessor(pThis, &aCtxts[iRing], X86_XCPT_UD, UINT8_MAX, true /*fPageLevel*/); 793 1054 794 1055 /* 795 * Check the U bit on PTE level. 1056 * Check the U bit on PTE level. We only mess with the 2nd page. 796 1057 */ 797 1058 { 1059 bool const fPgLvl = true; 1060 bool const fWp = RT_BOOL(ASMGetCR0() & X86_CR0_WP); 1061 unsigned iPteWrk; 1062 1063 bs3CpuBasic2Pf_FlushAll(); 1064 for (iPteWrk = 0; iPteWrk < RT_ELEMENTS(g_aPteWorkers); iPteWrk++) 1065 { 1066 BS3CPUBASIC2PFMODPT EffWrk; 1067 const BS3CPUBASIC2PFMODPT *pPteWrk = &g_aPteWorkers[iPteWrk]; 1068 if ( pPteWrk->pfnApplicable && !pPteWrk->pfnApplicable(pThis, pPteWrk)) 1069 continue; 1070 //if (pThis->bMode == BS3_MODE_LM16) Bs3TestPrintf("PteWrk: %s\n", pPteWrk->pszName); 1071 1072 EffWrk = *pPteWrk; 1073 1074 /* 1075 * Do the modification once, then test all different accesses 1076 * without flushing the TLB or anything in-between. 1077 */ 1078 for (iStore = 0; iStore < RT_ELEMENTS(g_aStoreMethods); iStore++) 1079 { 1080 pPteWrk->pfnModify(pThis, iStore, pPteWrk); 1081 1082 for (iRing = 0; iRing < 4; iRing++) 1083 { 1084 PBS3REGCTX const pCtx = &aCtxts[iRing]; 1085 if ( EffWrk.fReserved 1086 || !EffWrk.fPresent 1087 || (!EffWrk.fUser && iRing == 3)) 1088 { 1089 uint32_t const fPfBase = ( EffWrk.fReserved ? X86_TRAP_PF_P | X86_TRAP_PF_RSVD 1090 : EffWrk.fPresent ? X86_TRAP_PF_P : 0) 1091 | (iRing == 3 ? X86_TRAP_PF_US : 0); 1092 for (iAccessor = 0; iAccessor < RT_ELEMENTS(g_aAccessors); iAccessor++) 1093 g_aAccessors[iAccessor].pfnAccessor(pThis, pCtx, X86_XCPT_PF, 1094 fPfBase | (g_aAccessors[iAccessor].fAccess & fPfIdMask), fPgLvl); 1095 } 1096 else 1097 { 1098 uint32_t const fPfBase = X86_TRAP_PF_P | (iRing == 3 ? X86_TRAP_PF_US : 0); 1099 for (iAccessor = 0; iAccessor < RT_ELEMENTS(g_aAccessors); iAccessor++) 1100 if ( ( (g_aAccessors[iAccessor].fAccess & X86_TRAP_PF_ID) 1101 && EffWrk.fNoExecute) 1102 || ( (g_aAccessors[iAccessor].fAccess & X86_TRAP_PF_RW) 1103 && !EffWrk.fWriteable 1104 && (fWp || iRing == 3)) ) 1105 g_aAccessors[iAccessor].pfnAccessor(pThis, pCtx, X86_XCPT_PF, 1106 fPfBase | (g_aAccessors[iAccessor].fAccess & fPfIdMask), 1107 fPgLvl); 1108 else 1109 g_aAccessors[iAccessor].pfnAccessor(pThis, pCtx, X86_XCPT_UD, UINT8_MAX, fPgLvl); 1110 1111 } 1112 } 1113 1114 /* Reset the paging + full flush. */ 1115 bs3CpuBasic2Pf_RestoreFromBackups(pThis); 1116 } 1117 1118 /* 1119 * Again, but redoing everything for each accessor. 1120 */ 1121 for (iStore = 0; iStore < RT_ELEMENTS(g_aStoreMethods); iStore++) 1122 { 1123 for (iRing = 0; iRing < 4; iRing++) 1124 { 1125 PBS3REGCTX const pCtx = &aCtxts[iRing]; 1126 if ( EffWrk.fReserved 1127 || !EffWrk.fPresent 1128 || (!EffWrk.fUser && iRing == 3)) 1129 { 1130 uint32_t const fPfBase = ( EffWrk.fReserved ? X86_TRAP_PF_P | X86_TRAP_PF_RSVD 1131 : EffWrk.fPresent ? X86_TRAP_PF_P : 0) 1132 | (iRing == 3 ? X86_TRAP_PF_US : 0); 1133 for (iAccessor = 0; iAccessor < RT_ELEMENTS(g_aAccessors); iAccessor++) 1134 { 1135 pPteWrk->pfnModify(pThis, iStore, pPteWrk); 1136 g_aAccessors[iAccessor].pfnAccessor(pThis, pCtx, X86_XCPT_PF, 1137 fPfBase | (g_aAccessors[iAccessor].fAccess & fPfIdMask), fPgLvl); 1138 bs3CpuBasic2Pf_RestoreFromBackups(pThis); 1139 } 1140 } 1141 else 1142 { 1143 uint32_t const fPfBase = X86_TRAP_PF_P | (iRing == 3 ? X86_TRAP_PF_US : 0); 1144 for (iAccessor = 0; iAccessor < RT_ELEMENTS(g_aAccessors); iAccessor++) 1145 { 1146 pPteWrk->pfnModify(pThis, iStore, pPteWrk); 1147 if ( ( (g_aAccessors[iAccessor].fAccess & X86_TRAP_PF_ID) 1148 && EffWrk.fNoExecute) 1149 || ( (g_aAccessors[iAccessor].fAccess & X86_TRAP_PF_RW) 1150 && !EffWrk.fWriteable 1151 && (fWp || iRing == 3)) ) 1152 g_aAccessors[iAccessor].pfnAccessor(pThis, pCtx, X86_XCPT_PF, 1153 fPfBase | (g_aAccessors[iAccessor].fAccess & fPfIdMask), 1154 fPgLvl); 1155 else 1156 g_aAccessors[iAccessor].pfnAccessor(pThis, pCtx, X86_XCPT_UD, UINT8_MAX, fPgLvl); 1157 bs3CpuBasic2Pf_RestoreFromBackups(pThis); 1158 } 1159 } 1160 } 1161 } 1162 1163 /* 1164 * ... 1165 */ 1166 1167 } 1168 } 798 1169 799 1170 return 0; … … 834 1205 { 835 1206 cbTestUnaligned >>= 1; 836 if (cbTestUnaligned <= _ 8K)1207 if (cbTestUnaligned <= _16K) 837 1208 { 838 1209 Bs3TestFailed("Failed to allocate memory to play around with\n"); … … 841 1212 } 842 1213 1214 /* align. */ 843 1215 if ((uintptr_t)pvTestUnaligned & (cbTestUnaligned - 1)) 844 1216 { … … 851 1223 State.cbTest = cbTestUnaligned; 852 1224 } 1225 State.cTestPages = State.cbTest >> X86_PAGE_SHIFT; 853 1226 854 1227 /* … … 862 1235 if (RT_SUCCESS(rc)) 863 1236 { 864 /* 865 * Setup a 16-bit selector for accessing the alias. 866 */ 867 Bs3SelSetup16BitData(&Bs3GdteSpare00, (uintptr_t)State.pbTest); 868 State.uSel16TestData = BS3_SEL_SPARE_00 | 3; 869 870 //Bs3TestPrintf("RaiseXcpt0e_c32: bMode=%#x/%#x cbTest=%#x pbTest=%p pbAlias=%p\n", 871 // bMode, g_bBs3CurrentMode, cbTest, pbTest, pbAlias); 872 873 bRet = bs3CpuBasic2_RaiseXcpt0eWorker(&State); 1237 /* Set values that derives from the test memory size and paging info. */ 1238 if (State.PgInfo.cEntries == 2) 1239 { 1240 State.cTestPdes = (State.cTestPages + X86_PG_ENTRIES - 1) / X86_PG_ENTRIES; 1241 State.cTest1stPtes = RT_MIN(State.cTestPages, X86_PG_ENTRIES); 1242 State.cbPdeBackup = State.cTestPdes * (X86_PAGE_SIZE / X86_PG_ENTRIES); 1243 State.cbPteBackup = State.cTest1stPtes * (X86_PAGE_SIZE / X86_PG_ENTRIES); 1244 } 1245 else 1246 { 1247 State.cTestPdes = (State.cTestPages + X86_PG_PAE_ENTRIES - 1) / X86_PG_PAE_ENTRIES; 1248 State.cTest1stPtes = RT_MIN(State.cTestPages, X86_PG_PAE_ENTRIES); 1249 State.cbPdeBackup = State.cTestPdes * (X86_PAGE_SIZE / X86_PG_PAE_ENTRIES); 1250 State.cbPteBackup = State.cTest1stPtes * (X86_PAGE_SIZE / X86_PG_PAE_ENTRIES); 1251 } 1252 if (State.cTestPdes <= RT_ELEMENTS(State.au64PdeBackup)) 1253 { 1254 uint32_t cr0 = ASMGetCR0(); 1255 1256 /* Back up the structures. */ 1257 Bs3MemCpy(State.au64PteBackup, State.PgInfo.u.Legacy.pPte, State.cbPteBackup); 1258 Bs3MemCpy(State.au64PdeBackup, State.PgInfo.u.Legacy.pPde, State.cbPdeBackup); 1259 if (State.PgInfo.cEntries > 2) 1260 State.u64PdpteBackup = State.PgInfo.u.Pae.pPdpe->u; 1261 if (State.PgInfo.cEntries > 3) 1262 State.u64Pml4eBackup = State.PgInfo.u.Pae.pPml4e->u; 1263 1264 /* 1265 * Setup a 16-bit selector for accessing the alias. 1266 */ 1267 Bs3SelSetup16BitData(&Bs3GdteSpare00, (uintptr_t)State.pbTest); 1268 State.uSel16TestData = BS3_SEL_SPARE_00 | 3; 1269 1270 /* 1271 * Do the testing. 1272 */ 1273 ASMSetCR0(ASMGetCR0() & ~X86_CR0_WP); 1274 bRet = bs3CpuBasic2_RaiseXcpt0eWorker(&State, false /*fWp*/, false /*fNxe*/); 1275 if (bRet == 0 && (g_uBs3CpuDetected & BS3CPU_TYPE_MASK) >= BS3CPU_80486) 1276 { 1277 ASMSetCR0(ASMGetCR0() | X86_CR0_WP); 1278 bRet = bs3CpuBasic2_RaiseXcpt0eWorker(&State, true /*fWp*/, false /*fNxe*/); 1279 } 1280 1281 /* Do again with NX enabled. */ 1282 if (bRet == 0 && (g_uBs3CpuDetected & BS3CPU_F_NX)) 1283 { 1284 ASMWrMsr(MSR_K6_EFER, ASMRdMsr(MSR_K6_EFER) | MSR_K6_EFER_NXE); 1285 ASMSetCR0(ASMGetCR0() & ~X86_CR0_WP); 1286 bRet = bs3CpuBasic2_RaiseXcpt0eWorker(&State, false /*fWp*/, State.PgInfo.cbEntry == 8 /*fNxe*/); 1287 ASMSetCR0(ASMGetCR0() | X86_CR0_WP); 1288 bRet = bs3CpuBasic2_RaiseXcpt0eWorker(&State, true /*fWp*/, State.PgInfo.cbEntry == 8 /*fNxe*/); 1289 ASMWrMsr(MSR_K6_EFER, ASMRdMsr(MSR_K6_EFER) & ~MSR_K6_EFER_NXE); 1290 } 1291 bs3CpuBasic2Pf_RestoreFromBackups(&State); 1292 ASMSetCR0((ASMGetCR0() & ~X86_CR0_WP) | (cr0 & X86_CR0_WP)); 1293 } 1294 else 1295 Bs3TestFailedF("cTestPdes=%u!\n", State.cTestPdes); 874 1296 } 875 1297 else -
trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-CpuDetect.asm
r60674 r65366 294 294 test edx, X86_CPUID_EXT_FEATURE_EDX_LONG_MODE 295 295 jz .no_long_mode 296 or a x, BS3CPU_F_CPUID_EXT_LEAVES | BS3CPU_F_LONG_MODE297 jmp . return296 or ah, ((BS3CPU_F_CPUID_EXT_LEAVES | BS3CPU_F_LONG_MODE) >> 8) 297 jmp .no_check_for_nx 298 298 .no_long_mode: 299 or ax, BS3CPU_F_CPUID_EXT_LEAVES 300 jmp .return 299 or ah, (BS3CPU_F_CPUID_EXT_LEAVES >> 8) 300 .no_check_for_nx: 301 test edx, X86_CPUID_EXT_FEATURE_EDX_NX 302 jz .return 303 or ax, BS3CPU_F_NX 304 jmp .return 305 301 306 .no_ext_leaves: 302 307 pop xAX ; restore PAE+PProOrNewer -
trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit.h
r64751 r65366 3381 3381 /** Flag indicating that the CPU supports long mode. */ 3382 3382 #define BS3CPU_F_LONG_MODE UINT16_C(0x1000) 3383 /** Flag indicating that the CPU supports NX. */ 3384 #define BS3CPU_F_NX UINT16_C(0x2000) 3383 3385 /** @} */ 3384 3386 -
trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit.mac
r64694 r65366 1703 1703 %define BS3CPU_F_PSE_BIT 11 1704 1704 %define BS3CPU_F_LONG_MODE 0x1000 1705 %define BS3CPU_F_LONG_MODE_BIT 12 1706 %define BS3CPU_F_NX 0x2000 1707 %define BS3CPU_F_NX_BIT 13 1705 1708 ;; @} 1706 1709
注意:
瀏覽 TracChangeset
來幫助您使用更動檢視器