未验证 提交 1f94e113 编写于 作者: J Jan Kotas 提交者: GitHub

Flush instruction cache after thunk pool allocation (#75393)

* Flush instruction cache after thunk pool allocation

Fixes #74710

* More precise ifdef
上级 cb1343da
...@@ -692,6 +692,7 @@ EXTERN_C void * __cdecl _alloca(size_t); ...@@ -692,6 +692,7 @@ EXTERN_C void * __cdecl _alloca(size_t);
REDHAWK_PALIMPORT _Ret_maybenull_ _Post_writable_byte_size_(size) void* REDHAWK_PALAPI PalVirtualAlloc(_In_opt_ void* pAddress, uintptr_t size, uint32_t allocationType, uint32_t protect); REDHAWK_PALIMPORT _Ret_maybenull_ _Post_writable_byte_size_(size) void* REDHAWK_PALAPI PalVirtualAlloc(_In_opt_ void* pAddress, uintptr_t size, uint32_t allocationType, uint32_t protect);
REDHAWK_PALIMPORT UInt32_BOOL REDHAWK_PALAPI PalVirtualFree(_In_ void* pAddress, uintptr_t size, uint32_t freeType); REDHAWK_PALIMPORT UInt32_BOOL REDHAWK_PALAPI PalVirtualFree(_In_ void* pAddress, uintptr_t size, uint32_t freeType);
REDHAWK_PALIMPORT UInt32_BOOL REDHAWK_PALAPI PalVirtualProtect(_In_ void* pAddress, uintptr_t size, uint32_t protect); REDHAWK_PALIMPORT UInt32_BOOL REDHAWK_PALAPI PalVirtualProtect(_In_ void* pAddress, uintptr_t size, uint32_t protect);
REDHAWK_PALIMPORT void PalFlushInstructionCache(_In_ void* pAddress, size_t size);
REDHAWK_PALIMPORT void REDHAWK_PALAPI PalSleep(uint32_t milliseconds); REDHAWK_PALIMPORT void REDHAWK_PALAPI PalSleep(uint32_t milliseconds);
REDHAWK_PALIMPORT UInt32_BOOL REDHAWK_PALAPI PalSwitchToThread(); REDHAWK_PALIMPORT UInt32_BOOL REDHAWK_PALAPI PalSwitchToThread();
REDHAWK_PALIMPORT HANDLE REDHAWK_PALAPI PalCreateEventW(_In_opt_ LPSECURITY_ATTRIBUTES pEventAttributes, UInt32_BOOL manualReset, UInt32_BOOL initialState, _In_opt_z_ LPCWSTR pName); REDHAWK_PALIMPORT HANDLE REDHAWK_PALAPI PalCreateEventW(_In_opt_ LPSECURITY_ATTRIBUTES pEventAttributes, UInt32_BOOL manualReset, UInt32_BOOL initialState, _In_opt_z_ LPCWSTR pName);
......
...@@ -229,6 +229,8 @@ EXTERN_C NATIVEAOT_API void* __cdecl RhAllocateThunksMapping() ...@@ -229,6 +229,8 @@ EXTERN_C NATIVEAOT_API void* __cdecl RhAllocateThunksMapping()
return NULL; return NULL;
} }
PalFlushInstructionCache(pThunksSection, THUNKS_MAP_SIZE);
return pThunksSection; return pThunksSection;
} }
......
...@@ -832,6 +832,33 @@ REDHAWK_PALEXPORT UInt32_BOOL REDHAWK_PALAPI PalVirtualProtect(_In_ void* pAddre ...@@ -832,6 +832,33 @@ REDHAWK_PALEXPORT UInt32_BOOL REDHAWK_PALAPI PalVirtualProtect(_In_ void* pAddre
return mprotect(pPageStart, memSize, unixProtect) == 0; return mprotect(pPageStart, memSize, unixProtect) == 0;
} }
REDHAWK_PALEXPORT void PalFlushInstructionCache(_In_ void* pAddress, size_t size)
{
#if defined(__linux__) && defined(HOST_ARM)
// On Linux/arm (at least on 3.10) we found that there is a problem with __do_cache_op (arch/arm/kernel/traps.c)
// implementing cacheflush syscall. cacheflush flushes only the first page in range [pAddress, pAddress + size)
// and leaves other pages in undefined state which causes random tests failures (often due to SIGSEGV) with no particular pattern.
//
// As a workaround, we call __builtin___clear_cache on each page separately.
const size_t pageSize = getpagesize();
uint8_t* begin = (uint8_t*)pAddress;
uint8_t* end = begin + size;
while (begin < end)
{
uint8_t* endOrNextPageBegin = ALIGN_UP(begin + 1, pageSize);
if (endOrNextPageBegin > end)
endOrNextPageBegin = end;
__builtin___clear_cache((char *)begin, (char *)endOrNextPageBegin);
begin = endOrNextPageBegin;
}
#else
__builtin___clear_cache((char *)pAddress, (char *)pAddress + size);
#endif
}
REDHAWK_PALEXPORT _Ret_maybenull_ void* REDHAWK_PALAPI PalSetWerDataBuffer(_In_ void* pNewBuffer) REDHAWK_PALEXPORT _Ret_maybenull_ void* REDHAWK_PALAPI PalSetWerDataBuffer(_In_ void* pNewBuffer)
{ {
static void* pBuffer; static void* pBuffer;
......
...@@ -599,6 +599,11 @@ REDHAWK_PALEXPORT UInt32_BOOL REDHAWK_PALAPI PalVirtualProtect(_In_ void* pAddre ...@@ -599,6 +599,11 @@ REDHAWK_PALEXPORT UInt32_BOOL REDHAWK_PALAPI PalVirtualProtect(_In_ void* pAddre
return VirtualProtect(pAddress, size, protect, &oldProtect); return VirtualProtect(pAddress, size, protect, &oldProtect);
} }
REDHAWK_PALEXPORT void PalFlushInstructionCache(_In_ void* pAddress, size_t size)
{
FlushInstructionCache(GetCurrentProcess(), pAddress, size);
}
REDHAWK_PALEXPORT _Ret_maybenull_ void* REDHAWK_PALAPI PalSetWerDataBuffer(_In_ void* pNewBuffer) REDHAWK_PALEXPORT _Ret_maybenull_ void* REDHAWK_PALAPI PalSetWerDataBuffer(_In_ void* pNewBuffer)
{ {
static void* pBuffer; static void* pBuffer;
......
...@@ -1668,10 +1668,7 @@ DBG_FlushInstructionCache( ...@@ -1668,10 +1668,7 @@ DBG_FlushInstructionCache(
IN LPCVOID lpBaseAddress, IN LPCVOID lpBaseAddress,
IN SIZE_T dwSize) IN SIZE_T dwSize)
{ {
#ifndef HOST_ARM #if defined(__linux__) && defined(HOST_ARM)
// Intrinsic should do the right thing across all platforms (except Linux arm)
__builtin___clear_cache((char *)lpBaseAddress, (char *)((INT_PTR)lpBaseAddress + dwSize));
#else // HOST_ARM
// On Linux/arm (at least on 3.10) we found that there is a problem with __do_cache_op (arch/arm/kernel/traps.c) // On Linux/arm (at least on 3.10) we found that there is a problem with __do_cache_op (arch/arm/kernel/traps.c)
// implementing cacheflush syscall. cacheflush flushes only the first page in range [lpBaseAddress, lpBaseAddress + dwSize) // implementing cacheflush syscall. cacheflush flushes only the first page in range [lpBaseAddress, lpBaseAddress + dwSize)
// and leaves other pages in undefined state which causes random tests failures (often due to SIGSEGV) with no particular pattern. // and leaves other pages in undefined state which causes random tests failures (often due to SIGSEGV) with no particular pattern.
...@@ -1691,6 +1688,8 @@ DBG_FlushInstructionCache( ...@@ -1691,6 +1688,8 @@ DBG_FlushInstructionCache(
__builtin___clear_cache((char *)begin, (char *)endOrNextPageBegin); __builtin___clear_cache((char *)begin, (char *)endOrNextPageBegin);
begin = endOrNextPageBegin; begin = endOrNextPageBegin;
} }
#endif // HOST_ARM #else
__builtin___clear_cache((char *)lpBaseAddress, (char *)((INT_PTR)lpBaseAddress + dwSize));
#endif
return TRUE; return TRUE;
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册