kernel/eka/memmodel/epoc/flexible/mmu/mpager.cpp
changeset 259 57b9594f5772
parent 201 43365a9b78a3
equal deleted inserted replaced
247:d8d70de2bd36 259:57b9594f5772
  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