Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/dotnet/runtime.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>2022-09-12 20:06:37 +0300
committerGitHub <noreply@github.com>2022-09-12 20:06:37 +0300
commitd920ddcc62513d91876ca7883a186cdbd3874718 (patch)
tree2c5e20c94558d787db810a910204df4dc74f095f
parentf9b38e88dbf1489d6b1569bf83bfbea3a8970f56 (diff)
[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>
-rw-r--r--src/coreclr/nativeaot/Runtime/PalRedhawk.h1
-rw-r--r--src/coreclr/nativeaot/Runtime/ThunksMapping.cpp2
-rw-r--r--src/coreclr/nativeaot/Runtime/unix/PalRedhawkUnix.cpp27
-rw-r--r--src/coreclr/nativeaot/Runtime/windows/PalRedhawkMinWin.cpp5
-rw-r--r--src/coreclr/pal/src/thread/context.cpp9
5 files changed, 39 insertions, 5 deletions
diff --git a/src/coreclr/nativeaot/Runtime/PalRedhawk.h b/src/coreclr/nativeaot/Runtime/PalRedhawk.h
index 5e8751f6945..007b3914415 100644
--- a/src/coreclr/nativeaot/Runtime/PalRedhawk.h
+++ b/src/coreclr/nativeaot/Runtime/PalRedhawk.h
@@ -674,6 +674,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);
diff --git a/src/coreclr/nativeaot/Runtime/ThunksMapping.cpp b/src/coreclr/nativeaot/Runtime/ThunksMapping.cpp
index 6fe0e768f15..760dbc3b0ad 100644
--- a/src/coreclr/nativeaot/Runtime/ThunksMapping.cpp
+++ b/src/coreclr/nativeaot/Runtime/ThunksMapping.cpp
@@ -229,6 +229,8 @@ EXTERN_C NATIVEAOT_API void* __cdecl RhAllocateThunksMapping()
return NULL;
}
+ PalFlushInstructionCache(pThunksSection, THUNKS_MAP_SIZE);
+
return pThunksSection;
}
diff --git a/src/coreclr/nativeaot/Runtime/unix/PalRedhawkUnix.cpp b/src/coreclr/nativeaot/Runtime/unix/PalRedhawkUnix.cpp
index f8be025c062..55ad31c82d8 100644
--- a/src/coreclr/nativeaot/Runtime/unix/PalRedhawkUnix.cpp
+++ b/src/coreclr/nativeaot/Runtime/unix/PalRedhawkUnix.cpp
@@ -832,6 +832,33 @@ 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)
+{
+#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)
{
static void* pBuffer;
diff --git a/src/coreclr/nativeaot/Runtime/windows/PalRedhawkMinWin.cpp b/src/coreclr/nativeaot/Runtime/windows/PalRedhawkMinWin.cpp
index 39f8ffd00a0..20238e87501 100644
--- a/src/coreclr/nativeaot/Runtime/windows/PalRedhawkMinWin.cpp
+++ b/src/coreclr/nativeaot/Runtime/windows/PalRedhawkMinWin.cpp
@@ -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;
diff --git a/src/coreclr/pal/src/thread/context.cpp b/src/coreclr/pal/src/thread/context.cpp
index 184116239ca..a9a00bb04a0 100644
--- a/src/coreclr/pal/src/thread/context.cpp
+++ b/src/coreclr/pal/src/thread/context.cpp
@@ -1637,10 +1637,7 @@ DBG_FlushInstructionCache(
IN LPCVOID lpBaseAddress,
IN SIZE_T dwSize)
{
-#ifndef 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
+#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 [lpBaseAddress, lpBaseAddress + dwSize)
// 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(
__builtin___clear_cache((char *)begin, (char *)endOrNextPageBegin);
begin = endOrNextPageBegin;
}
-#endif // HOST_ARM
+#else
+ __builtin___clear_cache((char *)lpBaseAddress, (char *)((INT_PTR)lpBaseAddress + dwSize));
+#endif
return TRUE;
}