X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Kernel%2Farch%2Fx86%2Fmm_virt.c;h=a022da2b9e9f92f24b414e520d1051eb2b7e11fa;hb=df4e449c0972a703ce403332668a7bb3366d126a;hp=b4fd2225a3d90616c3c7d4883efb8f137ff4a0a7;hpb=cf00ee7fb53960fabd8b3c1072a54605118adf9c;p=tpg%2Facess2.git diff --git a/Kernel/arch/x86/mm_virt.c b/Kernel/arch/x86/mm_virt.c index b4fd2225..a022da2b 100644 --- a/Kernel/arch/x86/mm_virt.c +++ b/Kernel/arch/x86/mm_virt.c @@ -28,8 +28,6 @@ #define TEMP_MAP_ADDR 0xFEFF0000 // Allows 16 "temp" pages #define NUM_TEMP_PAGES 16 -#define USE_COW 1 - #define PF_PRESENT 0x1 #define PF_WRITE 0x2 #define PF_USER 0x4 @@ -99,7 +97,7 @@ void MM_InstallVirtual() */ void MM_PageFault(Uint Addr, Uint ErrorCode, tRegs *Regs) { - ENTER("xAddr bErrorCode", Addr, ErrorCode); + //ENTER("xAddr bErrorCode", Addr, ErrorCode); // -- Check for COW -- if( gaPageDir [Addr>>22] & PF_PRESENT @@ -107,12 +105,20 @@ void MM_PageFault(Uint Addr, Uint ErrorCode, tRegs *Regs) && gaPageTable[Addr>>12] & PF_COW ) { tPAddr paddr; - paddr = MM_DuplicatePage( Addr ); - MM_DerefPhys( gaPageTable[Addr>>12] & ~0xFFF ); - gaPageTable[Addr>>12] &= PF_USER; - gaPageTable[Addr>>12] |= paddr|PF_PRESENT|PF_WRITE; + if(MM_GetRefCount( gaPageTable[Addr>>12] & ~0xFFF ) == 0) + { + gaPageTable[Addr>>12] &= ~PF_COW; + gaPageTable[Addr>>12] |= PF_PRESENT|PF_WRITE; + } + else + { + paddr = MM_DuplicatePage( Addr ); + MM_DerefPhys( gaPageTable[Addr>>12] & ~0xFFF ); + gaPageTable[Addr>>12] &= PF_USER; + gaPageTable[Addr>>12] |= paddr|PF_PRESENT|PF_WRITE; + } INVLPG( Addr & ~0xFFF ); - LEAVE('-'); + //LEAVE('-') return; } @@ -136,7 +142,6 @@ void MM_PageFault(Uint Addr, Uint ErrorCode, tRegs *Regs) MM_DumpTables(0, -1); Panic("Page Fault at 0x%x\n", Regs->eip); - LEAVE('-'); } /** @@ -200,11 +205,18 @@ void MM_DumpTables(tVAddr Start, tVAddr End) */ tPAddr MM_Allocate(Uint VAddr) { + tPAddr paddr; // Check if the directory is mapped if( gaPageDir[ VAddr >> 22 ] == 0 ) { // Allocate directory - gaPageDir[ VAddr >> 22 ] = MM_AllocPhys() | 3; + paddr = MM_AllocPhys(); + if( paddr == 0 ) { + Warning("MM_Allocate - Out of Memory (Called by %p)", __builtin_return_address(0)); + return 0; + } + // Map + gaPageDir[ VAddr >> 22 ] = paddr | 3; // Mark as user if(VAddr < MM_USER_MAX) gaPageDir[ VAddr >> 22 ] |= PF_USER; @@ -213,18 +225,25 @@ tPAddr MM_Allocate(Uint VAddr) } // Check if the page is already allocated else if( gaPageTable[ VAddr >> 12 ] != 0 ) { - Warning("MM_Allocate - Allocating to used address"); + Warning("MM_Allocate - Allocating to used address (%p)", VAddr); return gaPageTable[ VAddr >> 12 ] & ~0xFFF; } // Allocate - gaPageTable[ VAddr >> 12 ] = MM_AllocPhys() | 3; + paddr = MM_AllocPhys(); + if( paddr == 0 ) { + Warning("MM_Allocate - Out of Memory when allocating at %p (Called by %p)", + VAddr, __builtin_return_address(0)); + return 0; + } + // Map + gaPageTable[ VAddr >> 12 ] = paddr | 3; // Mark as user if(VAddr < MM_USER_MAX) gaPageTable[ VAddr >> 12 ] |= PF_USER; // Invalidate Cache for address INVLPG( VAddr & ~0xFFF ); - return gaPageTable[ VAddr >> 12 ] & ~0xFFF; + return paddr; } /** @@ -393,7 +412,6 @@ Uint MM_Clone() continue; } - #if USE_COW // Refrence old page MM_RefPhys( gaPageTable[i*1024+j] & ~0xFFF ); // Add to new table @@ -403,10 +421,6 @@ Uint MM_Clone() } else gaTmpTable[i*1024+j] = gaPageTable[i*1024+j]; - LOG("gaTmpTable[0x%x] = 0x%x", i*1024+j, gaTmpTable[i*1024+j]); - #else - gaTmpTable[i*1024+j] = MM_DuplicatePage( (i*1024+j)<<12 ) | (gaPageTable[i*1024+j]&7); - #endif } } @@ -524,6 +538,19 @@ void MM_SetFlags(Uint VAddr, Uint Flags, Uint Mask) if( Flags & MM_PFLAG_KERNEL ) *ent &= ~PF_USER; else *ent |= PF_USER; } + + // Copy-On-Write + if( Mask & MM_PFLAG_COW ) + { + if( Flags & MM_PFLAG_COW ) { + *ent &= ~PF_WRITE; + *ent |= PF_COW; + } + else { + *ent &= ~PF_COW; + *ent |= PF_WRITE; + } + } } /**