570 } |
570 } |
571 |
571 |
572 // Now we have the os asid check access to kernel memory. |
572 // Now we have the os asid check access to kernel memory. |
573 if(aAddr >= KUserMemoryLimit && osAsid != (TUint)KKernelOsAsid) |
573 if(aAddr >= KUserMemoryLimit && osAsid != (TUint)KKernelOsAsid) |
574 { |
574 { |
|
575 NKern::ThreadEnterCS(); |
|
576 MmuLock::Unlock(); |
575 if (!iAliasLinAddr) |
577 if (!iAliasLinAddr) |
576 {// Close the new reference as RemoveAlias won't do as iAliasLinAddr is not set. |
578 {// Close the new reference as RemoveAlias won't do as iAliasLinAddr is not set. |
577 aProcess->AsyncCloseOsAsid(); |
579 aProcess->AsyncCloseOsAsid(); // Asynchronous close as this method should be quick. |
578 } |
580 } |
579 MmuLock::Unlock(); |
581 NKern::ThreadLeaveCS(); |
580 return KErrBadDescriptor; // prevent access to supervisor only memory |
582 return KErrBadDescriptor; // prevent access to supervisor only memory |
581 } |
583 } |
582 |
584 |
583 // Now we know all accesses to global memory are safe so check if aAddr is global. |
585 // Now we know all accesses to global memory are safe so check if aAddr is global. |
584 if(aAddr >= KGlobalMemoryBase) |
586 if(aAddr >= KGlobalMemoryBase) |
585 { |
587 { |
586 // address is in global section, don't bother aliasing it... |
588 // address is in global section, don't bother aliasing it... |
587 if (!iAliasLinAddr) |
589 if (!iAliasLinAddr) |
588 {// Close the new reference as not required. |
590 {// Close the new reference as not required. |
589 aProcess->AsyncCloseOsAsid(); |
591 NKern::ThreadEnterCS(); |
|
592 MmuLock::Unlock(); |
|
593 aProcess->AsyncCloseOsAsid(); // Asynchronous close as this method should be quick. |
|
594 NKern::ThreadLeaveCS(); |
590 } |
595 } |
591 else |
596 else |
592 {// Remove the existing alias as it is not required. |
597 {// Remove the existing alias as it is not required. |
593 DoRemoveAlias(iAliasLinAddr); |
598 DoRemoveAlias(iAliasLinAddr); // Releases mmulock. |
594 } |
599 } |
595 MmuLock::Unlock(); |
|
596 aAliasAddr = aAddr; |
600 aAliasAddr = aAddr; |
597 TInt maxSize = KChunkSize-(aAddr&KChunkMask); |
601 TInt maxSize = KChunkSize-(aAddr&KChunkMask); |
598 aAliasSize = aSize<maxSize ? aSize : maxSize; |
602 aAliasSize = aSize<maxSize ? aSize : maxSize; |
599 TRACE2(("DMemModelThread::Alias() abandoned as memory is globally mapped")); |
603 TRACE2(("DMemModelThread::Alias() abandoned as memory is globally mapped")); |
600 return KErrNone; |
604 return KErrNone; |
690 #ifdef __SMP__ |
692 #ifdef __SMP__ |
691 __NK_ASSERT_DEBUG(iCpuRestoreCookie>=0); |
693 __NK_ASSERT_DEBUG(iCpuRestoreCookie>=0); |
692 NKern::EndFreezeCpu(iCpuRestoreCookie); |
694 NKern::EndFreezeCpu(iCpuRestoreCookie); |
693 iCpuRestoreCookie = -1; |
695 iCpuRestoreCookie = -1; |
694 #endif |
696 #endif |
695 // Must close the os asid while the mmu lock is held to prevent it being |
697 |
696 // leaked, however this requires that it is closed asynchronously as can't |
698 // Must close the os asid while in critical section to prevent it being |
697 // delete os asid with mmu lock held. |
699 // leaked. However, we can't hold the mmu lock so we have to enter an |
698 iAliasProcess->AsyncCloseOsAsid(); |
700 // explict crtical section. It is ok to release the mmu lock as the |
|
701 // iAliasLinAddr and iAliasProcess members are only ever updated by the |
|
702 // current thread. |
|
703 NKern::ThreadEnterCS(); |
|
704 MmuLock::Unlock(); |
|
705 iAliasProcess->AsyncCloseOsAsid(); // Asynchronous close as this method should be quick. |
|
706 NKern::ThreadLeaveCS(); |
699 } |
707 } |
700 |
708 |
701 |
709 |
702 TInt M::DemandPagingFault(TAny* aExceptionInfo) |
710 TInt M::DemandPagingFault(TAny* aExceptionInfo) |
703 { |
711 { |