diff -r f497542af8e4 -r 538db54a451d kernel/eka/memmodel/epoc/flexible/mmu/arm/xmmu.cpp --- a/kernel/eka/memmodel/epoc/flexible/mmu/arm/xmmu.cpp Tue Jan 19 13:48:03 2010 +0000 +++ 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 = aSizeAsyncCloseOsAsid(); + + // 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(); }