Skip to content

Commit d920ddc

Browse files
[release/7.0] Flush instruction cache after thunk pool allocation (#75403)
* Flush instruction cache after thunk pool allocation Fixes #74710 * More precise ifdef Co-authored-by: Jan Kotas <jkotas@microsoft.com>
1 parent f9b38e8 commit d920ddc

File tree

5 files changed

+39
-5
lines changed

5 files changed

+39
-5
lines changed

src/coreclr/nativeaot/Runtime/PalRedhawk.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -674,6 +674,7 @@ EXTERN_C void * __cdecl _alloca(size_t);
674674
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);
675675
REDHAWK_PALIMPORT UInt32_BOOL REDHAWK_PALAPI PalVirtualFree(_In_ void* pAddress, uintptr_t size, uint32_t freeType);
676676
REDHAWK_PALIMPORT UInt32_BOOL REDHAWK_PALAPI PalVirtualProtect(_In_ void* pAddress, uintptr_t size, uint32_t protect);
677+
REDHAWK_PALIMPORT void PalFlushInstructionCache(_In_ void* pAddress, size_t size);
677678
REDHAWK_PALIMPORT void REDHAWK_PALAPI PalSleep(uint32_t milliseconds);
678679
REDHAWK_PALIMPORT UInt32_BOOL REDHAWK_PALAPI PalSwitchToThread();
679680
REDHAWK_PALIMPORT HANDLE REDHAWK_PALAPI PalCreateEventW(_In_opt_ LPSECURITY_ATTRIBUTES pEventAttributes, UInt32_BOOL manualReset, UInt32_BOOL initialState, _In_opt_z_ LPCWSTR pName);

src/coreclr/nativeaot/Runtime/ThunksMapping.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,8 @@ EXTERN_C NATIVEAOT_API void* __cdecl RhAllocateThunksMapping()
229229
return NULL;
230230
}
231231

232+
PalFlushInstructionCache(pThunksSection, THUNKS_MAP_SIZE);
233+
232234
return pThunksSection;
233235
}
234236

src/coreclr/nativeaot/Runtime/unix/PalRedhawkUnix.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -832,6 +832,33 @@ REDHAWK_PALEXPORT UInt32_BOOL REDHAWK_PALAPI PalVirtualProtect(_In_ void* pAddre
832832
return mprotect(pPageStart, memSize, unixProtect) == 0;
833833
}
834834

835+
REDHAWK_PALEXPORT void PalFlushInstructionCache(_In_ void* pAddress, size_t size)
836+
{
837+
#if defined(__linux__) && defined(HOST_ARM)
838+
// On Linux/arm (at least on 3.10) we found that there is a problem with __do_cache_op (arch/arm/kernel/traps.c)
839+
// implementing cacheflush syscall. cacheflush flushes only the first page in range [pAddress, pAddress + size)
840+
// and leaves other pages in undefined state which causes random tests failures (often due to SIGSEGV) with no particular pattern.
841+
//
842+
// As a workaround, we call __builtin___clear_cache on each page separately.
843+
844+
const size_t pageSize = getpagesize();
845+
uint8_t* begin = (uint8_t*)pAddress;
846+
uint8_t* end = begin + size;
847+
848+
while (begin < end)
849+
{
850+
uint8_t* endOrNextPageBegin = ALIGN_UP(begin + 1, pageSize);
851+
if (endOrNextPageBegin > end)
852+
endOrNextPageBegin = end;
853+
854+
__builtin___clear_cache((char *)begin, (char *)endOrNextPageBegin);
855+
begin = endOrNextPageBegin;
856+
}
857+
#else
858+
__builtin___clear_cache((char *)pAddress, (char *)pAddress + size);
859+
#endif
860+
}
861+
835862
REDHAWK_PALEXPORT _Ret_maybenull_ void* REDHAWK_PALAPI PalSetWerDataBuffer(_In_ void* pNewBuffer)
836863
{
837864
static void* pBuffer;

src/coreclr/nativeaot/Runtime/windows/PalRedhawkMinWin.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,11 @@ REDHAWK_PALEXPORT UInt32_BOOL REDHAWK_PALAPI PalVirtualProtect(_In_ void* pAddre
599599
return VirtualProtect(pAddress, size, protect, &oldProtect);
600600
}
601601

602+
REDHAWK_PALEXPORT void PalFlushInstructionCache(_In_ void* pAddress, size_t size)
603+
{
604+
FlushInstructionCache(GetCurrentProcess(), pAddress, size);
605+
}
606+
602607
REDHAWK_PALEXPORT _Ret_maybenull_ void* REDHAWK_PALAPI PalSetWerDataBuffer(_In_ void* pNewBuffer)
603608
{
604609
static void* pBuffer;

src/coreclr/pal/src/thread/context.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1637,10 +1637,7 @@ DBG_FlushInstructionCache(
16371637
IN LPCVOID lpBaseAddress,
16381638
IN SIZE_T dwSize)
16391639
{
1640-
#ifndef HOST_ARM
1641-
// Intrinsic should do the right thing across all platforms (except Linux arm)
1642-
__builtin___clear_cache((char *)lpBaseAddress, (char *)((INT_PTR)lpBaseAddress + dwSize));
1643-
#else // HOST_ARM
1640+
#if defined(__linux__) && defined(HOST_ARM)
16441641
// On Linux/arm (at least on 3.10) we found that there is a problem with __do_cache_op (arch/arm/kernel/traps.c)
16451642
// implementing cacheflush syscall. cacheflush flushes only the first page in range [lpBaseAddress, lpBaseAddress + dwSize)
16461643
// and leaves other pages in undefined state which causes random tests failures (often due to SIGSEGV) with no particular pattern.
@@ -1660,6 +1657,8 @@ DBG_FlushInstructionCache(
16601657
__builtin___clear_cache((char *)begin, (char *)endOrNextPageBegin);
16611658
begin = endOrNextPageBegin;
16621659
}
1663-
#endif // HOST_ARM
1660+
#else
1661+
__builtin___clear_cache((char *)lpBaseAddress, (char *)((INT_PTR)lpBaseAddress + dwSize));
1662+
#endif
16641663
return TRUE;
16651664
}

0 commit comments

Comments
 (0)