⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fault.c

📁 wince下的源代码集合打包
💻 C
📖 第 1 页 / 共 4 页
字号:
            // Remember the keys which have been used for SetCPUASID().            g_PageDirAccess |= ReqKey;        }        // pDirEntry points to the entry of the page directory corresponding to        // the address which faulted.  Unless the fault occurred in the alias        // area, in which case pDirEntry is the real entry, we will fix up both        // regardless        pDirEntry = &g_PageDir.PTE[ulDirFaultIdx];        if ((*pDirEntry & PG_VALID_MASK) == 0)        {            DWORD dwPageTableEntry;            //            // Allocate a page to be used as the 1st level Page Table in the            // Page Directory            //            pPageTable = AllocFreePTE(ulDirFaultIdx);#ifdef DEBUG_VMEM            {                int     i;                for (i = 0; i < ARRAY_SIZE(pPageTable->PTE); i++)                {                    if (pPageTable->PTE[i] != 0)                    {                        NKDbgPrintfW(                            TEXT("LowAddrSpacePageFault: AllocFreePTE returned a PDE with nonzero entries\r\n"));                        NKDbgPrintfW(                            TEXT("pPageTable = 0x%8.8X, PTE index = %d\r\n"),                            pPageTable, i);                        DebugBreak();                    }                }            }#endif            dwPageTableEntry = LIN_TO_PHYS(pPageTable) + PG_READ_WRITE;            *pDirEntry = g_ShadowPageDir.PTE[ulDirFaultIdx] = dwPageTableEntry;            //            // If the current process owns the page, then we need to initialize            // the alias page table pointer in slot 0.            //            if ((DWORD)(pCurProc->procnum + 1) == ulDirFaultIdx / PDES_PER_SLOT)            {                g_PageDir.PTE[ulDirFaultIdx % PDES_PER_SLOT] = dwPageTableEntry;            }        }        else        {            //            // There is already a 1st level Page Table page in the            // faulting Page Directory entry            //            pPageTable = (PPAGETABLE)PHYS_TO_LIN(*pDirEntry & PG_PHYS_ADDR_MASK);            // Is this a spurious page fault?            OldPTE =  pPageTable->PTE[((ULONG)pvAddr/PAGE_SIZE)&0x3ff];        }        //        // Now pPageTable points to the 2nd level Page Table page        //        ulBlockIndex = (DWORD)pvAddr / BLOCK_SIZE % BLOCKS_PER_PAGE_TABLE;        memcpy(&pPageTable->PTE[ulBlockIndex * PAGES_PER_BLOCK], pmb->aPages, sizeof(pmb->aPages));        pDirtyRange = &g_PTDirtyRegion[PT_PTR_TO_INDEX(pPageTable)];        if (pDirtyRange->ulStartBlock > ulBlockIndex)            pDirtyRange->ulStartBlock = ulBlockIndex;        ulBlockIndex++;        if (pDirtyRange->ulEndBlock < ulBlockIndex)            pDirtyRange->ulEndBlock = ulBlockIndex;        // Workaround for TLB incoherency seen in some AMD processors, specifically K6-2 400        //        if (OldPDE & OldPTE & PG_VALID_MASK)        {            // The Page Tables were valid on entry. We should not have got this fault.            // #ifdef DEBUG_VMEM              NKDbgPrintfW(              TEXT("LowAddrSpacePageFault: spurious Page Fault @0x%8.8X, PDE = 0x%8.8X, PTE = 0x%8.8X\r\n"),              pvAddr, OldPDE, OldPTE);#endif                                        PhysTLBFlush();        }        return pPageTable;    }    return NULL;}void _inline UpdateSlot0AccessedBits(void){    PDWORD pRealPD = &g_PageDir.PTE[0];    PDWORD pShadow = &g_ShadowPageDir.PTE[PID_TO_PT_INDEX(pCurProc->procnum)];    do {        DWORD dwTest = *pRealPD;        if (dwTest & PG_ACCESSED_MASK)        {#ifdef DEBUG_VMEM            if ((*pShadow & ~PG_ACCESSED_MASK) != (dwTest & ~PG_ACCESSED_MASK))            {                NKDbgPrintfW(                    TEXT("UpdateSlot0AccessedBits: Real Slot 0 PDE doesn't match Shadow Process PDE\r\n"));                NKDbgPrintfW(                    TEXT("Slot index = %d, PDE index = %d\r\n"),                    pCurProc->procnum + 1,                    pRealPD - &g_PageDir.PTE[0]);                NKDbgPrintfW(                    TEXT("Real PDE = 0x%8.8X, Shadow PDE = 0x%8.8X\r\n"),                    dwTest & ~PG_ACCESSED_MASK, *pShadow & ~PG_ACCESSED_MASK);                DebugBreak();            }#endif            *pShadow = dwTest;            *pRealPD = dwTest & (~PG_ACCESSED_MASK);        }        pShadow++;        pRealPD++;    } while (pRealPD < &g_PageDir.PTE[PDES_PER_SLOT]);}DWORD ResetPage(PPAGETABLE pPageTable, ULONG ulIndex){    ULONG ulStart = g_PTDirtyRegion[ulIndex].ulStartBlock;    ULONG ulEnd = g_PTDirtyRegion[ulIndex].ulEndBlock;    if (ulEnd)    {        g_PTDirtyRegion[ulIndex].ulEndBlock = 0;        g_PTDirtyRegion[ulIndex].ulStartBlock = BLOCKS_PER_PAGE_TABLE;        memset((PBYTE)pPageTable+(ulStart*PAGES_PER_BLOCK*sizeof(DWORD)), 0,               (ulEnd-ulStart)*PAGES_PER_BLOCK*sizeof(DWORD));    }#ifdef DEBUG_VMEM    {        int     i;        for (i = 0; i < ARRAY_SIZE(pPageTable->PTE); i++)        {            if (pPageTable->PTE[i] != 0)            {                NKDbgPrintfW(                    TEXT("ResetPage: Bad dirty region, PTE not zero after reset\r\n"));                NKDbgPrintfW(                    TEXT("ulStartBlock = %d, ulEndBlock = %d, PTE index = %d, PTE value = 0x%8.8X\r\n"),                    ulStart, ulEnd, i, pPageTable->PTE[i]);                DebugBreak();            }        }    }#endif    return(ulEnd);}PPAGETABLE AllocFreePTE(ULONG ulDirIdx){    PPAGETABLE pPageTable;    ULONG ulMapIdx;    //    // Copy the access bits from the alias slot entries to the corresponding    // "real" slot entries.    //    UpdateSlot0AccessedBits();    //    // Start the scan where we left off last time    //    ulMapIdx = g_AccessScanIdx;    while (TRUE)    {        ULONG ulTestPDIdx = g_PTMapIdx[ulMapIdx];        DWORD dwTestPDE = g_PageDir.PTE[ulTestPDIdx];        if ((dwTestPDE & PG_ACCESSED_MASK) == 0)        {            if ((g_ShadowPageDir.PTE[ulTestPDIdx] & PG_ACCESSED_MASK) == 0)            {                PDWORD pAlias = &g_PageDir.PTE[ulTestPDIdx % PDES_PER_SLOT];                if ((*pAlias & PG_PHYS_ADDR_MASK) ==                    (dwTestPDE & PG_PHYS_ADDR_MASK))                {                    *pAlias = 0;                }#ifdef DEBUG_VMEM                else                if ((DWORD)(pCurProc->procnum + 1) == ulTestPDIdx / PDES_PER_SLOT)                {                    NKDbgPrintfW(                        TEXT("AllocFreePTE: Slot 0 PDE doesn't match Process Slot PDE\r\n"));                    NKDbgPrintfW(                        TEXT("Slot index = %d, PDE index = %d\r\n"),                        ulTestPDIdx / PDES_PER_SLOT, ulTestPDIdx % PDES_PER_SLOT);                    NKDbgPrintfW(                        TEXT("Slot 0 PDE = 0x%8.8X, Process Slot PDE = 0x%8.8X\r\n"),                        *pAlias & ~PG_ACCESSED_MASK, dwTestPDE & ~PG_ACCESSED_MASK);                    DebugBreak();                }#endif                g_ShadowPageDir.PTE[ulTestPDIdx] = 0;                g_PageDir.PTE[ulTestPDIdx] = 0;                g_AccessScanIdx = (ulMapIdx+1) % PTE_POOL_SIZE; // Set up the global for the next time                g_PTMapIdx[ulMapIdx] = ulDirIdx;                pPageTable = &g_PageTablePool[ulMapIdx];                if (ResetPage(pPageTable, ulMapIdx))                {                    PhysTLBFlush();                }                return(pPageTable);            }        }        else        {            g_PageDir.PTE[ulTestPDIdx] = dwTestPDE & ~PG_ACCESSED_MASK;        }#ifdef DEBUG_VMEM        if (dwTestPDE != 0 && (g_ShadowPageDir.PTE[ulTestPDIdx] & ~PG_ACCESSED_MASK) !=            (dwTestPDE & ~PG_ACCESSED_MASK))        {            NKDbgPrintfW(                TEXT("AllocFreePTE: Shadow PDE doesn't match Process Slot PDE\r\n"));            NKDbgPrintfW(                TEXT("Slot index = %d, PDE index = %d\r\n"),                ulTestPDIdx / PDES_PER_SLOT, ulTestPDIdx % PDES_PER_SLOT);            NKDbgPrintfW(                TEXT("Shadow PDE = 0x%8.8X, Process Slot PDE = 0x%8.8X\r\n"),                g_ShadowPageDir.PTE[ulTestPDIdx] & ~PG_ACCESSED_MASK, dwTestPDE & ~PG_ACCESSED_MASK);            DebugBreak();        }#endif        g_ShadowPageDir.PTE[ulTestPDIdx] = dwTestPDE & ~PG_ACCESSED_MASK;        ulMapIdx = (ulMapIdx+1) % PTE_POOL_SIZE;    }}#ifdef DEBUG_VMEMvoid ValidateVirtualMemory(){    int         iRealSlotNumber;    int         iSlotIndex;    PSECTION    pSection;    int         i, j, k;    int         iFirstPageDir;    DWORD       dwPageDirEntry;    PPAGETABLE  pPageTable;    int         iFirstMemblock;    MEMBLOCK   *pMemblock;    int         iFirstPTE;    DWORD       dwPageTableEntry;    //    // Find the real slot associated with the alias slot 0    //    iRealSlotNumber = pCurProc->procnum + 1;    //    // Check each process slot    //    - If it is the current process ensure each entry matches the    //      corresponding entry in slot 0    //    - Check that each entry has a backing MEMBLOCK    //    - Check that each entry matches it's corresponding MEMBLOCK entry.    //    for (iSlotIndex = 1; iSlotIndex <= 32; iSlotIndex++)    {        iFirstPageDir = iSlotIndex * PDES_PER_SLOT;        pSection = SectionTable[iSlotIndex];        for (i = 0; i < PDES_PER_SLOT; i++)        {            if (iSlotIndex == iRealSlotNumber)            {                //                // If this slot is for the active process insure the alias                // area at slot 0 matches                //                if ((g_PageDir.PTE[i] & ~PG_ACCESSED_MASK) !=                    (g_PageDir.PTE[i + iFirstPageDir] & ~PG_ACCESSED_MASK))                {                    if (i != 0 ||                        (g_PageDir.PTE[i] & ~PG_ACCESSED_MASK) != KPAGE_PTE ||                        g_PageDir.PTE[i + iFirstPageDir] != 0)                    {                        NKDbgPrintfW(                            TEXT("ValidateVirtualMemory: Slot 0 PDE doesn't match Process slot PDE\r\n"));                        NKDbgPrintfW(                            TEXT("Slot index = %d, PDE index = %d\r\n"), iSlotIndex, i);                        NKDbgPrintfW(                            TEXT("pSection = 0x%8.8X, Slot 0 PDE = 0x%8.8X, Process Slot PDE = 0x%8.8X\r\n"),                            pSection, g_PageDir.PTE[i] & ~PG_ACCESSED_MASK,                            g_PageDir.PTE[i + iFirstPageDir] & ~PG_ACCESSED_MASK);                        DebugBreak();                    }                }            }            dwPageDirEntry = g_PageDir.PTE[iFirstPageDir + i];            if (dwPageDirEntry != 0)            {                pPageTable = (PPAGETABLE)PHYS_TO_LIN(dwPageDirEntry & PG_PHYS_ADDR_MASK);                iFirstMemblock = i * BLOCKS_PER_PAGE_TABLE;                for (j = 0; j < BLOCKS_PER_PAGE_TABLE; j++)                {                    pMemblock = (*pSection)[iFirstMemblock + j];                    iFirstPTE = j * PAGES_PER_BLOCK;                    for (k = 0; k < PAGES_PER_BLOCK; k++)                    {                        dwPageTableEntry = pPageTable->PTE[iFirstPTE + k];                        if (dwPageTableEntry != 0)                        {                            if (pMemblock != NULL && pMemblock != RESERVED_BLOCK)                            {                                if ((dwPageTableEntry & ~0xFFF) !=                                    (pMemblock->aPages[k] & ~0xFFF) && pMemblock->aPages[k])                                {                                    NKDbgPrintfW(                                        TEXT("ValidateVirtualMemory: PTE doesn't match MEMBLOCK entry\r\n"));                                    NKDbgPrintfW(                                        TEXT("Slot index = %d, PDE index = %d, MemBlock index = %d, Page index = %d\r\n"),                                        iSlotIndex, i, j, k);                                    NKDbgPrintfW(                                        TEXT("pSection = 0x%8.8X, dwPageDirEntry = 0x%8.8X, dwPageTableEntry = 0x%8.8X, dwMemblockEntry = 0x%8.8X\r\n"),                                        pSection, dwPageDirEntry, dwPageTableEntry, pMemblock->aPages[k]);                                    DebugBreak();                                }                            }                            else                            {                                //                                // Special case the Kernel Data Page since it                                // doesn't get unmapped when a process goes                                // away.                                //                                if (i != 0 || j != 0 || k != 5 ||                                    (dwPageTableEntry & ~PG_ACCESSED_MASK) != KPAGE_PTE)                                {                                    NKDbgPrintfW(                                        TEXT("ValidateVirtualMemory: PTE exists without backing MEMBLOCK\r\n"));                                    NKDbgPrintfW(                                        TEXT("Slot index = %d, PDE index = %d, MemBlock index = %d, Page index = %d\r\n"),                                        iSlotIndex, i, j, k);                                    NKDbgPrintfW(                                        TEXT("pSection = 0x%8.8X, dwPageDirEntry = 0x%8.8X, dwPageTableEntry = 0x%8.8X\r\n"),                                        pSection, dwPageDirEntry, dwPageTableEntry);                                    DebugBreak();                                }                            }                        }                    }                }            }        }    }}#endifvoid InvalidatePageTables(PDWORD pDirEntry, PDWORD pLastDirEntry){    BOOL bFlushTLB = FALSE;    PPAGETABLE pPageTable;    int idxEntry;    KCALLPROFON(72);    do {        if (*pDirEntry & PG_VALID_MASK) {            pPageTable = (PPAGETABLE)PHYS_TO_LIN(*pDirEntry & PG_PHYS_ADDR_MASK);            idxEntry = pDirEntry - &g_ShadowPageDir.PTE[0];            if (ResetPage(pPageTable, PT_PTR_TO_INDEX(pPageTable))                    && (g_PageDir.PTE[idxEntry] & PG_VALID_MASK))                bFlushTLB = TRUE;        }        pDirEntry++;    } while (pDirEntry <= pLastDirEntry);    if (bFlushTLB)        PhysTLBFlush();    KCALLPROFOFF(72);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -