diff --git a/cmake/randomx.cmake b/cmake/randomx.cmake index 56c8cc18d..83c8e5b3a 100644 --- a/cmake/randomx.cmake +++ b/cmake/randomx.cmake @@ -100,12 +100,21 @@ if (WITH_RANDOMX) message("-- WITH_MSR=ON") if (XMRIG_OS_WIN) - list(APPEND SOURCES_CRYPTO src/crypto/rx/Rx_win.cpp src/hw/msr/Msr_win.cpp) + list(APPEND SOURCES_CRYPTO + src/crypto/rx/Rx_win.cpp + src/hw/msr/Msr_win.cpp + src/crypto/rx/RxFix_win.cpp + ) elseif (XMRIG_OS_LINUX) - list(APPEND SOURCES_CRYPTO src/crypto/rx/Rx_linux.cpp src/hw/msr/Msr_linux.cpp) + list(APPEND SOURCES_CRYPTO + src/crypto/rx/Rx_linux.cpp + src/hw/msr/Msr_linux.cpp + src/crypto/rx/RxFix_linux.cpp + ) endif() list(APPEND HEADERS_CRYPTO + src/crypto/rx/RxFix.h src/hw/msr/Msr.h src/hw/msr/MsrItem.h ) diff --git a/src/crypto/randomx/jit_compiler_x86.cpp b/src/crypto/randomx/jit_compiler_x86.cpp index 8c3145b2a..17227c34f 100644 --- a/src/crypto/randomx/jit_compiler_x86.cpp +++ b/src/crypto/randomx/jit_compiler_x86.cpp @@ -1,7 +1,7 @@ /* Copyright (c) 2018-2020, tevador -Copyright (c) 2019-2020, SChernykh -Copyright (c) 2019-2020, XMRig , +Copyright (c) 2019-2021, SChernykh +Copyright (c) 2019-2021, XMRig , All rights reserved. @@ -44,7 +44,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "crypto/rx/Profiler.h" #ifdef XMRIG_FIX_RYZEN -# include "crypto/rx/Rx.h" +# include "crypto/rx/RxFix.h" #endif #ifdef _MSC_VER @@ -427,7 +427,7 @@ namespace randomx { } # ifdef XMRIG_FIX_RYZEN - xmrig::Rx::setMainLoopBounds(mainLoopBounds); + xmrig::RxFix::setMainLoopBounds(mainLoopBounds); # endif memcpy(code + prologueSize - 48, &pcfg.eMask, sizeof(pcfg.eMask)); diff --git a/src/crypto/rx/Rx.cpp b/src/crypto/rx/Rx.cpp index 40d3c6129..99ca6b0ad 100644 --- a/src/crypto/rx/Rx.cpp +++ b/src/crypto/rx/Rx.cpp @@ -1,7 +1,7 @@ /* XMRig * Copyright (c) 2018-2019 tevador - * Copyright (c) 2018-2020 SChernykh - * Copyright (c) 2016-2020 XMRig , + * Copyright (c) 2018-2021 SChernykh + * Copyright (c) 2016-2021 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -27,6 +27,11 @@ #include "crypto/randomx/aes_hash.hpp" +#ifdef XMRIG_FIX_RYZEN +# include "crypto/rx/RxFix.h" +#endif + + namespace xmrig { @@ -104,7 +109,10 @@ bool xmrig::Rx::init(const T &seed, const RxConfig &config, const CpuConfig &cpu } if (!osInitialized) { - setupMainLoopExceptionFrame(); +# ifdef XMRIG_FIX_RYZEN + RxFix::setupMainLoopExceptionFrame(); +# endif + if (!cpu.isHwAES()) { SelectSoftAESImpl(cpu.threads().get(seed.algorithm()).count()); } diff --git a/src/crypto/rx/Rx.h b/src/crypto/rx/Rx.h index 42bd0c156..a93f7449f 100644 --- a/src/crypto/rx/Rx.h +++ b/src/crypto/rx/Rx.h @@ -1,7 +1,7 @@ /* XMRig * Copyright (c) 2018-2019 tevador - * Copyright (c) 2018-2020 SChernykh - * Copyright (c) 2016-2020 XMRig , + * Copyright (c) 2018-2021 SChernykh + * Copyright (c) 2016-2021 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -52,10 +52,6 @@ public: template static bool init(const T &seed, const RxConfig &config, const CpuConfig &cpu); template static bool isReady(const T &seed); -# ifdef XMRIG_FIX_RYZEN - static void setMainLoopBounds(const std::pair& bounds); -# endif - # ifdef XMRIG_FEATURE_MSR static bool isMSR(); # else @@ -65,7 +61,6 @@ public: private: static bool msrInit(const RxConfig &config, const std::vector& threads); static void msrDestroy(); - static void setupMainLoopExceptionFrame(); }; diff --git a/src/crypto/rx/RxFix.h b/src/crypto/rx/RxFix.h new file mode 100644 index 000000000..66d2e7d9a --- /dev/null +++ b/src/crypto/rx/RxFix.h @@ -0,0 +1,42 @@ +/* XMRig + * Copyright (c) 2018-2019 tevador + * Copyright (c) 2018-2021 SChernykh + * Copyright (c) 2016-2021 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef XMRIG_RXFIX_H +#define XMRIG_RXFIX_H + + +#include + + +namespace xmrig +{ + + +class RxFix +{ +public: + static void setMainLoopBounds(const std::pair &bounds); + static void setupMainLoopExceptionFrame(); +}; + + +} /* namespace xmrig */ + + +#endif /* XMRIG_RXFIX_H */ diff --git a/src/crypto/rx/RxFix_linux.cpp b/src/crypto/rx/RxFix_linux.cpp new file mode 100644 index 000000000..1a3743c73 --- /dev/null +++ b/src/crypto/rx/RxFix_linux.cpp @@ -0,0 +1,71 @@ +/* XMRig + * Copyright (c) 2018-2019 tevador + * Copyright (c) 2018-2021 SChernykh + * Copyright (c) 2016-2021 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include "crypto/rx/RxFix.h" +#include "base/io/log/Log.h" + + +#include +#include +#include + + +namespace xmrig { + + +static thread_local std::pair mainLoopBounds = { nullptr, nullptr }; + + +static void MainLoopHandler(int sig, siginfo_t *info, void *ucontext) +{ + ucontext_t *ucp = (ucontext_t*) ucontext; + + LOG_VERBOSE(YELLOW_BOLD("%s at %p"), (sig == SIGSEGV) ? "SIGSEGV" : "SIGILL", ucp->uc_mcontext.gregs[REG_RIP]); + + void* p = reinterpret_cast(ucp->uc_mcontext.gregs[REG_RIP]); + const std::pair& loopBounds = mainLoopBounds; + + if ((loopBounds.first <= p) && (p < loopBounds.second)) { + ucp->uc_mcontext.gregs[REG_RIP] = reinterpret_cast(loopBounds.second); + } + else { + abort(); + } +} + + +} // namespace xmrig + + + +void xmrig::RxFix::setMainLoopBounds(const std::pair &bounds) +{ + mainLoopBounds = bounds; +} + + +void xmrig::RxFix::setupMainLoopExceptionFrame() +{ + struct sigaction act = {}; + act.sa_sigaction = MainLoopHandler; + act.sa_flags = SA_RESTART | SA_SIGINFO; + sigaction(SIGSEGV, &act, nullptr); + sigaction(SIGILL, &act, nullptr); +} diff --git a/src/crypto/rx/RxFix_win.cpp b/src/crypto/rx/RxFix_win.cpp new file mode 100644 index 000000000..75538be4d --- /dev/null +++ b/src/crypto/rx/RxFix_win.cpp @@ -0,0 +1,74 @@ +/* XMRig + * Copyright (c) 2018-2019 tevador + * Copyright (c) 2018-2021 SChernykh + * Copyright (c) 2016-2021 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include "crypto/rx/RxFix.h" +#include "base/io/log/Log.h" + + +#include + + +namespace xmrig { + + +static thread_local std::pair mainLoopBounds = { nullptr, nullptr }; + + +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_VERBOSE(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_VERBOSE(YELLOW_BOLD("[THREAD %u] Exception 0x%08X at 0x%p"), GetCurrentThreadId(), ExceptionInfo->ExceptionRecord->ExceptionCode, ExceptionInfo->ExceptionRecord->ExceptionAddress); + } + + void* p = reinterpret_cast(ExceptionInfo->ContextRecord->Rip); + const std::pair& loopBounds = mainLoopBounds; + + if ((loopBounds.first <= p) && (p < loopBounds.second)) { + ExceptionInfo->ContextRecord->Rip = reinterpret_cast(loopBounds.second); + return EXCEPTION_CONTINUE_EXECUTION; + } + + return EXCEPTION_CONTINUE_SEARCH; +} + + +} // namespace xmrig + + +void xmrig::RxFix::setMainLoopBounds(const std::pair &bounds) +{ + mainLoopBounds = bounds; +} + + +void xmrig::RxFix::setupMainLoopExceptionFrame() +{ + AddVectoredExceptionHandler(1, MainLoopHandler); +} diff --git a/src/crypto/rx/Rx_linux.cpp b/src/crypto/rx/Rx_linux.cpp index 6228825b6..e73980026 100644 --- a/src/crypto/rx/Rx_linux.cpp +++ b/src/crypto/rx/Rx_linux.cpp @@ -37,8 +37,6 @@ #include #include #include -#include -#include namespace xmrig { @@ -235,33 +233,6 @@ static bool wrmsr(const MsrItems& preset, const std::vector& threads, } -#ifdef XMRIG_FIX_RYZEN -static thread_local std::pair mainLoopBounds = { nullptr, nullptr }; - -static void MainLoopHandler(int sig, siginfo_t *info, void *ucontext) -{ - ucontext_t *ucp = (ucontext_t*) ucontext; - - LOG_VERBOSE(YELLOW_BOLD("%s at %p"), (sig == SIGSEGV) ? "SIGSEGV" : "SIGILL", ucp->uc_mcontext.gregs[REG_RIP]); - - void* p = reinterpret_cast(ucp->uc_mcontext.gregs[REG_RIP]); - const std::pair& loopBounds = mainLoopBounds; - - if ((loopBounds.first <= p) && (p < loopBounds.second)) { - ucp->uc_mcontext.gregs[REG_RIP] = reinterpret_cast(loopBounds.second); - } - else { - abort(); - } -} - -void Rx::setMainLoopBounds(const std::pair& bounds) -{ - mainLoopBounds = bounds; -} -#endif - - } // namespace xmrig @@ -299,15 +270,3 @@ 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() -{ -# ifdef XMRIG_FIX_RYZEN - struct sigaction act = {}; - act.sa_sigaction = MainLoopHandler; - act.sa_flags = SA_RESTART | SA_SIGINFO; - sigaction(SIGSEGV, &act, nullptr); - sigaction(SIGILL, &act, nullptr); -# endif -} diff --git a/src/crypto/rx/Rx_win.cpp b/src/crypto/rx/Rx_win.cpp index d131822f7..36e13819b 100644 --- a/src/crypto/rx/Rx_win.cpp +++ b/src/crypto/rx/Rx_win.cpp @@ -348,43 +348,6 @@ static bool wrmsr(const MsrItems &preset, const std::vector& threads, } -#ifdef XMRIG_FIX_RYZEN -static thread_local std::pair mainLoopBounds = { nullptr, nullptr }; - -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_VERBOSE(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_VERBOSE(YELLOW_BOLD("[THREAD %u] Exception 0x%08X at 0x%p"), GetCurrentThreadId(), ExceptionInfo->ExceptionRecord->ExceptionCode, ExceptionInfo->ExceptionRecord->ExceptionAddress); - } - - void* p = reinterpret_cast(ExceptionInfo->ContextRecord->Rip); - const std::pair& loopBounds = mainLoopBounds; - - if ((loopBounds.first <= p) && (p < loopBounds.second)) { - ExceptionInfo->ContextRecord->Rip = reinterpret_cast(loopBounds.second); - return EXCEPTION_CONTINUE_EXECUTION; - } - - return EXCEPTION_CONTINUE_SEARCH; -} - -void Rx::setMainLoopBounds(const std::pair& bounds) -{ - mainLoopBounds = bounds; -} -#endif - - } // namespace xmrig @@ -421,11 +384,3 @@ 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() -{ -# ifdef XMRIG_FIX_RYZEN - AddVectoredExceptionHandler(1, MainLoopHandler); -# endif -}