kernel/eka/memmodel/epoc/flexible/mmu/mmapping.cpp
branchanywhere
changeset 41 d32f34975bbf
parent 33 0173bcd7697c
child 39 5d2844f35677
--- a/kernel/eka/memmodel/epoc/flexible/mmu/mmapping.cpp	Mon Feb 01 19:40:00 2010 +0100
+++ b/kernel/eka/memmodel/epoc/flexible/mmu/mmapping.cpp	Mon Feb 01 19:49:38 2010 +0100
@@ -104,22 +104,30 @@
 			return KErrArgument;
 		}
 
-	TLinAddr base = iAllocatedLinAddrAndOsAsid&~KPageMask;
-#ifdef _DEBUG
-	TUint osAsid = iAllocatedLinAddrAndOsAsid&KPageMask;
-#endif
+	TLinAddr base = iAllocatedLinAddrAndOsAsid & ~KPageMask;
+	TLinAddr top = base + (aCount << KPageShift);
 
 	// check user/supervisor memory partitioning...
-	if(base<KUserMemoryLimit != (bool)(aPermissions&EUser))
-		return KErrAccessDenied;
+	if (aPermissions & EUser)
+		{
+		if (base > KUserMemoryLimit || top > KUserMemoryLimit)
+			return KErrAccessDenied;
+		}
+	else
+		{
+		if (base < KUserMemoryLimit || top < KUserMemoryLimit)
+			return KErrAccessDenied;
+		}
 
-	// check mapping doesn't straddle KGlobalMemoryBase or KUserMemoryLimit...
-	__NK_ASSERT_DEBUG(TUint(KGlobalMemoryBase-base)==0 || TUint(KGlobalMemoryBase-base)>=TUint(aCount<<KPageShift));
-	__NK_ASSERT_DEBUG(TUint(KUserMemoryLimit-base)==0 || TUint(KUserMemoryLimit-base)>=TUint(aCount<<KPageShift));
+	// check that mapping doesn't straddle KUserMemoryLimit or KGlobalMemoryBase ...
+	__NK_ASSERT_DEBUG((base < KUserMemoryLimit) == (top <= KUserMemoryLimit));
+	__NK_ASSERT_DEBUG((base < KGlobalMemoryBase) == (top <= KGlobalMemoryBase));
+
+	// check that only global memory is mapped into the kernel process
+	TBool global = base >= KGlobalMemoryBase;
+	__NK_ASSERT_DEBUG(global || (iAllocatedLinAddrAndOsAsid & KPageMask) != KKernelOsAsid);
 
 	// setup attributes...
-	TBool global = base>=KGlobalMemoryBase;
-	__NK_ASSERT_DEBUG(global || osAsid!=(TInt)KKernelOsAsid); // prevent non-global memory in kernel process
 	PteType() =	Mmu::PteType(aPermissions,global);
 	iBlankPte = Mmu::BlankPte(aMemory->Attributes(),PteType());
 
@@ -285,6 +293,10 @@
 		else
 			{
 			TPde pde = Mmu::PageTablePhysAddr(pt)|iBlankPde;
+#ifdef	__USER_MEMORY_GUARDS_ENABLED__
+			if (IsUserMapping())
+				pde = PDE_IN_DOMAIN(pde, USER_MEMORY_DOMAIN);
+#endif
 			TRACE2(("!PDE %x=%x (was %x)",pPde,pde,*pPde));
 			if (Mmu::PdeMapsSection(*pPde))
 				{
@@ -495,19 +507,20 @@
 		if(pinnedPt && pinnedPt!=pt)
 			{
 			// previously pinned page table not needed...
-			PageTableAllocator::UnpinPageTable(pinnedPt,aPinArgs);
+			::PageTables.UnpinPageTable(pinnedPt,aPinArgs);
 
 			// make sure we have memory for next pin attempt...
 			MmuLock::Unlock();
 			aPinArgs.AllocReplacementPages(KNumPagesToPinOnePageTable);
-			MmuLock::Lock();
 			if(!aPinArgs.HaveSufficientPages(KNumPagesToPinOnePageTable)) // if out of memory...
 				{
 				// make sure we free any unneeded page table we allocated...
 				if(pt)
 					FreePageTable(Mmu::PageDirectoryEntry(OsAsid(),aAddr));
+				MmuLock::Lock();
 				return 0;
 				}
+			MmuLock::Lock();
 			}
 
 		if(!pt)
@@ -527,8 +540,16 @@
 			return pt;
 
 		// pin the page table...
+		if (::PageTables.PinPageTable(pt,aPinArgs) != KErrNone)
+			{// Couldn't pin the page table...
+			MmuLock::Unlock();
+			// make sure we free any unneeded page table we allocated...
+			FreePageTable(Mmu::PageDirectoryEntry(OsAsid(),aAddr));
+			MmuLock::Lock();
+			return 0;
+			}
+
 		pinnedPt = pt;
-		PageTableAllocator::PinPageTable(pinnedPt,aPinArgs);
 		}
 	}
 
@@ -628,6 +649,10 @@
 			pti->SetFine(aAddr&~KChunkMask,iAllocatedLinAddrAndOsAsid&KPageMask);
 
 			TPde pde = Mmu::PageTablePhysAddr(newPt)|iBlankPde;
+#ifdef	__USER_MEMORY_GUARDS_ENABLED__
+			if (IsUserMapping())
+				pde = PDE_IN_DOMAIN(pde, USER_MEMORY_DOMAIN);
+#endif
 			TRACE2(("!PDE %x=%x",aPdeAddress,pde));
 			__NK_ASSERT_DEBUG(((*aPdeAddress^pde)&~KPdeMatchMask)==0 || *aPdeAddress==KPdeUnallocatedEntry);
 			*aPdeAddress = pde;
@@ -1469,7 +1494,7 @@
 
 	MmuLock::Lock();
 	while(pPt<pPtEnd)
-		PageTableAllocator::UnpinPageTable(*pPt++,aPinArgs);
+		::PageTables.UnpinPageTable(*pPt++,aPinArgs);
 	MmuLock::Unlock();
 	iNumPinnedPageTables = 0;