mirror of
https://github.com/xmrig/xmrig.git
synced 2024-11-18 00:37:46 +00:00
Merge pull request #1465 from SChernykh/dev
Fix for 1st-gen Ryzen crashes
This commit is contained in:
commit
6ceb4dfc4f
10 changed files with 102 additions and 9 deletions
|
@ -1,4 +1,5 @@
|
|||
;# save VM register values
|
||||
add rsp, 24
|
||||
pop rcx
|
||||
mov qword ptr [rcx+0], r8
|
||||
mov qword ptr [rcx+8], r9
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
lea rcx, [rsi+rax]
|
||||
push rcx
|
||||
mov [rsp+8], rcx
|
||||
xor r8, qword ptr [rcx+0]
|
||||
xor r9, qword ptr [rcx+8]
|
||||
xor r10, qword ptr [rcx+16]
|
||||
|
@ -9,7 +9,7 @@
|
|||
xor r14, qword ptr [rcx+48]
|
||||
xor r15, qword ptr [rcx+56]
|
||||
lea rcx, [rsi+rdx]
|
||||
push rcx
|
||||
mov [rsp+16], rcx
|
||||
cvtdq2pd xmm0, qword ptr [rcx+0]
|
||||
cvtdq2pd xmm1, qword ptr [rcx+8]
|
||||
cvtdq2pd xmm2, qword ptr [rcx+16]
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
pop rcx
|
||||
mov rcx, [rsp+16]
|
||||
mov qword ptr [rcx+0], r8
|
||||
mov qword ptr [rcx+8], r9
|
||||
mov qword ptr [rcx+16], r10
|
||||
|
@ -7,7 +7,7 @@
|
|||
mov qword ptr [rcx+40], r13
|
||||
mov qword ptr [rcx+48], r14
|
||||
mov qword ptr [rcx+56], r15
|
||||
pop rcx
|
||||
mov rcx, [rsp+8]
|
||||
xorpd xmm0, xmm4
|
||||
xorpd xmm1, xmm5
|
||||
xorpd xmm2, xmm6
|
||||
|
|
|
@ -36,6 +36,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "crypto/randomx/program.hpp"
|
||||
#include "crypto/randomx/reciprocal.h"
|
||||
#include "crypto/randomx/virtual_memory.hpp"
|
||||
#include "crypto/rx/Rx.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# include <intrin.h>
|
||||
|
@ -168,8 +169,8 @@ namespace randomx {
|
|||
static const uint8_t REX_MAXPD[] = { 0x66, 0x41, 0x0f, 0x5f };
|
||||
static const uint8_t REX_DIVPD[] = { 0x66, 0x41, 0x0f, 0x5e };
|
||||
static const uint8_t SQRTPD[] = { 0x66, 0x0f, 0x51 };
|
||||
static const uint8_t AND_OR_MOV_LDMXCSR[] = { 0x25, 0x00, 0x60, 0x00, 0x00, 0x0D, 0xC0, 0x9F, 0x00, 0x00, 0x89, 0x44, 0x24, 0xFC, 0x0F, 0xAE, 0x54, 0x24, 0xFC };
|
||||
static const uint8_t AND_OR_MOV_LDMXCSR_RYZEN[] = { 0x25, 0x00, 0x60, 0x00, 0x00, 0x0D, 0xC0, 0x9F, 0x00, 0x00, 0x3B, 0x44, 0x24, 0xFC, 0x74, 0x09, 0x89, 0x44, 0x24, 0xFC, 0x0F, 0xAE, 0x54, 0x24, 0xFC };
|
||||
static const uint8_t AND_OR_MOV_LDMXCSR[] = { 0x25, 0x00, 0x60, 0x00, 0x00, 0x0D, 0xC0, 0x9F, 0x00, 0x00, 0x89, 0x04, 0x24, 0x0F, 0xAE, 0x14, 0x24 };
|
||||
static const uint8_t AND_OR_MOV_LDMXCSR_RYZEN[] = { 0x25, 0x00, 0x60, 0x00, 0x00, 0x0D, 0xC0, 0x9F, 0x00, 0x00, 0x3B, 0x04, 0x24, 0x74, 0x07, 0x89, 0x04, 0x24, 0x0F, 0xAE, 0x14, 0x24 };
|
||||
static const uint8_t ROL_RAX[] = { 0x48, 0xc1, 0xc0 };
|
||||
static const uint8_t XOR_ECX_ECX[] = { 0x33, 0xC9 };
|
||||
static const uint8_t REX_CMP_R32I[] = { 0x41, 0x81 };
|
||||
|
@ -380,10 +381,12 @@ namespace randomx {
|
|||
*(uint32_t*)(code + codePos + 10) = RandomX_CurrentConfig.ScratchpadL3Mask64_Calculated;
|
||||
*(uint32_t*)(code + codePos + 20) = RandomX_CurrentConfig.ScratchpadL3Mask64_Calculated;
|
||||
if (hasAVX) {
|
||||
uint32_t* p = (uint32_t*)(code + codePos + 29);
|
||||
uint32_t* p = (uint32_t*)(code + codePos + 32);
|
||||
*p = (*p & 0xFF000000U) | 0x0077F8C5U;
|
||||
}
|
||||
|
||||
xmrig::Rx::setMainLoopBounds(code + prologueSize, code + epilogueOffset);
|
||||
|
||||
codePos = prologueSize;
|
||||
memcpy(code + codePos - 48, &pcfg.eMask, sizeof(pcfg.eMask));
|
||||
memcpy(code + codePos, codeLoopLoad, loopLoadSize);
|
||||
|
|
|
@ -93,7 +93,8 @@ DECL(randomx_program_prologue_first_load):
|
|||
and eax, RANDOMX_SCRATCHPAD_MASK
|
||||
ror rdx, 32
|
||||
and edx, RANDOMX_SCRATCHPAD_MASK
|
||||
stmxcsr dword ptr [rsp-20]
|
||||
sub rsp, 24
|
||||
stmxcsr dword ptr [rsp]
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
|
|
|
@ -81,7 +81,8 @@ randomx_program_prologue_first_load PROC
|
|||
and eax, RANDOMX_SCRATCHPAD_MASK
|
||||
ror rdx, 32
|
||||
and edx, RANDOMX_SCRATCHPAD_MASK
|
||||
stmxcsr dword ptr [rsp-20]
|
||||
sub rsp, 24
|
||||
stmxcsr dword ptr [rsp]
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
|
|
|
@ -74,6 +74,7 @@ bool xmrig::Rx::init(const Job &job, const RxConfig &config, const CpuConfig &cp
|
|||
|
||||
if (!osInitialized) {
|
||||
msrInit(config);
|
||||
SetupMainLoopExceptionFrame();
|
||||
osInitialized = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -57,9 +57,20 @@ public:
|
|||
static void destroy();
|
||||
static void init(IRxListener *listener);
|
||||
|
||||
static void setMainLoopBounds(const void* loopBegin, const void* loopEnd)
|
||||
{
|
||||
mainLoopBounds.first = loopBegin;
|
||||
mainLoopBounds.second = loopEnd;
|
||||
}
|
||||
|
||||
static const std::pair<const void*, const void*>& getMainLoopBounds() { return mainLoopBounds; }
|
||||
|
||||
private:
|
||||
static void msrInit(const RxConfig &config);
|
||||
static void msrDestroy();
|
||||
static void SetupMainLoopExceptionFrame();
|
||||
|
||||
static thread_local std::pair<const void*, const void*> mainLoopBounds;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -43,6 +43,8 @@
|
|||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <ucontext.h>
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
@ -178,6 +180,29 @@ static bool wrmsr(const MsrItems &preset, bool save)
|
|||
}
|
||||
|
||||
|
||||
static void MainLoopHandler(int sig, siginfo_t *info, void *ucontext)
|
||||
{
|
||||
# if defined(__x86_64__) || defined(__amd64__)
|
||||
ucontext_t *ucp = (ucontext_t*) ucontext;
|
||||
|
||||
LOG_INFO(YELLOW_BOLD("%s at %p"), (sig == SIGSEGV) ? "SIGSEGV" : "SIGILL", ucp->uc_mcontext.gregs[REG_RIP]);
|
||||
|
||||
void* p = reinterpret_cast<void*>(ucp->uc_mcontext.gregs[REG_RIP]);
|
||||
const std::pair<const void*, const void*>& loopBounds = xmrig::Rx::getMainLoopBounds();
|
||||
|
||||
if ((loopBounds.first <= p) && (p < loopBounds.second)) {
|
||||
ucp->uc_mcontext.gregs[REG_RIP] = reinterpret_cast<size_t>(loopBounds.second);
|
||||
}
|
||||
else {
|
||||
abort();
|
||||
}
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
thread_local std::pair<const void*, const void*> Rx::mainLoopBounds = { nullptr, nullptr };
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
|
@ -208,3 +233,16 @@ void xmrig::Rx::msrDestroy()
|
|||
LOG_ERR(CLEAR "%s" RED_BOLD_S "failed to restore initial state" BLACK_BOLD(" (%" PRIu64 " ms)"), tag, Chrono::steadyMSecs() - ts);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Rx::SetupMainLoopExceptionFrame()
|
||||
{
|
||||
# if defined(__x86_64__) || defined(__amd64__)
|
||||
struct sigaction act = {};
|
||||
act.sa_sigaction = MainLoopHandler;
|
||||
act.sa_flags = SA_RESTART | SA_SIGINFO;
|
||||
sigaction(SIGSEGV, &act, nullptr);
|
||||
sigaction(SIGILL, &act, nullptr);
|
||||
# endif
|
||||
}
|
||||
|
||||
|
|
|
@ -303,6 +303,37 @@ static bool wrmsr(const MsrItems &preset, bool save)
|
|||
}
|
||||
|
||||
|
||||
static LONG WINAPI MainLoopHandler(_EXCEPTION_POINTERS *ExceptionInfo)
|
||||
{
|
||||
if (ExceptionInfo->ExceptionRecord->ExceptionCode == 0xC0000005) {
|
||||
const char* accessType;
|
||||
switch (ExceptionInfo->ExceptionRecord->ExceptionInformation[0]) {
|
||||
case 0: accessType = "read"; break;
|
||||
case 1: accessType = "write"; break;
|
||||
case 8: accessType = "DEP violation"; break;
|
||||
default: accessType = "unknown"; break;
|
||||
}
|
||||
LOG_INFO(YELLOW_BOLD("[THREAD %u] Access violation at 0x%p: %s at address 0x%p"), GetCurrentThreadId(), ExceptionInfo->ExceptionRecord->ExceptionAddress, accessType, ExceptionInfo->ExceptionRecord->ExceptionInformation[1]);
|
||||
}
|
||||
else {
|
||||
LOG_INFO(YELLOW_BOLD("[THREAD %u] Exception 0x%08X at 0x%p"), GetCurrentThreadId(), ExceptionInfo->ExceptionRecord->ExceptionCode, ExceptionInfo->ExceptionRecord->ExceptionAddress);
|
||||
}
|
||||
|
||||
void* p = reinterpret_cast<void*>(ExceptionInfo->ContextRecord->Rip);
|
||||
const std::pair<const void*, const void*>& loopBounds = xmrig::Rx::getMainLoopBounds();
|
||||
|
||||
if ((loopBounds.first <= p) && (p < loopBounds.second)) {
|
||||
ExceptionInfo->ContextRecord->Rip = reinterpret_cast<DWORD64>(loopBounds.second);
|
||||
return EXCEPTION_CONTINUE_EXECUTION;
|
||||
}
|
||||
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
|
||||
thread_local std::pair<const void*, const void*> Rx::mainLoopBounds = { nullptr, nullptr };
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
|
@ -333,3 +364,9 @@ void xmrig::Rx::msrDestroy()
|
|||
LOG_ERR(CLEAR "%s" RED_BOLD_S "failed to restore initial state" BLACK_BOLD(" (%" PRIu64 " ms)"), tag, Chrono::steadyMSecs() - ts);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Rx::SetupMainLoopExceptionFrame()
|
||||
{
|
||||
AddVectoredExceptionHandler(1, MainLoopHandler);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue