Modules/UHCI - Fixed edge case NULL dereference
[tpg/acess2.git] / Kernel / arch / x86_64 / mm_virt.c
index 8b56043..511803c 100644 (file)
@@ -100,6 +100,8 @@ void MM_FinishVirtualInit(void)
 void MM_int_ClonePageEnt( Uint64 *Ent, void *NextLevel, tVAddr Addr, int bTable )
 {
        tPAddr  curpage = *Ent & PADDR_MASK; 
+        int    bCopied = 0;
+       
        if( MM_GetRefCount( curpage ) <= 0 ) {
                Log_KernelPanic("MMVirt", "Page %P still marked COW, but unreferenced", curpage);
        }
@@ -107,7 +109,7 @@ void MM_int_ClonePageEnt( Uint64 *Ent, void *NextLevel, tVAddr Addr, int bTable
        {
                *Ent &= ~PF_COW;
                *Ent |= PF_PRESENT|PF_WRITE;
-//             Log_Debug("MMVirt", "COW ent at %p (%p) only %P", Ent, NextLevel, curpage);
+               Log_Debug("MMVirt", "COW ent at %p (%p) only %P", Ent, NextLevel, curpage);
        }
        else
        {
@@ -125,23 +127,28 @@ void MM_int_ClonePageEnt( Uint64 *Ent, void *NextLevel, tVAddr Addr, int bTable
                memcpy( tmp, NextLevel, 0x1000 );
                MM_FreeTemp( (tVAddr)tmp );
                
-//             Log_Debug("MMVirt", "COW ent at %p (%p) from %P to %P", Ent, NextLevel, curpage, paddr);
+               Log_Debug("MMVirt", "COW ent at %p (%p) from %P to %P", Ent, NextLevel, curpage, paddr);
 
                MM_DerefPhys( curpage );
                *Ent &= PF_USER;
                *Ent |= paddr|PF_PRESENT|PF_WRITE;
+               
+               bCopied = 1;
        }
        INVLPG( (tVAddr)NextLevel );
        
-       // Mark COW on pages
+       // Mark COW on contents if it's a PDPT, Dir or Table
        if(bTable) 
        {
                Uint64  *dp = NextLevel;
                 int    i;
                for( i = 0; i < 512; i ++ )
                {
-                       if( !(dp[i] & PF_PRESENT) )     continue;
-                       MM_RefPhys( dp[i] & PADDR_MASK );
+                       if( !(dp[i] & PF_PRESENT) )
+                               continue;
+                       
+                       if( bCopied )
+                               MM_RefPhys( dp[i] & PADDR_MASK );
                        if( dp[i] & PF_WRITE ) {
                                dp[i] &= ~PF_WRITE;
                                dp[i] |= PF_COW;
@@ -677,7 +684,7 @@ Uint MM_GetFlags(tVAddr VAddr)
 int MM_IsValidBuffer(tVAddr Addr, size_t Size)
 {
         int    bIsUser;
-        int    pml4, pdp, dir, tab;
+       Uint64  pml4, pdp, dir, tab;
 
        Size += Addr & (PAGE_SIZE-1);
        Addr &= ~(PAGE_SIZE-1);
@@ -687,8 +694,6 @@ int MM_IsValidBuffer(tVAddr Addr, size_t Size)
        pdp = Addr >> 30;
        dir = Addr >> 21;
        tab = Addr >> 12;
-       
-//     Debug("Addr = %p, Size = 0x%x, dir = %i, tab = %i", Addr, Size, dir, tab);
 
        if( !(PAGEMAPLVL4(pml4) & 1) )  return 0;
        if( !(PAGEDIRPTR(pdp) & 1) )    return 0;
@@ -889,11 +894,11 @@ tPAddr MM_Clone(void)
        {
                // Skip addresses:
                // 320 0xFFFFA....      - Kernel Stacks
-               if( i == 320 )  continue;
+               if( i == MM_KSTACK_BASE>>39 )   continue;
                // 509 0xFFFFFE0..      - Fractal mapping
-               if( i == 508 )  continue;
+               if( i == MM_FRACTAL_BASE>>39 )  continue;
                // 510 0xFFFFFE8..      - Temp fractal mapping
-               if( i == 509 )  continue;
+               if( i == MM_TMPFRAC_BASE>>39 )  continue;
                
                TMPMAPLVL4(i) = PAGEMAPLVL4(i);
                if( TMPMAPLVL4(i) & 1 )

UCC git Repository :: git.ucc.asn.au