Fix 1st gen AMD Ryzen segfault issue.

XMRig wasn't clearing the cache after codegen, causing this issue due
to a stale instruction cache. Oddly, this issue never occurred on my
1950x, only my 1800x.
This commit is contained in:
Richard Diamond 2019-11-30 19:06:11 -06:00
parent 41e374f0d9
commit 4b617ab7bd
2 changed files with 13 additions and 0 deletions

View file

@ -69,11 +69,19 @@ void *xmrig::VirtualMemory::allocateLargePagesMemory(size_t size)
return mem == MAP_FAILED ? nullptr : mem; return mem == MAP_FAILED ? nullptr : mem;
} }
# ifndef HAVE_BUILTIN_CLEAR_CACHE
// Even though Clang doesn't provide __builtin___clear_cache, compiler-rt,
// which is part of the LLVM project, still defines this function, same as libgcc.
// So calling this should do the same thing as the builtin.
extern "C" void __clear_cache(void* start, void* end);
# endif
void xmrig::VirtualMemory::flushInstructionCache(void *p, size_t size) void xmrig::VirtualMemory::flushInstructionCache(void *p, size_t size)
{ {
# ifdef HAVE_BUILTIN_CLEAR_CACHE # ifdef HAVE_BUILTIN_CLEAR_CACHE
__builtin___clear_cache(reinterpret_cast<char*>(p), reinterpret_cast<char*>(p) + size); __builtin___clear_cache(reinterpret_cast<char*>(p), reinterpret_cast<char*>(p) + size);
# else
__clear_cache(p, (void*)((char*)p + size));
# endif # endif
} }

View file

@ -29,6 +29,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <stdexcept> #include <stdexcept>
#include <cstring> #include <cstring>
#include <climits> #include <climits>
#include "crypto/common/VirtualMemory.h"
#include "crypto/randomx/jit_compiler_x86.hpp" #include "crypto/randomx/jit_compiler_x86.hpp"
#include "crypto/randomx/jit_compiler_x86_static.hpp" #include "crypto/randomx/jit_compiler_x86_static.hpp"
#include "crypto/randomx/superscalar.hpp" #include "crypto/randomx/superscalar.hpp"
@ -218,6 +219,7 @@ namespace randomx {
memcpy(code + codePos, RandomX_CurrentConfig.codeReadDatasetTweaked, readDatasetSize); memcpy(code + codePos, RandomX_CurrentConfig.codeReadDatasetTweaked, readDatasetSize);
codePos += readDatasetSize; codePos += readDatasetSize;
generateProgramEpilogue(prog, pcfg); generateProgramEpilogue(prog, pcfg);
xmrig::VirtualMemory::flushInstructionCache(code, getCodeSize());
} }
void JitCompilerX86::generateProgramLight(Program& prog, ProgramConfiguration& pcfg, uint32_t datasetOffset) { void JitCompilerX86::generateProgramLight(Program& prog, ProgramConfiguration& pcfg, uint32_t datasetOffset) {
@ -229,6 +231,7 @@ namespace randomx {
emit32(superScalarHashOffset - (codePos + 4), code, codePos); emit32(superScalarHashOffset - (codePos + 4), code, codePos);
emit(codeReadDatasetLightSshFin, readDatasetLightFinSize, code, codePos); emit(codeReadDatasetLightSshFin, readDatasetLightFinSize, code, codePos);
generateProgramEpilogue(prog, pcfg); generateProgramEpilogue(prog, pcfg);
xmrig::VirtualMemory::flushInstructionCache(code, getCodeSize());
} }
template<size_t N> template<size_t N>
@ -258,6 +261,7 @@ namespace randomx {
} }
} }
emitByte(RET, code, codePos); emitByte(RET, code, codePos);
xmrig::VirtualMemory::flushInstructionCache(code, getCodeSize());
} }
template template
@ -265,6 +269,7 @@ namespace randomx {
void JitCompilerX86::generateDatasetInitCode() { void JitCompilerX86::generateDatasetInitCode() {
memcpy(code, codeDatasetInit, datasetInitSize); memcpy(code, codeDatasetInit, datasetInitSize);
xmrig::VirtualMemory::flushInstructionCache(code, getCodeSize());
} }
void JitCompilerX86::generateProgramPrologue(Program& prog, ProgramConfiguration& pcfg) { void JitCompilerX86::generateProgramPrologue(Program& prog, ProgramConfiguration& pcfg) {