Changeset 65396 in vbox for trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-basic-2-pf.c32
- Timestamp:
- Jan 20, 2017 8:07:35 PM (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-basic-2-pf.c32
r65366 r65396 43 43 } while (0) 44 44 45 #define BS3CPUBASIC2PF_HALT(pThis) \ 46 do { \ 47 Bs3TestPrintf("Halting: pteworker=%s store=%s accessor=%s\n", \ 48 pThis->pszPteWorker, pThis->pszStore, pThis->pszAccessor); \ 49 ASMHalt(); \ 50 } while (0) 51 52 53 /** @def BS3CPUBASIC2PF_FASTER 54 * This is useful for IEM execution. */ 55 #define BS3CPUBASIC2PF_FASTER 56 45 57 46 58 /********************************************************************************************************************************* … … 53 65 FNBS3CPUBASIC2PFSNIPPET *pfn; 54 66 uint8_t offUd2; 55 uint8_t cbTmpl; 67 56 68 } FNBS3CPUBASIC2PFTSTCODE; 57 69 typedef FNBS3CPUBASIC2PFTSTCODE const *PCFNBS3CPUBASIC2PFTSTCODE; … … 59 71 typedef struct BS3CPUBASIC2PFTTSTCMNMODE 60 72 { 61 uint8_t bMode; 62 FNBS3CPUBASIC2PFTSTCODE MovLoad; 63 FNBS3CPUBASIC2PFTSTCODE MovStore; 64 FNBS3CPUBASIC2PFTSTCODE Xchg; 65 FNBS3CPUBASIC2PFTSTCODE CmpXchg; 73 uint8_t bMode; 74 FNBS3CPUBASIC2PFTSTCODE MovLoad; 75 FNBS3CPUBASIC2PFTSTCODE MovStore; 76 FNBS3CPUBASIC2PFTSTCODE Xchg; 77 FNBS3CPUBASIC2PFTSTCODE CmpXchg; 78 FNBS3CPUBASIC2PFTSTCODE DivMem; 66 79 } BS3CPUBASIC2PFTTSTCMNMODE; 67 80 typedef BS3CPUBASIC2PFTTSTCMNMODE const *PCBS3CPUBASIC2PFTTSTCMNMODE; … … 108 121 bool fNxe; 109 122 123 const char *pszAccessor; 124 const char *pszPteWorker; 125 const char *pszStore; 126 110 127 /** Trap context frame. */ 111 128 BS3TRAPFRAME TrapCtx; … … 139 156 uint32_t fReserved : 1; 140 157 uint32_t uModifyArg : 24; 141 void (*pfnModify)(PBS3CPUBASIC2PFSTATE pThis, unsigned iStore, struct BS3CPUBASIC2PFMODPT const *pEntry); 158 void (*pfnModify)(PBS3CPUBASIC2PFSTATE pThis, unsigned iStore, struct BS3CPUBASIC2PFMODPT const *pEntry, 159 uint32_t fClearMask, uint32_t fSetMask); 142 160 bool (*pfnApplicable)(PBS3CPUBASIC2PFSTATE pThis, struct BS3CPUBASIC2PFMODPT const *pEntry); 143 161 } BS3CPUBASIC2PFMODPT; 144 162 typedef BS3CPUBASIC2PFMODPT const *PCBS3CPUBASIC2PFMODPT; 145 163 164 /** Page level protection. Alternative is page directory or higher level. */ 165 #define BS3CB2PFACC_F_PAGE_LEVEL RT_BIT(0) 166 /** Directly access the boobytrapped page, no edging on or off it. */ 167 #define BS3CB2PFACC_F_DIRECT RT_BIT(1) 146 168 147 169 /** … … 153 175 const char *pszName; 154 176 /** The accessor. */ 155 void (*pfnAccessor)(PBS3CPUBASIC2PFSTATE pThis, PBS3REGCTX pCtx, uint 8_t bXcpt, uint8_t uPfErrCd, bool fPageLevel);177 void (*pfnAccessor)(PBS3CPUBASIC2PFSTATE pThis, PBS3REGCTX pCtx, uint32_t fFlags, uint8_t bXcpt, uint8_t uPfErrCd); 156 178 /** The X86_TRAP_PF_XXX access flags this access sets. */ 157 179 uint32_t fAccess; 158 180 /** The exception when things are fine. */ 181 uint8_t bOkayXcpt; 159 182 } BS3CPUBASIC2PFACCESSOR; 160 183 typedef const BS3CPUBASIC2PFACCESSOR *PCBS3CPUBASIC2PFACCESSOR; … … 177 200 FNBS3CPUBASIC2PFSNIPPET bs3CpuBasic2_xchg_ds_bx_ax__ud2_c16; 178 201 FNBS3CPUBASIC2PFSNIPPET bs3CpuBasic2_cmpxchg_ds_bx_cx__ud2_c16; 202 FNBS3CPUBASIC2PFSNIPPET bs3CpuBasic2_div_ds_bx__ud2_c16; 179 203 180 204 FNBS3CPUBASIC2PFSNIPPET bs3CpuBasic2_mov_ax_ds_bx__ud2_c32; … … 182 206 FNBS3CPUBASIC2PFSNIPPET bs3CpuBasic2_xchg_ds_bx_ax__ud2_c32; 183 207 FNBS3CPUBASIC2PFSNIPPET bs3CpuBasic2_cmpxchg_ds_bx_cx__ud2_c32; 208 FNBS3CPUBASIC2PFSNIPPET bs3CpuBasic2_div_ds_bx__ud2_c32; 184 209 185 210 FNBS3CPUBASIC2PFSNIPPET bs3CpuBasic2_mov_ax_ds_bx__ud2_c64; … … 187 212 FNBS3CPUBASIC2PFSNIPPET bs3CpuBasic2_xchg_ds_bx_ax__ud2_c64; 188 213 FNBS3CPUBASIC2PFSNIPPET bs3CpuBasic2_cmpxchg_ds_bx_cx__ud2_c64; 214 FNBS3CPUBASIC2PFSNIPPET bs3CpuBasic2_div_ds_bx__ud2_c64; 189 215 190 216 … … 195 221 static const struct 196 222 { 197 const char *psz Store;223 const char *pszName; 198 224 void (BS3_CALL *pfnStore)(void *pvDst, uint32_t uValue, uint32_t uOld); 199 225 } g_aStoreMethods[] = … … 213 239 { bs3CpuBasic2_xchg_ds_bx_ax__ud2_c16, 2 }, 214 240 { bs3CpuBasic2_cmpxchg_ds_bx_cx__ud2_c16, 3 }, 241 { bs3CpuBasic2_div_ds_bx__ud2_c16, 2 }, 215 242 }, 216 243 { … … 220 247 { bs3CpuBasic2_xchg_ds_bx_ax__ud2_c32, 2 }, 221 248 { bs3CpuBasic2_cmpxchg_ds_bx_cx__ud2_c32, 3 }, 249 { bs3CpuBasic2_div_ds_bx__ud2_c32, 2 }, 222 250 }, 223 251 { … … 227 255 { bs3CpuBasic2_xchg_ds_bx_ax__ud2_c64, 2 + 1 }, 228 256 { bs3CpuBasic2_cmpxchg_ds_bx_cx__ud2_c64, 3 + 1 }, 257 { bs3CpuBasic2_div_ds_bx__ud2_c64, 2 + 1 }, 229 258 }, 230 259 { … … 234 263 { bs3CpuBasic2_xchg_ds_bx_ax__ud2_c16, 2 }, 235 264 { bs3CpuBasic2_cmpxchg_ds_bx_cx__ud2_c16, 3 }, 265 { bs3CpuBasic2_div_ds_bx__ud2_c16, 2 }, 236 266 }, 237 267 }; … … 263 293 Bs3TestPrintf("Halting: g_uBs3CpuDetected=%#x\n", g_uBs3CpuDetected); 264 294 Bs3TestPrintf("Halting: bXcpt=%#x uErrCd=%#x\n", bXcpt, uErrCd); 265 ASMHalt();295 BS3CPUBASIC2PF_HALT(pThis); 266 296 #endif 267 297 } … … 297 327 Bs3TestPrintf("Halting: g_uBs3CpuDetected=%#x\n", g_uBs3CpuDetected); 298 328 Bs3TestPrintf("Halting: bXcpt=%#x uErrCd=%#x\n", bXcpt, uErrCd); 299 ASMHalt();329 BS3CPUBASIC2PF_HALT(pThis); 300 330 #endif 301 331 } … … 361 391 * @{ */ 362 392 363 static void bs3CpuBasic2Pf_DoExec(PBS3CPUBASIC2PFSTATE pThis, PBS3REGCTX pCtx, uint 8_t bXcpt, uint8_t uPfErrCd, bool fPageLevel)393 static void bs3CpuBasic2Pf_DoExec(PBS3CPUBASIC2PFSTATE pThis, PBS3REGCTX pCtx, uint32_t fFlags, uint8_t bXcpt, uint8_t uPfErrCd) 364 394 { 365 395 uint8_t *pbOrgTest = pThis->pbOrgTest; … … 395 425 //Bs3TestPrintf("off=%#06x bXcpt=%#x uErrCd=%#RX64\n", off, pThis->TrapCtx.bXcpt, pThis->TrapCtx.uErrCd); 396 426 if ( bXcpt != X86_XCPT_PF 397 || ( fPageLevel&& off < X86_PAGE_SIZE - 4))427 || ((fFlags & BS3CB2PFACC_F_PAGE_LEVEL) && off < X86_PAGE_SIZE - 4)) 398 428 bs3CpuBasic2Pf_CompareSimpleUd(pThis, pCtx, 3); 399 else if (! fPageLevel|| off >= X86_PAGE_SIZE)429 else if (!(fFlags & BS3CB2PFACC_F_PAGE_LEVEL) || off >= X86_PAGE_SIZE) 400 430 bs3CpuBasic2Pf_CompareSimplePf(pThis, pCtx, 0, uPfErrCd, (uintptr_t)pThis->pbTest + off); 401 431 else … … 441 471 * @param pThis The test stat data. 442 472 * @param pCtx The test context. 473 * @param fFlags BS3CB2PFACC_F_XXX. 443 474 * @param bXcpt X86_XCPT_PF if this can cause \#PFs, otherwise 444 475 * X86_XCPT_UD. 445 476 * @param uPfErrCd The error code for \#PFs. 446 * @param fPageLevel Set if we're pushing PTE level bits.447 477 */ 448 static void bs3CpuBasic2Pf_DoMovLoad(PBS3CPUBASIC2PFSTATE pThis, PBS3REGCTX pCtx, uint8_t bXcpt, uint8_t uPfErrCd, 449 bool fPageLevel) 478 static void bs3CpuBasic2Pf_DoMovLoad(PBS3CPUBASIC2PFSTATE pThis, PBS3REGCTX pCtx, uint32_t fFlags, uint8_t bXcpt, uint8_t uPfErrCd) 450 479 { 451 480 static uint64_t const s_uValue = UINT64_C(0x7c4d0114428d); … … 496 525 497 526 if ( bXcpt != X86_XCPT_PF 498 || ( fPageLevel&& off >= X86_PAGE_SIZE * 2)499 || ( fPageLevel&& off <= X86_PAGE_SIZE - pThis->cbAccess) )527 || ((fFlags & BS3CB2PFACC_F_PAGE_LEVEL) && off >= X86_PAGE_SIZE * 2) 528 || ((fFlags & BS3CB2PFACC_F_PAGE_LEVEL) && off <= X86_PAGE_SIZE - pThis->cbAccess) ) 500 529 { 501 530 pThis->ExpectCtx.rax.u = uExpectRax; … … 522 551 * @param pThis The test stat data. 523 552 * @param pCtx The test context. 553 * @param fFlags BS3CB2PFACC_F_XXX. 524 554 * @param bXcpt X86_XCPT_PF if this can cause \#PFs, otherwise 525 555 * X86_XCPT_UD. 526 556 * @param uPfErrCd The error code for \#PFs. 527 * @param fPageLevel Set if we're pushing PTE level bits.528 557 */ 529 static void bs3CpuBasic2Pf_DoMovStore(PBS3CPUBASIC2PFSTATE pThis, PBS3REGCTX pCtx, uint 8_t bXcpt, uint8_t uPfErrCd,530 bool fPageLevel)558 static void bs3CpuBasic2Pf_DoMovStore(PBS3CPUBASIC2PFSTATE pThis, PBS3REGCTX pCtx, uint32_t fFlags, 559 uint8_t bXcpt, uint8_t uPfErrCd) 531 560 { 532 561 static uint64_t const s_uValue = UINT64_C(0x3af45ead86a34a26); … … 581 610 582 611 if ( bXcpt != X86_XCPT_PF 583 || ( fPageLevel&& off >= X86_PAGE_SIZE * 2)584 || ( fPageLevel&& off <= X86_PAGE_SIZE - pThis->cbAccess) )612 || ((fFlags & BS3CB2PFACC_F_PAGE_LEVEL) && off >= X86_PAGE_SIZE * 2) 613 || ((fFlags & BS3CB2PFACC_F_PAGE_LEVEL) && off <= X86_PAGE_SIZE - pThis->cbAccess) ) 585 614 { 586 615 bs3CpuBasic2Pf_CompareCtx(pThis, &pThis->ExpectCtx, pThis->pCmnMode->MovStore.offUd2, X86_XCPT_UD, 0 /*uErrCd*/); … … 614 643 * @param pThis The test stat data. 615 644 * @param pCtx The test context. 645 * @param fFlags BS3CB2PFACC_F_XXX. 616 646 * @param bXcpt X86_XCPT_PF if this can cause \#PFs, otherwise 617 647 * X86_XCPT_UD. 618 648 * @param uPfErrCd The error code for \#PFs. 619 * @param fPageLevel Set if we're pushing PTE level bits.620 649 */ 621 static void bs3CpuBasic2Pf_DoXchg(PBS3CPUBASIC2PFSTATE pThis, PBS3REGCTX pCtx, uint 8_t bXcpt, uint8_t uPfErrCd, bool fPageLevel)650 static void bs3CpuBasic2Pf_DoXchg(PBS3CPUBASIC2PFSTATE pThis, PBS3REGCTX pCtx, uint32_t fFlags, uint8_t bXcpt, uint8_t uPfErrCd) 622 651 { 623 652 static uint64_t const s_uValue = UINT64_C(0xea58699648e2f32c); … … 678 707 679 708 if ( bXcpt != X86_XCPT_PF 680 || ( fPageLevel&& off >= X86_PAGE_SIZE * 2)681 || ( fPageLevel&& off <= X86_PAGE_SIZE - pThis->cbAccess) )709 || ((fFlags & BS3CB2PFACC_F_PAGE_LEVEL) && off >= X86_PAGE_SIZE * 2) 710 || ((fFlags & BS3CB2PFACC_F_PAGE_LEVEL) && off <= X86_PAGE_SIZE - pThis->cbAccess) ) 682 711 { 683 712 pThis->ExpectCtx.rax.u = uExpectedRax; … … 712 741 * @param pThis The test stat data. 713 742 * @param pCtx The test context. 743 * @param fFlags BS3CB2PFACC_F_XXX. 714 744 * @param bXcpt X86_XCPT_PF if this can cause \#PFs, otherwise 715 745 * X86_XCPT_UD. 716 746 * @param uPfErrCd The error code for \#PFs. 717 * @param fPageLevel Set if we're pushing PTE level bits.718 747 * @param fMissmatch Whether to fail and not store (@c true), or succeed 719 748 * and do the store. 720 749 */ 721 static void bs3CpuBasic2Pf_DoCmpXchg(PBS3CPUBASIC2PFSTATE pThis, PBS3REGCTX pCtx, uint 8_t bXcpt, uint8_t uPfErrCd,722 bool fPageLevel, bool fMissmatch)750 static void bs3CpuBasic2Pf_DoCmpXchg(PBS3CPUBASIC2PFSTATE pThis, PBS3REGCTX pCtx, uint32_t fFlags, 751 uint8_t bXcpt, uint8_t uPfErrCd, bool fMissmatch) 723 752 { 724 753 static uint64_t const s_uValue = UINT64_C(0xea58699648e2f32c); … … 799 828 800 829 if ( bXcpt != X86_XCPT_PF 801 || ( fPageLevel&& off >= X86_PAGE_SIZE * 2)802 || ( fPageLevel&& off <= X86_PAGE_SIZE - pThis->cbAccess) )830 || ((fFlags & BS3CB2PFACC_F_PAGE_LEVEL) && off >= X86_PAGE_SIZE * 2) 831 || ((fFlags & BS3CB2PFACC_F_PAGE_LEVEL) && off <= X86_PAGE_SIZE - pThis->cbAccess) ) 803 832 { 804 833 pThis->ExpectCtx.rax.u = uExpectedRax; … … 831 860 832 861 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*/ ); 862 static void bs3CpuBasic2Pf_DoCmpXchgMiss(PBS3CPUBASIC2PFSTATE pThis, PBS3REGCTX pCtx, uint32_t fFlags, 863 uint8_t bXcpt, uint8_t uPfErrCd) 864 { 865 bs3CpuBasic2Pf_DoCmpXchg(pThis, pCtx, fFlags, bXcpt, uPfErrCd, true /*fMissmatch*/ ); 866 } 867 868 869 static void bs3CpuBasic2Pf_DoCmpXchgMatch(PBS3CPUBASIC2PFSTATE pThis, PBS3REGCTX pCtx, uint32_t fFlags, 870 uint8_t bXcpt, uint8_t uPfErrCd) 871 { 872 bs3CpuBasic2Pf_DoCmpXchg(pThis, pCtx, fFlags, bXcpt, uPfErrCd , false /*fMissmatch*/ ); 873 } 874 875 876 /** 877 * @interface_method_impl{BS3CPUBASIC2PFACCESSOR,pfnAccessor, 878 * DIV [MEM=0] for checking the accessed bit} 879 */ 880 static void bs3CpuBasic2Pf_DoDivByZero(PBS3CPUBASIC2PFSTATE pThis, PBS3REGCTX pCtx, uint32_t fFlags, 881 uint8_t bXcpt, uint8_t uPfErrCd) 882 { 883 static uint64_t const s_uFiller = UINT64_C(0x9856703711f4069e); 884 uint64_t uZeroAndFill; 885 unsigned i; 886 887 /* 888 * Adjust the incoming context and calculate our expections. 889 */ 890 bs3CpuBasic2Pf_SetCsEip(pThis, pCtx, &pThis->pCmnMode->DivMem); 891 892 Bs3MemCpy(&pThis->ExpectCtx, pCtx, sizeof(pThis->ExpectCtx)); 893 switch (pThis->bMode & BS3_MODE_CODE_MASK) 894 { 895 case BS3_MODE_CODE_16: 896 case BS3_MODE_CODE_V86: 897 uZeroAndFill = s_uFiller & UINT64_C(0xffffffffffff0000); 898 break; 899 case BS3_MODE_CODE_32: 900 uZeroAndFill = s_uFiller & UINT64_C(0xffffffff00000000); 901 break; 902 case BS3_MODE_CODE_64: 903 uZeroAndFill = 0; 904 break; 905 } 906 907 /* 908 * Make two approaches to the test page (the 2nd one): 909 * - i=0: Start on the 1st page and edge into the 2nd. 910 * - i=1: Start at the end of the 2nd page and edge off it and into the 3rd. 911 */ 912 for (i = 0; i < 2; i++) 913 { 914 unsigned off = X86_PAGE_SIZE * (i + 1) - pThis->cbAccess; 915 unsigned offEnd = X86_PAGE_SIZE * (i + 1) + (i == 0 ? 8 : 7); 916 for (; off < offEnd; off++) 917 { 918 *(uint64_t *)&pThis->pbOrgTest[off] = uZeroAndFill; 919 if (BS3_MODE_IS_16BIT_CODE(pThis->bMode)) 920 pThis->ExpectCtx.rbx.u = pCtx->rbx.u = off; 921 else 922 pThis->ExpectCtx.rbx.u = pCtx->rbx.u = (uintptr_t)pThis->pbTest + off; 923 924 Bs3TrapSetJmpAndRestore(pCtx, &pThis->TrapCtx); 925 //if (pThis->bMode == BS3_MODE_PP16_32) Bs3TestPrintf("off=%#06x bXcpt=%#x uErrCd=%#RX64\n", off, pThis->TrapCtx.bXcpt, pThis->TrapCtx.uErrCd); 926 927 if ( bXcpt != X86_XCPT_PF 928 || ((fFlags & BS3CB2PFACC_F_PAGE_LEVEL) && off >= X86_PAGE_SIZE * 2) 929 || ((fFlags & BS3CB2PFACC_F_PAGE_LEVEL) && off <= X86_PAGE_SIZE - pThis->cbAccess) ) 930 { 931 bs3CpuBasic2Pf_CompareCtx(pThis, &pThis->ExpectCtx, 0 /*cbPcAdjust*/, X86_XCPT_DE, 0 /*uErrCd*/); 932 if (*(uint64_t *)&pThis->pbOrgTest[off] != uZeroAndFill) 933 Bs3TestFailedF("%u - %s: Modified source op: %#RX64, expected %#RX64", 934 g_usBs3TestStep, "xxxx", *(uint64_t *)&pThis->pbOrgTest[off], uZeroAndFill); 935 } 936 else 937 { 938 if (off < X86_PAGE_SIZE) 939 pThis->ExpectCtx.cr2.u = (uintptr_t)pThis->pbTest + X86_PAGE_SIZE; 940 else 941 pThis->ExpectCtx.cr2.u = (uintptr_t)pThis->pbTest + off; 942 bs3CpuBasic2Pf_CompareCtx(pThis, &pThis->ExpectCtx, 0 /*cbPcAdjust*/, bXcpt, uPfErrCd); 943 pThis->ExpectCtx.cr2 = pCtx->cr2; 944 if (*(uint64_t *)&pThis->pbOrgTest[off] != uZeroAndFill) 945 Bs3TestFailedF("%u - %s: Modified source op: %#RX64, expected %#RX64", 946 g_usBs3TestStep, "xxxx", *(uint64_t *)&pThis->pbOrgTest[off], uZeroAndFill); 947 } 948 } 949 } 844 950 } 845 951 … … 847 953 static BS3CPUBASIC2PFACCESSOR const g_aAccessors[] = 848 954 { 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 }, 955 { "DoExec", bs3CpuBasic2Pf_DoExec, X86_TRAP_PF_ID, X86_XCPT_UD }, 956 { "DoMovLoad", bs3CpuBasic2Pf_DoMovLoad, 0, X86_XCPT_UD }, 957 { "DoMovStore", bs3CpuBasic2Pf_DoMovStore, X86_TRAP_PF_RW, X86_XCPT_UD }, 958 { "DoXchg", bs3CpuBasic2Pf_DoXchg, X86_TRAP_PF_RW, X86_XCPT_UD }, 959 { "DoCmpXchgMiss", bs3CpuBasic2Pf_DoCmpXchgMiss, X86_TRAP_PF_RW, X86_XCPT_UD }, 960 { "DoCmpXhcgMatch", bs3CpuBasic2Pf_DoCmpXchgMatch, X86_TRAP_PF_RW, X86_XCPT_UD }, 961 { "DoDivByZero", bs3CpuBasic2Pf_DoDivByZero, 0, X86_XCPT_DE }, 855 962 }; 856 963 … … 862 969 863 970 864 static void bs3CpuBasic2Pf_ClearMask(PBS3CPUBASIC2PFSTATE pThis, unsigned iStore, PCBS3CPUBASIC2PFMODPT pEntry) 971 static void bs3CpuBasic2Pf_ClearMask(PBS3CPUBASIC2PFSTATE pThis, unsigned iStore, PCBS3CPUBASIC2PFMODPT pEntry, 972 uint32_t fClearMask, uint32_t fSetMask) 865 973 { 866 974 if (pThis->PgInfo.cbEntry == 4) 867 975 g_aStoreMethods[iStore].pfnStore(pThis->PgInfo.u.Legacy.pPte + 1, 868 pThis->PgInfo.u.Legacy.pPte[1].u& ~(uint32_t)pEntry->uModifyArg,976 ((pThis->PgInfo.u.Legacy.pPte[1].u & ~fClearMask) | fSetMask) & ~(uint32_t)pEntry->uModifyArg, 869 977 pThis->PgInfo.u.Legacy.pPte[1].u); 870 978 else 871 979 g_aStoreMethods[iStore].pfnStore(pThis->PgInfo.u.Pae.pPte + 1, 872 pThis->PgInfo.u.Pae.pPte[1].au32[0]& ~(uint32_t)pEntry->uModifyArg,980 ((pThis->PgInfo.u.Pae.pPte[1].au32[0] & ~fClearMask) | fSetMask) & ~(uint32_t)pEntry->uModifyArg, 873 981 pThis->PgInfo.u.Pae.pPte[1].au32[0]); 874 982 } 875 983 876 static void bs3CpuBasic2Pf_SetBit(PBS3CPUBASIC2PFSTATE pThis, unsigned iStore, PCBS3CPUBASIC2PFMODPT pEntry) 984 static void bs3CpuBasic2Pf_SetBit(PBS3CPUBASIC2PFSTATE pThis, unsigned iStore, PCBS3CPUBASIC2PFMODPT pEntry, 985 uint32_t fClearMask, uint32_t fSetMask) 877 986 { 878 987 if (pThis->PgInfo.cbEntry == 4) 879 988 g_aStoreMethods[iStore].pfnStore(pThis->PgInfo.u.Legacy.pPte + 1, 880 pThis->PgInfo.u.Legacy.pPte[1].u| RT_BIT_32(pEntry->uModifyArg),989 (pThis->PgInfo.u.Legacy.pPte[1].u & ~fClearMask) | fSetMask | RT_BIT_32(pEntry->uModifyArg), 881 990 pThis->PgInfo.u.Legacy.pPte[1].u); 882 991 else if (pEntry->uModifyArg < 32) 883 992 g_aStoreMethods[iStore].pfnStore(pThis->PgInfo.u.Pae.pPte + 1, 884 pThis->PgInfo.u.Pae.pPte[1].au32[0]| RT_BIT_32(pEntry->uModifyArg),993 (pThis->PgInfo.u.Pae.pPte[1].au32[0] & ~fClearMask) | fSetMask | RT_BIT_32(pEntry->uModifyArg), 885 994 pThis->PgInfo.u.Pae.pPte[1].au32[0]); 886 995 else 996 { 887 997 g_aStoreMethods[iStore].pfnStore(&pThis->PgInfo.u.Pae.pPte[1].au32[1], 888 998 pThis->PgInfo.u.Pae.pPte[1].au32[1] | RT_BIT_32(pEntry->uModifyArg - 32), 889 999 pThis->PgInfo.u.Pae.pPte[1].au32[1]); 890 } 891 892 static void bs3CpuBasic2Pf_ClearBit(PBS3CPUBASIC2PFSTATE pThis, unsigned iStore, PCBS3CPUBASIC2PFMODPT pEntry) 1000 if (fSetMask || fClearMask) 1001 g_aStoreMethods[iStore].pfnStore(pThis->PgInfo.u.Pae.pPte + 1, 1002 (pThis->PgInfo.u.Pae.pPte[1].au32[0] & ~fClearMask) | fSetMask, 1003 pThis->PgInfo.u.Pae.pPte[1].au32[0]); 1004 } 1005 } 1006 1007 #if 0 1008 static void bs3CpuBasic2Pf_ClearBit(PBS3CPUBASIC2PFSTATE pThis, unsigned iStore, PCBS3CPUBASIC2PFMODPT pEntry, 1009 uint32_t fClearMask, uint32_t fSetMask) 893 1010 { 894 1011 if (pThis->PgInfo.cbEntry == 4) 895 1012 g_aStoreMethods[iStore].pfnStore(pThis->PgInfo.u.Legacy.pPte + 1, 896 pThis->PgInfo.u.Legacy.pPte[1].u& ~RT_BIT_32(pEntry->uModifyArg),1013 ((pThis->PgInfo.u.Legacy.pPte[1].u & ~fClearMask) | fSetMask) & ~RT_BIT_32(pEntry->uModifyArg), 897 1014 pThis->PgInfo.u.Legacy.pPte[1].u); 898 1015 else if (pEntry->uModifyArg < 32) 899 1016 g_aStoreMethods[iStore].pfnStore(pThis->PgInfo.u.Pae.pPte + 1, 900 pThis->PgInfo.u.Pae.pPte[1].au32[0]& ~RT_BIT_32(pEntry->uModifyArg),1017 ((pThis->PgInfo.u.Pae.pPte[1].au32[0] & ~fClearMask) | fSetMask) & ~RT_BIT_32(pEntry->uModifyArg), 901 1018 pThis->PgInfo.u.Pae.pPte[1].au32[0]); 902 1019 else … … 905 1022 pThis->PgInfo.u.Pae.pPte[1].au32[1]); 906 1023 } 907 908 909 static void bs3CpuBasic2Pf_NoChange(PBS3CPUBASIC2PFSTATE pThis, unsigned iStore, PCBS3CPUBASIC2PFMODPT pEntry) 910 { 911 RT_NOREF3(pThis, iStore, pEntry); 1024 #endif 1025 1026 static void bs3CpuBasic2Pf_NoChange(PBS3CPUBASIC2PFSTATE pThis, unsigned iStore, PCBS3CPUBASIC2PFMODPT pEntry, 1027 uint32_t fClearMask, uint32_t fSetMask) 1028 { 1029 if (fClearMask || fSetMask) 1030 { 1031 if (pThis->PgInfo.cbEntry == 4) 1032 g_aStoreMethods[iStore].pfnStore(pThis->PgInfo.u.Legacy.pPte + 1, 1033 (pThis->PgInfo.u.Legacy.pPte[1].u & ~fClearMask) | fSetMask, 1034 pThis->PgInfo.u.Legacy.pPte[1].u); 1035 else 1036 g_aStoreMethods[iStore].pfnStore(pThis->PgInfo.u.Pae.pPte + 1, 1037 (pThis->PgInfo.u.Pae.pPte[1].au32[0] & ~fClearMask) | fSetMask, 1038 pThis->PgInfo.u.Pae.pPte[1].au32[0]); 1039 } 912 1040 } 913 1041 … … 1051 1179 for (iRing = 0; iRing < 4; iRing++) 1052 1180 for (iAccessor = 0; iAccessor < RT_ELEMENTS(g_aAccessors); iAccessor++) 1053 g_aAccessors[iAccessor].pfnAccessor(pThis, &aCtxts[iRing], X86_XCPT_UD, UINT8_MAX, true /*fPageLevel*/);1181 g_aAccessors[iAccessor].pfnAccessor(pThis, &aCtxts[iRing], BS3CB2PFACC_F_PAGE_LEVEL, X86_XCPT_UD, UINT8_MAX); 1054 1182 1055 1183 /* … … 1057 1185 */ 1058 1186 { 1059 bool const fPgLvl = true;1060 bool const fWp= RT_BOOL(ASMGetCR0() & X86_CR0_WP);1061 unsigned iPteWrk;1187 uint32_t const fAccessor = BS3CB2PFACC_F_PAGE_LEVEL; 1188 bool const fWp = RT_BOOL(ASMGetCR0() & X86_CR0_WP); 1189 unsigned iPteWrk; 1062 1190 1063 1191 bs3CpuBasic2Pf_FlushAll(); … … 1068 1196 if ( pPteWrk->pfnApplicable && !pPteWrk->pfnApplicable(pThis, pPteWrk)) 1069 1197 continue; 1070 //if (pThis->bMode == BS3_MODE_LM16) Bs3TestPrintf("PteWrk: %s\n", pPteWrk->pszName); 1198 1199 pThis->pszPteWorker = pPteWrk->pszName; 1071 1200 1072 1201 EffWrk = *pPteWrk; 1073 1202 1203 #if 1 1074 1204 /* 1075 1205 * Do the modification once, then test all different accesses … … 1078 1208 for (iStore = 0; iStore < RT_ELEMENTS(g_aStoreMethods); iStore++) 1079 1209 { 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 { 1210 pThis->pszStore = g_aStoreMethods[iStore].pszName; 1211 pPteWrk->pfnModify(pThis, iStore, pPteWrk, 0, 0); 1212 1123 1213 for (iRing = 0; iRing < 4; iRing++) 1124 1214 { … … 1133 1223 for (iAccessor = 0; iAccessor < RT_ELEMENTS(g_aAccessors); iAccessor++) 1134 1224 { 1135 pPteWrk->pfnModify(pThis, iStore, pPteWrk); 1136 g_aAccessors[iAccessor].pfnAccessor(pThis, pCtx, X86_XCPT_PF, 1137 fPfBase | (g_aAccessors[iAccessor].fAccess & fPfIdMask), fPgLvl); 1225 pThis->pszAccessor = g_aAccessors[iAccessor].pszName; 1226 g_aAccessors[iAccessor].pfnAccessor(pThis, pCtx, fAccessor, X86_XCPT_PF, 1227 fPfBase | (g_aAccessors[iAccessor].fAccess & fPfIdMask)); 1228 } 1229 } 1230 else 1231 { 1232 uint32_t const fPfBase = X86_TRAP_PF_P | (iRing == 3 ? X86_TRAP_PF_US : 0); 1233 for (iAccessor = 0; iAccessor < RT_ELEMENTS(g_aAccessors); iAccessor++) 1234 { 1235 pThis->pszAccessor = g_aAccessors[iAccessor].pszName; 1236 if ( ( (g_aAccessors[iAccessor].fAccess & X86_TRAP_PF_ID) 1237 && EffWrk.fNoExecute) 1238 || ( (g_aAccessors[iAccessor].fAccess & X86_TRAP_PF_RW) 1239 && !EffWrk.fWriteable 1240 && (fWp || iRing == 3)) ) 1241 g_aAccessors[iAccessor].pfnAccessor(pThis, pCtx, fAccessor, X86_XCPT_PF, 1242 fPfBase | (g_aAccessors[iAccessor].fAccess & fPfIdMask)); 1243 else 1244 g_aAccessors[iAccessor].pfnAccessor(pThis, pCtx, fAccessor, X86_XCPT_UD, UINT8_MAX); 1245 } 1246 } 1247 } 1248 1249 /* Reset the paging + full flush. */ 1250 bs3CpuBasic2Pf_RestoreFromBackups(pThis); 1251 } 1252 #endif 1253 1254 /* 1255 * Again, but redoing everything for each accessor. 1256 */ 1257 for (iStore = 0; iStore < RT_ELEMENTS(g_aStoreMethods); iStore++) 1258 { 1259 pThis->pszStore = g_aStoreMethods[iStore].pszName; 1260 1261 for (iRing = 0; iRing < 4; iRing++) 1262 { 1263 PBS3REGCTX const pCtx = &aCtxts[iRing]; 1264 #define CHECK_AD_BITS(a_fExpectedAD) \ 1265 do { \ 1266 uint32_t fActualAD = ( pThis->PgInfo.cbEntry == 8 \ 1267 ? pThis->PgInfo.u.Pae.pPte[1].au32[0] : pThis->PgInfo.u.Legacy.pPte[1].au32[0]) \ 1268 & (X86_PTE_A | X86_PTE_D); \ 1269 if (fActualAD != (a_fExpectedAD)) \ 1270 { \ 1271 Bs3TestFailedF("%u - %s/%u: unexpected A/D bits: %#x, expected %#x\n", \ 1272 g_usBs3TestStep, "xxxx", __LINE__, fActualAD, a_fExpectedAD); \ 1273 BS3CPUBASIC2PF_HALT(pThis); \ 1274 } \ 1275 } while (0) 1276 1277 if ( EffWrk.fReserved 1278 || !EffWrk.fPresent 1279 || (!EffWrk.fUser && iRing == 3)) 1280 { 1281 uint32_t const fPfBase = ( EffWrk.fReserved ? X86_TRAP_PF_P | X86_TRAP_PF_RSVD 1282 : EffWrk.fPresent ? X86_TRAP_PF_P : 0) 1283 | (iRing == 3 ? X86_TRAP_PF_US : 0); 1284 for (iAccessor = 0; iAccessor < RT_ELEMENTS(g_aAccessors); iAccessor++) 1285 { 1286 pThis->pszAccessor = g_aAccessors[iAccessor].pszName; 1287 1288 pPteWrk->pfnModify(pThis, iStore, pPteWrk, 0, 0); 1289 g_aAccessors[iAccessor].pfnAccessor(pThis, pCtx, fAccessor, X86_XCPT_PF, 1290 fPfBase | (g_aAccessors[iAccessor].fAccess & fPfIdMask)); 1291 CHECK_AD_BITS(0); 1292 bs3CpuBasic2Pf_RestoreFromBackups(pThis); 1293 1294 pPteWrk->pfnModify(pThis, iStore, pPteWrk, X86_PTE_A | X86_PTE_D, 0); 1295 g_aAccessors[iAccessor].pfnAccessor(pThis, pCtx, fAccessor, X86_XCPT_PF, 1296 fPfBase | (g_aAccessors[iAccessor].fAccess & fPfIdMask)); 1297 CHECK_AD_BITS(0); 1138 1298 bs3CpuBasic2Pf_RestoreFromBackups(pThis); 1139 1299 } … … 1144 1304 for (iAccessor = 0; iAccessor < RT_ELEMENTS(g_aAccessors); iAccessor++) 1145 1305 { 1146 p PteWrk->pfnModify(pThis, iStore, pPteWrk);1306 pThis->pszAccessor = g_aAccessors[iAccessor].pszName; 1147 1307 if ( ( (g_aAccessors[iAccessor].fAccess & X86_TRAP_PF_ID) 1148 1308 && EffWrk.fNoExecute) … … 1150 1310 && !EffWrk.fWriteable 1151 1311 && (fWp || iRing == 3)) ) 1152 g_aAccessors[iAccessor].pfnAccessor(pThis, pCtx, X86_XCPT_PF, 1153 fPfBase | (g_aAccessors[iAccessor].fAccess & fPfIdMask), 1154 fPgLvl); 1312 { 1313 uint32_t const fErrCd = fPfBase | (g_aAccessors[iAccessor].fAccess & fPfIdMask); 1314 1315 pPteWrk->pfnModify(pThis, iStore, pPteWrk, X86_PTE_A | X86_PTE_D, 0); 1316 g_aAccessors[iAccessor].pfnAccessor(pThis, pCtx, fAccessor, X86_XCPT_PF, fErrCd); 1317 CHECK_AD_BITS(0); 1318 bs3CpuBasic2Pf_RestoreFromBackups(pThis); 1319 1320 pPteWrk->pfnModify(pThis, iStore, pPteWrk, 0, X86_PTE_A | X86_PTE_D); 1321 g_aAccessors[iAccessor].pfnAccessor(pThis, pCtx, fAccessor, X86_XCPT_PF, fErrCd); 1322 CHECK_AD_BITS(X86_PTE_A | X86_PTE_D); 1323 bs3CpuBasic2Pf_RestoreFromBackups(pThis); 1324 1325 pPteWrk->pfnModify(pThis, iStore, pPteWrk, X86_PTE_A, X86_PTE_D); 1326 g_aAccessors[iAccessor].pfnAccessor(pThis, pCtx, fAccessor, X86_XCPT_PF, fErrCd); 1327 CHECK_AD_BITS(X86_PTE_D); 1328 bs3CpuBasic2Pf_RestoreFromBackups(pThis); 1329 1330 pPteWrk->pfnModify(pThis, iStore, pPteWrk, X86_PTE_D, X86_PTE_A); 1331 g_aAccessors[iAccessor].pfnAccessor(pThis, pCtx, fAccessor, X86_XCPT_PF, fErrCd); 1332 CHECK_AD_BITS(X86_PTE_A); 1333 bs3CpuBasic2Pf_RestoreFromBackups(pThis); 1334 } 1155 1335 else 1156 g_aAccessors[iAccessor].pfnAccessor(pThis, pCtx, X86_XCPT_UD, UINT8_MAX, fPgLvl); 1157 bs3CpuBasic2Pf_RestoreFromBackups(pThis); 1336 { 1337 uint32_t const fExpectedAD = (g_aAccessors[iAccessor].fAccess & X86_TRAP_PF_RW) 1338 ? X86_PTE_A | X86_PTE_D : X86_PTE_A; 1339 1340 pPteWrk->pfnModify(pThis, iStore, pPteWrk, X86_PTE_A | X86_PTE_D, 0); 1341 g_aAccessors[iAccessor].pfnAccessor(pThis, pCtx, fAccessor, X86_XCPT_UD, UINT8_MAX); 1342 CHECK_AD_BITS(fExpectedAD); 1343 bs3CpuBasic2Pf_RestoreFromBackups(pThis); 1344 1345 pPteWrk->pfnModify(pThis, iStore, pPteWrk, 0, X86_PTE_A | X86_PTE_D); 1346 g_aAccessors[iAccessor].pfnAccessor(pThis, pCtx, fAccessor, X86_XCPT_UD, UINT8_MAX); 1347 CHECK_AD_BITS(X86_PTE_A | X86_PTE_D); 1348 bs3CpuBasic2Pf_RestoreFromBackups(pThis); 1349 1350 pPteWrk->pfnModify(pThis, iStore, pPteWrk, X86_PTE_A, X86_PTE_D); 1351 g_aAccessors[iAccessor].pfnAccessor(pThis, pCtx, fAccessor, X86_XCPT_UD, UINT8_MAX); 1352 CHECK_AD_BITS(fExpectedAD | X86_PTE_D); 1353 bs3CpuBasic2Pf_RestoreFromBackups(pThis); 1354 1355 pPteWrk->pfnModify(pThis, iStore, pPteWrk, X86_PTE_D, X86_PTE_A); 1356 g_aAccessors[iAccessor].pfnAccessor(pThis, pCtx, fAccessor, X86_XCPT_UD, UINT8_MAX); 1357 CHECK_AD_BITS(fExpectedAD | X86_PTE_A); 1358 bs3CpuBasic2Pf_RestoreFromBackups(pThis); 1359 } 1158 1360 } 1159 1361 } … … 1250 1452 State.cbPteBackup = State.cTest1stPtes * (X86_PAGE_SIZE / X86_PG_PAE_ENTRIES); 1251 1453 } 1454 #ifdef BS3CPUBASIC2PF_FASTER 1455 State.cbPteBackup = State.PgInfo.cbEntry * 4; 1456 #endif 1252 1457 if (State.cTestPdes <= RT_ELEMENTS(State.au64PdeBackup)) 1253 1458 {
Note:
See TracChangeset
for help on using the changeset viewer.