--- a/kernel/eka/memmodel/epoc/flexible/mmu/arm/xmmu.cpp Thu Jan 07 13:38:45 2010 +0200
+++ b/kernel/eka/memmodel/epoc/flexible/mmu/arm/xmmu.cpp Mon Jan 18 21:31:10 2010 +0200
@@ -439,7 +439,7 @@
{
// reuse existing functions rather than duplicating the logic
TPde pde = BlankPde(aAttributes);
- TPde pte = BlankPte(aAttributes, aPteType);
+ TPte pte = BlankPte(aAttributes, aPteType);
return PageToSectionEntry(pte, pde);
}
@@ -882,11 +882,13 @@
// Now we have the os asid check access to kernel memory.
if(aAddr >= KUserMemoryLimit && osAsid != (TUint)KKernelOsAsid)
{
+ NKern::ThreadEnterCS();
+ MmuLock::Unlock();
if (!iAliasLinAddr)
{// Close the new reference as RemoveAlias won't do as iAliasLinAddr is not set.
- aProcess->AsyncCloseOsAsid();
+ aProcess->AsyncCloseOsAsid(); // Asynchronous close as this method should be quick.
}
- MmuLock::Unlock();
+ NKern::ThreadLeaveCS();
return KErrBadDescriptor; // prevent access to supervisor only memory
}
@@ -896,13 +898,15 @@
// address is in global section, don't bother aliasing it...
if (!iAliasLinAddr)
{// Close the new reference as not required.
- aProcess->AsyncCloseOsAsid();
+ NKern::ThreadEnterCS();
+ MmuLock::Unlock();
+ aProcess->AsyncCloseOsAsid(); // Asynchronous close as this method should be quick.
+ NKern::ThreadLeaveCS();
}
else
{// Remove the existing alias as it is not required.
- DoRemoveAlias(iAliasLinAddr);
+ DoRemoveAlias(iAliasLinAddr); // Releases mmulock.
}
- MmuLock::Unlock();
aAliasAddr = aAddr;
TInt maxSize = KChunkSize-(aAddr&KChunkMask);
aAliasSize = aSize<maxSize ? aSize : maxSize;
@@ -982,9 +986,7 @@
{
MmuLock::Lock();
- DoRemoveAlias(addr);
-
- MmuLock::Unlock();
+ DoRemoveAlias(addr); // Unlocks mmulock.
}
}
@@ -993,6 +995,7 @@
Remove the alias mapping.
@pre Mmulock held
+@post MmuLock released.
*/
void DMemModelThread::DoRemoveAlias(TLinAddr aAddr)
{
@@ -1011,10 +1014,16 @@
NKern::EndFreezeCpu(iCpuRestoreCookie);
iCpuRestoreCookie = -1;
#endif
- // Must close the os asid while the mmu lock is held to prevent it being
- // leaked, however this requires that it is closed asynchronously as can't
- // delete os asid with mmu lock held.
- iAliasProcess->AsyncCloseOsAsid();
+
+ // Must close the os asid while in critical section to prevent it being
+ // leaked. However, we can't hold the mmu lock so we have to enter an
+ // explict crtical section. It is ok to release the mmu lock as the
+ // iAliasLinAddr and iAliasProcess members are only ever updated by the
+ // current thread.
+ NKern::ThreadEnterCS();
+ MmuLock::Unlock();
+ iAliasProcess->AsyncCloseOsAsid(); // Asynchronous close as this method should be quick.
+ NKern::ThreadLeaveCS();
}