2042 aCount = 0; |
2042 aCount = 0; |
2043 MmuLock::Unlock(); |
2043 MmuLock::Unlock(); |
2044 } |
2044 } |
2045 |
2045 |
2046 |
2046 |
2047 TInt DPager::CheckRealtimeThreadFault(DThread* aThread, TAny* aExceptionInfo) |
2047 DThread* DPager::ResponsibleThread(DThread* aThread, TAny* aExceptionInfo) |
2048 { |
2048 { |
2049 // realtime threads shouldn't take paging faults... |
|
2050 DThread* client = aThread->iIpcClient; |
2049 DThread* client = aThread->iIpcClient; |
2051 |
2050 |
2052 // If iIpcClient is set then we are accessing the address space of a remote thread. If we are |
2051 // If iIpcClient is set then we are accessing the address space of a remote thread. If we are |
2053 // in an IPC trap, this will contain information the local and remote addresses being accessed. |
2052 // in an IPC trap, this will contain information the local and remote addresses being accessed. |
2054 // If this is not set then we assume than any fault must be the fault of a bad remote address. |
2053 // If this is not set then we assume than any fault must be the fault of a bad remote address. |
2055 TIpcExcTrap* ipcTrap = (TIpcExcTrap*)aThread->iExcTrap; |
2054 TIpcExcTrap* ipcTrap = (TIpcExcTrap*)aThread->iExcTrap; |
2056 if (ipcTrap && !ipcTrap->IsTIpcExcTrap()) |
2055 if (ipcTrap && !ipcTrap->IsTIpcExcTrap()) |
2057 ipcTrap = 0; |
2056 ipcTrap = 0; |
2058 if (client && (!ipcTrap || ipcTrap->ExcLocation(aThread, aExceptionInfo) == TIpcExcTrap::EExcRemote)) |
2057 if (client && |
2059 { |
2058 (!ipcTrap || ipcTrap->ExcLocation(aThread, aExceptionInfo) == TIpcExcTrap::EExcRemote)) |
2060 // kill client thread... |
2059 return client; |
2061 if(K::IllegalFunctionForRealtimeThread(client,"Access to Paged Memory (by other thread)")) |
|
2062 { |
|
2063 // treat memory access as bad... |
|
2064 return KErrAbort; |
|
2065 } |
|
2066 // else thread is in 'warning only' state so allow paging... |
|
2067 } |
|
2068 else |
2060 else |
2069 { |
2061 return NULL; |
2070 // kill current thread... |
2062 } |
2071 if(K::IllegalFunctionForRealtimeThread(NULL,"Access to Paged Memory")) |
2063 |
2072 { |
2064 |
2073 // if current thread is in critical section, then the above kill will be deferred |
2065 TInt DPager::CheckRealtimeThreadFault(DThread* aThread, TAny* aExceptionInfo) |
2074 // and we will continue executing. We will handle this by returning an error |
2066 { |
2075 // which means that the thread will take an exception (which hopefully is XTRAPed!) |
2067 // realtime threads shouldn't take paging faults... |
2076 return KErrAbort; |
2068 DThread* thread = ResponsibleThread(aThread, aExceptionInfo); |
2077 } |
2069 |
2078 // else thread is in 'warning only' state so allow paging... |
2070 const char* message = thread ? |
2079 } |
2071 "Access to Paged Memory (by other thread)" : "Access to Paged Memory"; |
2080 return KErrNone; |
2072 |
|
2073 // kill respsonsible thread... |
|
2074 if(K::IllegalFunctionForRealtimeThread(thread, message)) |
|
2075 { |
|
2076 // if we are killing the current thread and we are in a critical section, then the above |
|
2077 // kill will be deferred and we will continue executing. We will handle this by returning an |
|
2078 // error which means that the thread will take an exception (which hopefully is XTRAPed!) |
|
2079 |
|
2080 // treat memory access as bad... |
|
2081 return KErrAbort; |
|
2082 } |
|
2083 else |
|
2084 { |
|
2085 // thread is in 'warning only' state so allow paging... |
|
2086 return KErrNone; |
|
2087 } |
|
2088 } |
|
2089 |
|
2090 |
|
2091 void DPager::KillResponsibleThread(TPagingErrorContext aContext, TInt aErrorCode, |
|
2092 TAny* aExceptionInfo) |
|
2093 { |
|
2094 const char* message = NULL; |
|
2095 switch (aContext) |
|
2096 { |
|
2097 case EPagingErrorContextRomRead: |
|
2098 message = "PAGED-ROM-READ"; |
|
2099 break; |
|
2100 case EPagingErrorContextRomDecompress: |
|
2101 message = "PAGED-ROM-COMP"; |
|
2102 break; |
|
2103 case EPagingErrorContextCodeRead: |
|
2104 message = "PAGED-CODE-READ"; |
|
2105 break; |
|
2106 case EPagingErrorContextCodeDecompress: |
|
2107 message = "PAGED-CODE-COMP"; |
|
2108 break; |
|
2109 case EPagingErrorContextDataRead: |
|
2110 message = "PAGED-DATA-READ"; |
|
2111 break; |
|
2112 case EPagingErrorContextDataWrite: |
|
2113 message = "PAGED-DATA-WRITE"; |
|
2114 break; |
|
2115 default: |
|
2116 message = "PAGED-UNKNOWN"; |
|
2117 break; |
|
2118 } |
|
2119 |
|
2120 TPtrC8 category((const unsigned char*)message); |
|
2121 DThread* thread = ResponsibleThread(TheCurrentThread, aExceptionInfo); |
|
2122 if (thread) |
|
2123 { |
|
2124 NKern::LockSystem(); |
|
2125 thread->Die(EExitPanic, aErrorCode, category); |
|
2126 } |
|
2127 else |
|
2128 { |
|
2129 TheCurrentThread->SetExitInfo(EExitPanic, aErrorCode, category); |
|
2130 NKern::DeferredExit(); |
|
2131 } |
2081 } |
2132 } |
2082 |
2133 |
2083 |
2134 |
2084 TInt DPager::HandlePageFault( TLinAddr aPc, TLinAddr aFaultAddress, TUint aFaultAsid, TUint aFaultIndex, |
2135 TInt DPager::HandlePageFault( TLinAddr aPc, TLinAddr aFaultAddress, TUint aFaultAsid, TUint aFaultIndex, |
2085 TUint aAccessPermissions, DMemoryObject* aMemory, DMemoryMapping* aMapping, |
2136 TUint aAccessPermissions, DMemoryObject* aMemory, DMemoryMapping* aMapping, |
2101 |
2152 |
2102 DMemoryManager* manager = aMemory->iManager; |
2153 DMemoryManager* manager = aMemory->iManager; |
2103 r = manager->HandleFault(aMemory, aFaultIndex, aMapping, aMapInstanceCount, aAccessPermissions); |
2154 r = manager->HandleFault(aMemory, aFaultIndex, aMapping, aMapInstanceCount, aAccessPermissions); |
2104 |
2155 |
2105 TheThrashMonitor.NotifyEndPaging(); |
2156 TheThrashMonitor.NotifyEndPaging(); |
|
2157 |
|
2158 // If the paging system encountered an error paging in the memory (as opposed to a thread |
|
2159 // accessing non-existent memory), then panic the appropriate thread. Unfortunately this |
|
2160 // situation does occur as media such as eMMC wears out towards the end of its life. |
|
2161 if (r != KErrNone) |
|
2162 { |
|
2163 TPagingErrorContext context = ExtractErrorContext(r); |
|
2164 if (context != EPagingErrorContextNone) |
|
2165 KillResponsibleThread(context, ExtractErrorCode(r), aExceptionInfo); |
|
2166 } |
2106 } |
2167 } |
2107 return r; |
2168 return r; |
2108 } |
2169 } |
2109 |
2170 |
2110 |
2171 |
2642 if(!TheCurrentThread->HasCapability(ECapabilityWriteDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by VMHalFunction(EVMHalSetDataWriteSize)"))) |
2703 if(!TheCurrentThread->HasCapability(ECapabilityWriteDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by VMHalFunction(EVMHalSetDataWriteSize)"))) |
2643 K::UnlockedPlatformSecurityPanic(); |
2704 K::UnlockedPlatformSecurityPanic(); |
2644 if ((K::MemModelAttributes & EMemModelAttrDataPaging) == 0) |
2705 if ((K::MemModelAttributes & EMemModelAttrDataPaging) == 0) |
2645 return KErrNotSupported; |
2706 return KErrNotSupported; |
2646 return SetDataWriteSize((TUint)a1); |
2707 return SetDataWriteSize((TUint)a1); |
2647 |
2708 |
|
2709 #ifdef _DEBUG |
|
2710 case EVMHalDebugSetFail: |
|
2711 { |
|
2712 TUint context = (TUint)a1; |
|
2713 if (context >= EMaxPagingErrorContext) |
|
2714 return KErrArgument; |
|
2715 __e32_atomic_store_ord32(&(ThePager.iDebugFailContext), context); |
|
2716 return KErrNone; |
|
2717 } |
|
2718 #endif |
|
2719 |
2648 default: |
2720 default: |
2649 return KErrNotSupported; |
2721 return KErrNotSupported; |
2650 } |
2722 } |
2651 } |
2723 } |
2652 |
2724 |