VirtualBox

Ignore:
Timestamp:
Jan 20, 2017 8:07:35 PM (8 years ago)
Author:
vboxsync
Message:

bs3-cpu-basic-2-pf: Added testcase for access bit and instruction raising exception.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-basic-2-pf.c32

    r65366 r65396  
    4343    } while (0)
    4444
     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
    4557
    4658/*********************************************************************************************************************************
     
    5365    FNBS3CPUBASIC2PFSNIPPET    *pfn;
    5466    uint8_t                     offUd2;
    55     uint8_t                     cbTmpl;
     67
    5668} FNBS3CPUBASIC2PFTSTCODE;
    5769typedef FNBS3CPUBASIC2PFTSTCODE const *PCFNBS3CPUBASIC2PFTSTCODE;
     
    5971typedef struct BS3CPUBASIC2PFTTSTCMNMODE
    6072{
    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;
    6679} BS3CPUBASIC2PFTTSTCMNMODE;
    6780typedef BS3CPUBASIC2PFTTSTCMNMODE const *PCBS3CPUBASIC2PFTTSTCMNMODE;
     
    108121    bool                        fNxe;
    109122
     123    const char                 *pszAccessor;
     124    const char                 *pszPteWorker;
     125    const char                 *pszStore;
     126
    110127    /** Trap context frame. */
    111128    BS3TRAPFRAME                TrapCtx;
     
    139156    uint32_t fReserved   : 1;
    140157    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);
    142160    bool   (*pfnApplicable)(PBS3CPUBASIC2PFSTATE pThis, struct BS3CPUBASIC2PFMODPT const *pEntry);
    143161} BS3CPUBASIC2PFMODPT;
    144162typedef BS3CPUBASIC2PFMODPT const *PCBS3CPUBASIC2PFMODPT;
    145163
     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)
    146168
    147169/**
     
    153175    const char *pszName;
    154176    /** The accessor. */
    155     void      (*pfnAccessor)(PBS3CPUBASIC2PFSTATE pThis, PBS3REGCTX pCtx, uint8_t bXcpt, uint8_t uPfErrCd, bool fPageLevel);
     177    void      (*pfnAccessor)(PBS3CPUBASIC2PFSTATE pThis, PBS3REGCTX pCtx, uint32_t fFlags, uint8_t bXcpt, uint8_t uPfErrCd);
    156178    /** The X86_TRAP_PF_XXX access flags this access sets.   */
    157179    uint32_t    fAccess;
    158 
     180    /** The exception when things are fine. */
     181    uint8_t     bOkayXcpt;
    159182} BS3CPUBASIC2PFACCESSOR;
    160183typedef const BS3CPUBASIC2PFACCESSOR *PCBS3CPUBASIC2PFACCESSOR;
     
    177200FNBS3CPUBASIC2PFSNIPPET bs3CpuBasic2_xchg_ds_bx_ax__ud2_c16;
    178201FNBS3CPUBASIC2PFSNIPPET bs3CpuBasic2_cmpxchg_ds_bx_cx__ud2_c16;
     202FNBS3CPUBASIC2PFSNIPPET bs3CpuBasic2_div_ds_bx__ud2_c16;
    179203
    180204FNBS3CPUBASIC2PFSNIPPET bs3CpuBasic2_mov_ax_ds_bx__ud2_c32;
     
    182206FNBS3CPUBASIC2PFSNIPPET bs3CpuBasic2_xchg_ds_bx_ax__ud2_c32;
    183207FNBS3CPUBASIC2PFSNIPPET bs3CpuBasic2_cmpxchg_ds_bx_cx__ud2_c32;
     208FNBS3CPUBASIC2PFSNIPPET bs3CpuBasic2_div_ds_bx__ud2_c32;
    184209
    185210FNBS3CPUBASIC2PFSNIPPET bs3CpuBasic2_mov_ax_ds_bx__ud2_c64;
     
    187212FNBS3CPUBASIC2PFSNIPPET bs3CpuBasic2_xchg_ds_bx_ax__ud2_c64;
    188213FNBS3CPUBASIC2PFSNIPPET bs3CpuBasic2_cmpxchg_ds_bx_cx__ud2_c64;
     214FNBS3CPUBASIC2PFSNIPPET bs3CpuBasic2_div_ds_bx__ud2_c64;
    189215
    190216
     
    195221static const struct
    196222{
    197     const char     *pszStore;
     223    const char     *pszName;
    198224    void (BS3_CALL *pfnStore)(void *pvDst, uint32_t uValue, uint32_t uOld);
    199225} g_aStoreMethods[] =
     
    213239        {   bs3CpuBasic2_xchg_ds_bx_ax__ud2_c16,    2 },
    214240        {   bs3CpuBasic2_cmpxchg_ds_bx_cx__ud2_c16, 3 },
     241        {   bs3CpuBasic2_div_ds_bx__ud2_c16,        2 },
    215242    },
    216243    {
     
    220247        {   bs3CpuBasic2_xchg_ds_bx_ax__ud2_c32,    2 },
    221248        {   bs3CpuBasic2_cmpxchg_ds_bx_cx__ud2_c32, 3 },
     249        {   bs3CpuBasic2_div_ds_bx__ud2_c32,        2 },
    222250    },
    223251    {
     
    227255        {   bs3CpuBasic2_xchg_ds_bx_ax__ud2_c64,    2 + 1 },
    228256        {   bs3CpuBasic2_cmpxchg_ds_bx_cx__ud2_c64, 3 + 1 },
     257        {   bs3CpuBasic2_div_ds_bx__ud2_c64,        2 + 1 },
    229258    },
    230259    {
     
    234263        {   bs3CpuBasic2_xchg_ds_bx_ax__ud2_c16,    2 },
    235264        {   bs3CpuBasic2_cmpxchg_ds_bx_cx__ud2_c16, 3 },
     265        {   bs3CpuBasic2_div_ds_bx__ud2_c16,        2 },
    236266    },
    237267};
     
    263293        Bs3TestPrintf("Halting: g_uBs3CpuDetected=%#x\n", g_uBs3CpuDetected);
    264294        Bs3TestPrintf("Halting: bXcpt=%#x uErrCd=%#x\n", bXcpt, uErrCd);
    265         ASMHalt();
     295        BS3CPUBASIC2PF_HALT(pThis);
    266296#endif
    267297    }
     
    297327        Bs3TestPrintf("Halting: g_uBs3CpuDetected=%#x\n", g_uBs3CpuDetected);
    298328        Bs3TestPrintf("Halting: bXcpt=%#x uErrCd=%#x\n", bXcpt, uErrCd);
    299         ASMHalt();
     329        BS3CPUBASIC2PF_HALT(pThis);
    300330#endif
    301331    }
     
    361391 * @{ */
    362392
    363 static void bs3CpuBasic2Pf_DoExec(PBS3CPUBASIC2PFSTATE pThis, PBS3REGCTX pCtx, uint8_t bXcpt, uint8_t uPfErrCd, bool fPageLevel)
     393static void bs3CpuBasic2Pf_DoExec(PBS3CPUBASIC2PFSTATE pThis, PBS3REGCTX pCtx, uint32_t fFlags, uint8_t bXcpt, uint8_t uPfErrCd)
    364394{
    365395    uint8_t *pbOrgTest = pThis->pbOrgTest;
     
    395425        //Bs3TestPrintf("off=%#06x bXcpt=%#x uErrCd=%#RX64\n", off, pThis->TrapCtx.bXcpt, pThis->TrapCtx.uErrCd);
    396426        if (   bXcpt != X86_XCPT_PF
    397             || (fPageLevel && off < X86_PAGE_SIZE - 4))
     427            || ((fFlags & BS3CB2PFACC_F_PAGE_LEVEL) && off < X86_PAGE_SIZE - 4))
    398428            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)
    400430            bs3CpuBasic2Pf_CompareSimplePf(pThis, pCtx, 0, uPfErrCd, (uintptr_t)pThis->pbTest + off);
    401431        else
     
    441471 * @param   pThis           The test stat data.
    442472 * @param   pCtx            The test context.
     473 * @param   fFlags          BS3CB2PFACC_F_XXX.
    443474 * @param   bXcpt           X86_XCPT_PF if this can cause \#PFs, otherwise
    444475 *                          X86_XCPT_UD.
    445476 * @param   uPfErrCd        The error code for \#PFs.
    446  * @param   fPageLevel      Set if we're pushing PTE level bits.
    447477 */
    448 static void bs3CpuBasic2Pf_DoMovLoad(PBS3CPUBASIC2PFSTATE pThis, PBS3REGCTX pCtx, uint8_t bXcpt, uint8_t uPfErrCd,
    449                                      bool fPageLevel)
     478static void bs3CpuBasic2Pf_DoMovLoad(PBS3CPUBASIC2PFSTATE pThis, PBS3REGCTX pCtx, uint32_t fFlags, uint8_t bXcpt, uint8_t uPfErrCd)
    450479{
    451480    static uint64_t const s_uValue = UINT64_C(0x7c4d0114428d);
     
    496525
    497526            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) )
    500529            {
    501530                pThis->ExpectCtx.rax.u = uExpectRax;
     
    522551 * @param   pThis           The test stat data.
    523552 * @param   pCtx            The test context.
     553 * @param   fFlags          BS3CB2PFACC_F_XXX.
    524554 * @param   bXcpt           X86_XCPT_PF if this can cause \#PFs, otherwise
    525555 *                          X86_XCPT_UD.
    526556 * @param   uPfErrCd        The error code for \#PFs.
    527  * @param   fPageLevel      Set if we're pushing PTE level bits.
    528557 */
    529 static void bs3CpuBasic2Pf_DoMovStore(PBS3CPUBASIC2PFSTATE pThis, PBS3REGCTX pCtx, uint8_t bXcpt, uint8_t uPfErrCd,
    530                                       bool fPageLevel)
     558static void bs3CpuBasic2Pf_DoMovStore(PBS3CPUBASIC2PFSTATE pThis, PBS3REGCTX pCtx, uint32_t fFlags,
     559                                      uint8_t bXcpt, uint8_t uPfErrCd)
    531560{
    532561    static uint64_t const s_uValue        = UINT64_C(0x3af45ead86a34a26);
     
    581610
    582611            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) )
    585614            {
    586615                bs3CpuBasic2Pf_CompareCtx(pThis, &pThis->ExpectCtx, pThis->pCmnMode->MovStore.offUd2, X86_XCPT_UD, 0 /*uErrCd*/);
     
    614643 * @param   pThis           The test stat data.
    615644 * @param   pCtx            The test context.
     645 * @param   fFlags          BS3CB2PFACC_F_XXX.
    616646 * @param   bXcpt           X86_XCPT_PF if this can cause \#PFs, otherwise
    617647 *                          X86_XCPT_UD.
    618648 * @param   uPfErrCd        The error code for \#PFs.
    619  * @param   fPageLevel      Set if we're pushing PTE level bits.
    620649 */
    621 static void bs3CpuBasic2Pf_DoXchg(PBS3CPUBASIC2PFSTATE pThis, PBS3REGCTX pCtx, uint8_t bXcpt, uint8_t uPfErrCd, bool fPageLevel)
     650static void bs3CpuBasic2Pf_DoXchg(PBS3CPUBASIC2PFSTATE pThis, PBS3REGCTX pCtx, uint32_t fFlags, uint8_t bXcpt, uint8_t uPfErrCd)
    622651{
    623652    static uint64_t const s_uValue        = UINT64_C(0xea58699648e2f32c);
     
    678707
    679708            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) )
    682711            {
    683712                pThis->ExpectCtx.rax.u = uExpectedRax;
     
    712741 * @param   pThis           The test stat data.
    713742 * @param   pCtx            The test context.
     743 * @param   fFlags          BS3CB2PFACC_F_XXX.
    714744 * @param   bXcpt           X86_XCPT_PF if this can cause \#PFs, otherwise
    715745 *                          X86_XCPT_UD.
    716746 * @param   uPfErrCd        The error code for \#PFs.
    717  * @param   fPageLevel      Set if we're pushing PTE level bits.
    718747 * @param   fMissmatch      Whether to fail and not store (@c true), or succeed
    719748 *                          and do the store.
    720749 */
    721 static void bs3CpuBasic2Pf_DoCmpXchg(PBS3CPUBASIC2PFSTATE pThis, PBS3REGCTX pCtx, uint8_t bXcpt, uint8_t uPfErrCd,
    722                                      bool fPageLevel, bool fMissmatch)
     750static void bs3CpuBasic2Pf_DoCmpXchg(PBS3CPUBASIC2PFSTATE pThis, PBS3REGCTX pCtx, uint32_t fFlags,
     751                                     uint8_t bXcpt, uint8_t uPfErrCd, bool fMissmatch)
    723752{
    724753    static uint64_t const s_uValue        = UINT64_C(0xea58699648e2f32c);
     
    799828
    800829            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) )
    803832            {
    804833                pThis->ExpectCtx.rax.u = uExpectedRax;
     
    831860
    832861
    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*/ );
     862static 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
     869static 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 */
     880static 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    }
    844950}
    845951
     
    847953static BS3CPUBASIC2PFACCESSOR const g_aAccessors[] =
    848954{
    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 },
    855962};
    856963
     
    862969
    863970
    864 static void bs3CpuBasic2Pf_ClearMask(PBS3CPUBASIC2PFSTATE pThis, unsigned iStore, PCBS3CPUBASIC2PFMODPT pEntry)
     971static void bs3CpuBasic2Pf_ClearMask(PBS3CPUBASIC2PFSTATE pThis, unsigned iStore, PCBS3CPUBASIC2PFMODPT pEntry,
     972                                     uint32_t fClearMask, uint32_t fSetMask)
    865973{
    866974    if (pThis->PgInfo.cbEntry == 4)
    867975        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,
    869977                                         pThis->PgInfo.u.Legacy.pPte[1].u);
    870978    else
    871979        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,
    873981                                         pThis->PgInfo.u.Pae.pPte[1].au32[0]);
    874982}
    875983
    876 static void bs3CpuBasic2Pf_SetBit(PBS3CPUBASIC2PFSTATE pThis, unsigned iStore, PCBS3CPUBASIC2PFMODPT pEntry)
     984static void bs3CpuBasic2Pf_SetBit(PBS3CPUBASIC2PFSTATE pThis, unsigned iStore, PCBS3CPUBASIC2PFMODPT pEntry,
     985                                  uint32_t fClearMask, uint32_t fSetMask)
    877986{
    878987    if (pThis->PgInfo.cbEntry == 4)
    879988        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),
    881990                                         pThis->PgInfo.u.Legacy.pPte[1].u);
    882991    else if (pEntry->uModifyArg < 32)
    883992        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),
    885994                                         pThis->PgInfo.u.Pae.pPte[1].au32[0]);
    886995    else
     996    {
    887997        g_aStoreMethods[iStore].pfnStore(&pThis->PgInfo.u.Pae.pPte[1].au32[1],
    888998                                         pThis->PgInfo.u.Pae.pPte[1].au32[1] | RT_BIT_32(pEntry->uModifyArg - 32),
    889999                                         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
     1008static void bs3CpuBasic2Pf_ClearBit(PBS3CPUBASIC2PFSTATE pThis, unsigned iStore, PCBS3CPUBASIC2PFMODPT pEntry,
     1009                                    uint32_t fClearMask, uint32_t fSetMask)
    8931010{
    8941011    if (pThis->PgInfo.cbEntry == 4)
    8951012        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),
    8971014                                         pThis->PgInfo.u.Legacy.pPte[1].u);
    8981015    else if (pEntry->uModifyArg < 32)
    8991016        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),
    9011018                                         pThis->PgInfo.u.Pae.pPte[1].au32[0]);
    9021019    else
     
    9051022                                         pThis->PgInfo.u.Pae.pPte[1].au32[1]);
    9061023}
    907 
    908 
    909 static void bs3CpuBasic2Pf_NoChange(PBS3CPUBASIC2PFSTATE pThis, unsigned iStore, PCBS3CPUBASIC2PFMODPT pEntry)
    910 {
    911     RT_NOREF3(pThis, iStore, pEntry);
     1024#endif
     1025
     1026static 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    }
    9121040}
    9131041
     
    10511179    for (iRing = 0; iRing < 4; iRing++)
    10521180        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);
    10541182
    10551183    /*
     
    10571185     */
    10581186    {
    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;
    10621190
    10631191        bs3CpuBasic2Pf_FlushAll();
     
    10681196            if (   pPteWrk->pfnApplicable && !pPteWrk->pfnApplicable(pThis, pPteWrk))
    10691197                continue;
    1070             //if (pThis->bMode == BS3_MODE_LM16) Bs3TestPrintf("PteWrk: %s\n", pPteWrk->pszName);
     1198
     1199            pThis->pszPteWorker = pPteWrk->pszName;
    10711200
    10721201            EffWrk = *pPteWrk;
    10731202
     1203#if 1
    10741204            /*
    10751205             * Do the modification once, then test all different accesses
     
    10781208            for (iStore = 0; iStore < RT_ELEMENTS(g_aStoreMethods); iStore++)
    10791209            {
    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
    11231213                for (iRing = 0; iRing < 4; iRing++)
    11241214                {
     
    11331223                        for (iAccessor = 0; iAccessor < RT_ELEMENTS(g_aAccessors); iAccessor++)
    11341224                        {
    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);
    11381298                            bs3CpuBasic2Pf_RestoreFromBackups(pThis);
    11391299                        }
     
    11441304                        for (iAccessor = 0; iAccessor < RT_ELEMENTS(g_aAccessors); iAccessor++)
    11451305                        {
    1146                             pPteWrk->pfnModify(pThis, iStore, pPteWrk);
     1306                            pThis->pszAccessor = g_aAccessors[iAccessor].pszName;
    11471307                            if (   (   (g_aAccessors[iAccessor].fAccess & X86_TRAP_PF_ID)
    11481308                                    && EffWrk.fNoExecute)
     
    11501310                                    && !EffWrk.fWriteable
    11511311                                    && (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                            }
    11551335                            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                            }
    11581360                        }
    11591361                    }
     
    12501452                State.cbPteBackup  = State.cTest1stPtes * (X86_PAGE_SIZE / X86_PG_PAE_ENTRIES);
    12511453            }
     1454#ifdef BS3CPUBASIC2PF_FASTER
     1455            State.cbPteBackup = State.PgInfo.cbEntry * 4;
     1456#endif
    12521457            if (State.cTestPdes <= RT_ELEMENTS(State.au64PdeBackup))
    12531458            {
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette