VirtualBox

儲存庫 vbox 的更動 65366


忽略:
時間撮記:
2017-1-18 下午07:34:34 (8 年 以前)
作者:
vboxsync
訊息:

bs3kit: More #PF testing.

位置:
trunk/src/VBox/ValidationKit/bootsectors
檔案:
修改 4 筆資料

圖例:

未更動
新增
刪除
  • trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-basic-2-pf.c32

    r64776 r65366  
    8282    /** The size of the test area (at least two pages). */
    8383    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;
    8491    /** 16-bit data selector for pbTest. */
    8592    uint16_t                    uSel16TestData;
    8693    /** 16-bit code selector for pbTest. */
    8794    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;
    8899    /** Test paging information for pbTest. */
    89100    BS3PAGINGINFO4ADDR          PgInfo;
     
    91102    /** Set if we can use the INVLPG instruction. */
    92103    bool                        fUseInvlPg;
     104
     105    /** Reflects CR0.WP. */
     106    bool                        fWp;
     107    /** Reflects EFER.NXE & CR4.PAE. */
     108    bool                        fNxe;
    93109
    94110    /** Trap context frame. */
     
    97113    BS3REGCTX                   ExpectCtx;
    98114
     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
    99124} BS3CPUBASIC2PFSTATE;
    100125/** Pointer to state for the \#PF test. */
    101126typedef BS3CPUBASIC2PFSTATE *PBS3CPUBASIC2PFSTATE;
     127
     128
     129/**
     130 * Paging modification worker.
     131 */
     132typedef 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;
     144typedef BS3CPUBASIC2PFMODPT const *PCBS3CPUBASIC2PFMODPT;
     145
     146
     147/**
     148 * Memory accessor.
     149 */
     150typedef 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;
     160typedef const BS3CPUBASIC2PFACCESSOR *PCBS3CPUBASIC2PFACCESSOR;
    102161
    103162
     
    262321
    263322
     323/**
     324 * Restores all the paging entries from backup and flushes everything.
     325 */
     326static 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 */
     348static 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
    264363static void bs3CpuBasic2Pf_DoExec(PBS3CPUBASIC2PFSTATE pThis, PBS3REGCTX pCtx, uint8_t bXcpt, uint8_t uPfErrCd, bool fPageLevel)
    265364{
     
    267366    unsigned off;
    268367
    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++)
    270369    {
    271370        /* Emit a little bit of code (using the original allocation mapping) and point pCtx to it. */
     
    295394        Bs3TrapSetJmpAndRestore(pCtx, &pThis->TrapCtx);
    296395        //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);
    302401        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));
    305406    }
    306407}
     
    382483        unsigned off    = X86_PAGE_SIZE * (i + 1) - pThis->cbAccess;
    383484        unsigned offEnd = X86_PAGE_SIZE * (i + 1) + (i == 0 ? 8 : 7);
     485
    384486        for (; off < offEnd; off++)
    385487        {
     
    398500            {
    399501                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*/);
    401503                pThis->ExpectCtx.rax = pCtx->rax;
    402504            }
     
    482584                || (fPageLevel && off <= X86_PAGE_SIZE - pThis->cbAccess) )
    483585            {
    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*/);
    485587                if (*(uint64_t *)&pThis->pbOrgTest[off] != uExpectStored)
    486588                    Bs3TestFailedF("%u - %s: Stored %#RX64, expected %#RX64",
     
    580682            {
    581683                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*/);
    583685                if (*(uint64_t *)&pThis->pbOrgTest[off] != uExpectStored)
    584686                    Bs3TestFailedF("%u - %s: Stored %#RX64, expected %#RX64",
     
    702804                pThis->ExpectCtx.rax.u = uExpectedRax;
    703805                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*/);
    705807                if (*(uint64_t *)&pThis->pbOrgTest[off] != uExpectStored)
    706808                    Bs3TestFailedF("%u - %s: Stored %#RX64, expected %#RX64",
     
    729831
    730832
     833static 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
     840static 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
     847static 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
     864static 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
     876static 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
     892static 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
     909static 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
     920static 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
     935static 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
     949static bool bs3CpuBasic2Pf_IsNxe(PBS3CPUBASIC2PFSTATE pThis, PCBS3CPUBASIC2PFMODPT pEntry)
     950{
     951    return pThis->fNxe && pThis->PgInfo.cbEntry == 8;
     952}
     953
     954/** @} */
     955
     956
     957static 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
    731994/**
    732995 * Worker for bs3CpuBasic2_RaiseXcpt0e_c32 that does the actual testing.
     
    736999 * @returns Error count.
    7371000 * @param   pThis       Test state data.
    738  */
    739 static uint8_t bs3CpuBasic2_RaiseXcpt0eWorker(PBS3CPUBASIC2PFSTATE register pThis)
     1001 * @param   fNxe        Whether NX is enabled.
     1002 */
     1003static uint8_t bs3CpuBasic2_RaiseXcpt0eWorker(PBS3CPUBASIC2PFSTATE register pThis, bool const fWp, bool const fNxe)
    7401004{
    7411005    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;
    7421010    BS3REGCTX           aCtxts[4];
     1011
     1012    pThis->fWp  = fWp;
     1013    pThis->fNxe = fNxe;
    7431014
    7441015    /** @todo figure out V8086 testing. */
     
    7791050     */
    7801051    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*/);
    7931054
    7941055    /*
    795      * Check the U bit on PTE level.
     1056     * Check the U bit on PTE level.  We only mess with the 2nd page.
    7961057     */
    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    }
    7981169
    7991170    return 0;
     
    8341205    {
    8351206        cbTestUnaligned >>= 1;
    836         if (cbTestUnaligned <= _8K)
     1207        if (cbTestUnaligned <= _16K)
    8371208        {
    8381209            Bs3TestFailed("Failed to allocate memory to play around with\n");
     
    8411212    }
    8421213
     1214    /* align. */
    8431215    if ((uintptr_t)pvTestUnaligned & (cbTestUnaligned - 1))
    8441216    {
     
    8511223        State.cbTest    = cbTestUnaligned;
    8521224    }
     1225    State.cTestPages = State.cbTest >> X86_PAGE_SHIFT;
    8531226
    8541227    /*
     
    8621235        if (RT_SUCCESS(rc))
    8631236        {
    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);
    8741296        }
    8751297        else
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-CpuDetect.asm

    r60674 r65366  
    294294        test    edx, X86_CPUID_EXT_FEATURE_EDX_LONG_MODE
    295295        jz      .no_long_mode
    296         or      ax, BS3CPU_F_CPUID_EXT_LEAVES | BS3CPU_F_LONG_MODE
    297         jmp     .return
     296        or      ah, ((BS3CPU_F_CPUID_EXT_LEAVES | BS3CPU_F_LONG_MODE) >> 8)
     297        jmp     .no_check_for_nx
    298298.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
    301306.no_ext_leaves:
    302307        pop     xAX                     ; restore PAE+PProOrNewer
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit.h

    r64751 r65366  
    33813381/** Flag indicating that the CPU supports long mode. */
    33823382#define BS3CPU_F_LONG_MODE          UINT16_C(0x1000)
     3383/** Flag indicating that the CPU supports NX. */
     3384#define BS3CPU_F_NX                 UINT16_C(0x2000)
    33833385/** @} */
    33843386
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit.mac

    r64694 r65366  
    17031703%define BS3CPU_F_PSE_BIT            11
    17041704%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
    17051708;; @}
    17061709
注意: 瀏覽 TracChangeset 來幫助您使用更動檢視器

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