Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Flush instruction cache after thunk pool allocation #75393

Merged
merged 2 commits into from
Sep 10, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/coreclr/nativeaot/Runtime/PalRedhawk.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 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 void PalFlushInstructionCache(_In_ void* pAddress, size_t size);
REDHAWK_PALIMPORT void REDHAWK_PALAPI PalSleep(uint32_t milliseconds);
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);
Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/nativeaot/Runtime/ThunksMapping.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,8 @@ EXTERN_C NATIVEAOT_API void* __cdecl RhAllocateThunksMapping()
return NULL;
}

PalFlushInstructionCache(pThunksSection, THUNKS_MAP_SIZE);

return pThunksSection;
}

Expand Down
28 changes: 28 additions & 0 deletions src/coreclr/nativeaot/Runtime/unix/PalRedhawkUnix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -832,6 +832,34 @@ REDHAWK_PALEXPORT UInt32_BOOL REDHAWK_PALAPI PalVirtualProtect(_In_ void* pAddre
return mprotect(pPageStart, memSize, unixProtect) == 0;
}

REDHAWK_PALEXPORT void PalFlushInstructionCache(_In_ void* pAddress, size_t size)
{
#ifndef HOST_ARM
jkotas marked this conversation as resolved.
Show resolved Hide resolved
// Intrinsic should do the right thing across all platforms (except Linux arm)
__builtin___clear_cache((char *)pAddress, (char *)pAddress + size);
#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)
// 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;
}
#endif // HOST_ARM
}

REDHAWK_PALEXPORT _Ret_maybenull_ void* REDHAWK_PALAPI PalSetWerDataBuffer(_In_ void* pNewBuffer)
{
static void* pBuffer;
Expand Down
5 changes: 5 additions & 0 deletions src/coreclr/nativeaot/Runtime/windows/PalRedhawkMinWin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -599,6 +599,11 @@ REDHAWK_PALEXPORT UInt32_BOOL REDHAWK_PALAPI PalVirtualProtect(_In_ void* pAddre
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)
{
static void* pBuffer;
Expand Down