This commit is contained in:
commit
b4c93b7ff6
97 changed files with 6697 additions and 6013 deletions
|
@ -111,6 +111,7 @@ public:
|
|||
|
||||
# ifdef XMRIG_ALGO_CN_PICO
|
||||
case Algorithm::CN_PICO_0:
|
||||
case Algorithm::CN_PICO_TLO:
|
||||
return CN_ITER / 8;
|
||||
# endif
|
||||
|
||||
|
@ -171,6 +172,7 @@ public:
|
|||
case Algorithm::CN_DOUBLE:
|
||||
# ifdef XMRIG_ALGO_CN_PICO
|
||||
case Algorithm::CN_PICO_0:
|
||||
case Algorithm::CN_PICO_TLO:
|
||||
# endif
|
||||
return Algorithm::CN_2;
|
||||
|
||||
|
@ -217,6 +219,7 @@ template<> constexpr inline uint32_t CnAlgo<Algorithm::CN_RWZ>::iterations() con
|
|||
template<> constexpr inline uint32_t CnAlgo<Algorithm::CN_ZLS>::iterations() const { return 0x60000; }
|
||||
template<> constexpr inline uint32_t CnAlgo<Algorithm::CN_GPU>::iterations() const { return 0xC000; }
|
||||
template<> constexpr inline uint32_t CnAlgo<Algorithm::CN_PICO_0>::iterations() const { return CN_ITER / 8; }
|
||||
template<> constexpr inline uint32_t CnAlgo<Algorithm::CN_PICO_TLO>::iterations() const { return CN_ITER / 8; }
|
||||
|
||||
|
||||
template<> constexpr inline size_t CnAlgo<Algorithm::CN_LITE_0>::memory() const { return CN_MEMORY / 2; }
|
||||
|
@ -225,6 +228,7 @@ template<> constexpr inline size_t CnAlgo<Algorithm::CN_HEAVY_0>::memory() const
|
|||
template<> constexpr inline size_t CnAlgo<Algorithm::CN_HEAVY_TUBE>::memory() const { return CN_MEMORY * 2; }
|
||||
template<> constexpr inline size_t CnAlgo<Algorithm::CN_HEAVY_XHV>::memory() const { return CN_MEMORY * 2; }
|
||||
template<> constexpr inline size_t CnAlgo<Algorithm::CN_PICO_0>::memory() const { return CN_MEMORY / 8; }
|
||||
template<> constexpr inline size_t CnAlgo<Algorithm::CN_PICO_TLO>::memory() const { return CN_MEMORY / 8; }
|
||||
|
||||
|
||||
template<> constexpr inline uint32_t CnAlgo<Algorithm::CN_GPU>::mask() const { return 0x1FFFC0; }
|
||||
|
|
|
@ -79,6 +79,11 @@ cn_mainloop_fun cn_trtl_mainloop_ryzen_asm = nullptr;
|
|||
cn_mainloop_fun cn_trtl_mainloop_bulldozer_asm = nullptr;
|
||||
cn_mainloop_fun cn_trtl_double_mainloop_sandybridge_asm = nullptr;
|
||||
|
||||
cn_mainloop_fun cn_tlo_mainloop_ivybridge_asm = nullptr;
|
||||
cn_mainloop_fun cn_tlo_mainloop_ryzen_asm = nullptr;
|
||||
cn_mainloop_fun cn_tlo_mainloop_bulldozer_asm = nullptr;
|
||||
cn_mainloop_fun cn_tlo_double_mainloop_sandybridge_asm = nullptr;
|
||||
|
||||
cn_mainloop_fun cn_zls_mainloop_ivybridge_asm = nullptr;
|
||||
cn_mainloop_fun cn_zls_mainloop_ryzen_asm = nullptr;
|
||||
cn_mainloop_fun cn_zls_mainloop_bulldozer_asm = nullptr;
|
||||
|
@ -128,7 +133,7 @@ static void patchCode(T dst, U src, const uint32_t iterations, const uint32_t ma
|
|||
|
||||
static void patchAsmVariants()
|
||||
{
|
||||
const int allocation_size = 65536;
|
||||
const int allocation_size = 81920;
|
||||
auto base = static_cast<uint8_t *>(VirtualMemory::allocateExecutableMemory(allocation_size));
|
||||
|
||||
cn_half_mainloop_ivybridge_asm = reinterpret_cast<cn_mainloop_fun> (base + 0x0000);
|
||||
|
@ -153,6 +158,13 @@ static void patchAsmVariants()
|
|||
cn_double_mainloop_bulldozer_asm = reinterpret_cast<cn_mainloop_fun> (base + 0xE000);
|
||||
cn_double_double_mainloop_sandybridge_asm = reinterpret_cast<cn_mainloop_fun> (base + 0xF000);
|
||||
|
||||
# ifdef XMRIG_ALGO_CN_PICO
|
||||
cn_tlo_mainloop_ivybridge_asm = reinterpret_cast<cn_mainloop_fun> (base + 0x10000);
|
||||
cn_tlo_mainloop_ryzen_asm = reinterpret_cast<cn_mainloop_fun> (base + 0x11000);
|
||||
cn_tlo_mainloop_bulldozer_asm = reinterpret_cast<cn_mainloop_fun> (base + 0x12000);
|
||||
cn_tlo_double_mainloop_sandybridge_asm = reinterpret_cast<cn_mainloop_fun> (base + 0x13000);
|
||||
# endif
|
||||
|
||||
{
|
||||
constexpr uint32_t ITER = CnAlgo<Algorithm::CN_HALF>().iterations();
|
||||
|
||||
|
@ -172,6 +184,16 @@ static void patchAsmVariants()
|
|||
patchCode(cn_trtl_mainloop_bulldozer_asm, cnv2_mainloop_bulldozer_asm, ITER, MASK);
|
||||
patchCode(cn_trtl_double_mainloop_sandybridge_asm, cnv2_double_mainloop_sandybridge_asm, ITER, MASK);
|
||||
}
|
||||
|
||||
{
|
||||
constexpr uint32_t ITER = CnAlgo<Algorithm::CN_PICO_TLO>().iterations();
|
||||
constexpr uint32_t MASK = CnAlgo<Algorithm::CN_PICO_TLO>().mask();
|
||||
|
||||
patchCode(cn_tlo_mainloop_ivybridge_asm, cnv2_mainloop_ivybridge_asm, ITER, MASK);
|
||||
patchCode(cn_tlo_mainloop_ryzen_asm, cnv2_mainloop_ryzen_asm, ITER, MASK);
|
||||
patchCode(cn_tlo_mainloop_bulldozer_asm, cnv2_mainloop_bulldozer_asm, ITER, MASK);
|
||||
patchCode(cn_tlo_double_mainloop_sandybridge_asm, cnv2_double_mainloop_sandybridge_asm, ITER, MASK);
|
||||
}
|
||||
# endif
|
||||
|
||||
{
|
||||
|
@ -244,6 +266,8 @@ xmrig::CnHash::CnHash()
|
|||
# ifdef XMRIG_ALGO_CN_PICO
|
||||
ADD_FN(Algorithm::CN_PICO_0);
|
||||
ADD_FN_ASM(Algorithm::CN_PICO_0);
|
||||
ADD_FN(Algorithm::CN_PICO_TLO);
|
||||
ADD_FN_ASM(Algorithm::CN_PICO_TLO);
|
||||
# endif
|
||||
|
||||
# ifdef XMRIG_ALGO_ARGON2
|
||||
|
|
|
@ -338,6 +338,21 @@ const static uint8_t test_output_pico_trtl[160] = {
|
|||
0xA1, 0xE7, 0x53, 0x85, 0xFB, 0x72, 0xDD, 0x75, 0x90, 0x39, 0xB2, 0x3D, 0xC3, 0x08, 0x2C, 0xD5,
|
||||
0x01, 0x08, 0x27, 0x75, 0x86, 0xB9, 0xBB, 0x9B, 0xDF, 0xEA, 0x49, 0xDE, 0x46, 0xCB, 0x83, 0x45
|
||||
};
|
||||
|
||||
|
||||
// "cn-pico/tlo"
|
||||
const static uint8_t test_output_pico_tlo[160] = {
|
||||
0x99, 0x75, 0xF2, 0xC1, 0xB3, 0xB4, 0x54, 0x34, 0xA4, 0x93, 0x86, 0x21, 0x30, 0x97, 0xF3, 0x1B,
|
||||
0xB4, 0xB9, 0xA6, 0x58, 0x6A, 0x7E, 0x81, 0xF4, 0x42, 0x9F, 0x6D, 0x5F, 0x65, 0xC3, 0x8D, 0x1A,
|
||||
0xFC, 0x67, 0xDF, 0xCC, 0xB5, 0xFC, 0x90, 0xD7, 0x85, 0x5A, 0xE9, 0x03, 0x36, 0x1E, 0xAB, 0xD7,
|
||||
0x6F, 0x1E, 0x40, 0xA2, 0x2A, 0x72, 0xAD, 0x3E, 0xF2, 0xD6, 0xAD, 0x27, 0xB5, 0xA6, 0x0C, 0xE5,
|
||||
0x1C, 0xB1, 0x53, 0xE9, 0x70, 0x7D, 0x69, 0xF1, 0xE1, 0x55, 0x28, 0x45, 0xF5, 0x76, 0x56, 0xE5,
|
||||
0x10, 0x0D, 0xEA, 0xFD, 0xD9, 0xD6, 0xAF, 0x0F, 0x47, 0x0C, 0x0D, 0xA2, 0x10, 0x16, 0x43, 0xEE,
|
||||
0x25, 0x2C, 0x07, 0x3A, 0x64, 0x29, 0x16, 0xFF, 0xF5, 0xA5, 0x0B, 0xA2, 0xE0, 0xBD, 0xDC, 0xCE,
|
||||
0x93, 0x3F, 0xEF, 0x6B, 0x08, 0xF4, 0x4D, 0x6A, 0x6E, 0x14, 0x13, 0x10, 0x98, 0x11, 0xE1, 0x13,
|
||||
0xF6, 0x9D, 0x3D, 0x31, 0xC4, 0x3A, 0xA9, 0x44, 0x4C, 0x38, 0xAB, 0xB5, 0x4B, 0xD9, 0xFB, 0xE6,
|
||||
0x98, 0xB9, 0x46, 0xE2, 0x00, 0xEB, 0x56, 0x33, 0x1E, 0xBC, 0xEB, 0xF1, 0xF6, 0x88, 0xD3, 0xF0
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -794,6 +794,11 @@ extern cn_mainloop_fun cn_trtl_mainloop_ryzen_asm;
|
|||
extern cn_mainloop_fun cn_trtl_mainloop_bulldozer_asm;
|
||||
extern cn_mainloop_fun cn_trtl_double_mainloop_sandybridge_asm;
|
||||
|
||||
extern cn_mainloop_fun cn_tlo_mainloop_ivybridge_asm;
|
||||
extern cn_mainloop_fun cn_tlo_mainloop_ryzen_asm;
|
||||
extern cn_mainloop_fun cn_tlo_mainloop_bulldozer_asm;
|
||||
extern cn_mainloop_fun cn_tlo_double_mainloop_sandybridge_asm;
|
||||
|
||||
extern cn_mainloop_fun cn_zls_mainloop_ivybridge_asm;
|
||||
extern cn_mainloop_fun cn_zls_mainloop_ryzen_asm;
|
||||
extern cn_mainloop_fun cn_zls_mainloop_bulldozer_asm;
|
||||
|
@ -879,6 +884,17 @@ inline void cryptonight_single_hash_asm(const uint8_t *__restrict__ input, size_
|
|||
cn_trtl_mainloop_bulldozer_asm(ctx);
|
||||
}
|
||||
}
|
||||
else if (ALGO == Algorithm::CN_PICO_TLO) {
|
||||
if (ASM == Assembly::INTEL) {
|
||||
cn_tlo_mainloop_ivybridge_asm(ctx);
|
||||
}
|
||||
else if (ASM == Assembly::RYZEN) {
|
||||
cn_tlo_mainloop_ryzen_asm(ctx);
|
||||
}
|
||||
else {
|
||||
cn_tlo_mainloop_bulldozer_asm(ctx);
|
||||
}
|
||||
}
|
||||
# endif
|
||||
else if (ALGO == Algorithm::CN_RWZ) {
|
||||
cnv2_rwz_mainloop_asm(ctx);
|
||||
|
@ -944,6 +960,9 @@ inline void cryptonight_double_hash_asm(const uint8_t *__restrict__ input, size_
|
|||
else if (ALGO == Algorithm::CN_PICO_0) {
|
||||
cn_trtl_double_mainloop_sandybridge_asm(ctx);
|
||||
}
|
||||
else if (ALGO == Algorithm::CN_PICO_TLO) {
|
||||
cn_tlo_double_mainloop_sandybridge_asm(ctx);
|
||||
}
|
||||
# endif
|
||||
else if (ALGO == Algorithm::CN_RWZ) {
|
||||
cnv2_rwz_double_mainloop_asm(ctx);
|
||||
|
|
|
@ -101,6 +101,10 @@ static AlgoName const algorithm_names[] = {
|
|||
{ "cryptonight-turtle", "cn-trtl", Algorithm::CN_PICO_0 },
|
||||
{ "cryptonight-ultralite", "cn-ultralite", Algorithm::CN_PICO_0 },
|
||||
{ "cryptonight_turtle", "cn_turtle", Algorithm::CN_PICO_0 },
|
||||
{ "cryptonight-pico/tlo", "cn-pico/tlo", Algorithm::CN_PICO_TLO },
|
||||
{ "cryptonight/ultra", "cn/ultra", Algorithm::CN_PICO_TLO },
|
||||
{ "cryptonight-talleo", "cn-talleo", Algorithm::CN_PICO_TLO },
|
||||
{ "cryptonight_talleo", "cn_talleo", Algorithm::CN_PICO_TLO },
|
||||
# endif
|
||||
# ifdef XMRIG_ALGO_RANDOMX
|
||||
{ "randomx/0", "rx/0", Algorithm::RX_0 },
|
||||
|
@ -115,8 +119,6 @@ static AlgoName const algorithm_names[] = {
|
|||
{ "RandomARQ", nullptr, Algorithm::RX_ARQ },
|
||||
{ "randomx/sfx", "rx/sfx", Algorithm::RX_SFX },
|
||||
{ "RandomSFX", nullptr, Algorithm::RX_SFX },
|
||||
{ "randomx/v", "rx/v", Algorithm::RX_V },
|
||||
{ "RandomV", nullptr, Algorithm::RX_V },
|
||||
# endif
|
||||
# ifdef XMRIG_ALGO_ARGON2
|
||||
{ "argon2/chukwa", nullptr, Algorithm::AR2_CHUKWA },
|
||||
|
@ -144,7 +146,6 @@ size_t xmrig::Algorithm::l2() const
|
|||
case RX_0:
|
||||
case RX_LOKI:
|
||||
case RX_SFX:
|
||||
case RX_V:
|
||||
return 0x40000;
|
||||
|
||||
case RX_WOW:
|
||||
|
@ -184,7 +185,6 @@ size_t xmrig::Algorithm::l3() const
|
|||
case RX_0:
|
||||
case RX_LOKI:
|
||||
case RX_SFX:
|
||||
case RX_V:
|
||||
return oneMiB * 2;
|
||||
|
||||
case RX_WOW:
|
||||
|
@ -279,6 +279,7 @@ xmrig::Algorithm::Family xmrig::Algorithm::family(Id id)
|
|||
|
||||
# ifdef XMRIG_ALGO_CN_PICO
|
||||
case CN_PICO_0:
|
||||
case CN_PICO_TLO:
|
||||
return CN_PICO;
|
||||
# endif
|
||||
|
||||
|
@ -289,7 +290,6 @@ xmrig::Algorithm::Family xmrig::Algorithm::family(Id id)
|
|||
case DEFYX:
|
||||
case RX_ARQ:
|
||||
case RX_SFX:
|
||||
case RX_V:
|
||||
return RANDOM_X;
|
||||
# endif
|
||||
|
||||
|
|
|
@ -62,14 +62,14 @@ public:
|
|||
CN_HEAVY_0, // "cn-heavy/0" CryptoNight-Heavy (4 MB).
|
||||
CN_HEAVY_TUBE, // "cn-heavy/tube" CryptoNight-Heavy (modified, TUBE only).
|
||||
CN_HEAVY_XHV, // "cn-heavy/xhv" CryptoNight-Heavy (modified, Haven Protocol only).
|
||||
CN_PICO_0, // "cn-pico" CryptoNight Turtle (TRTL)
|
||||
CN_PICO_0, // "cn-pico" CryptoNight-Pico
|
||||
CN_PICO_TLO, // "cn-pico/tlo" CryptoNight-Pico (TLO)
|
||||
RX_0, // "rx/0" RandomX (reference configuration).
|
||||
RX_WOW, // "rx/wow" RandomWOW (Wownero).
|
||||
RX_LOKI, // "rx/loki" RandomXL (Loki).
|
||||
DEFYX, // "defyx" DefyX (Scala).
|
||||
RX_ARQ, // "rx/arq" RandomARQ (Arqma).
|
||||
RX_SFX, // "rx/sfx" RandomSFX (Safex Cash).
|
||||
RX_V, // "rx/v" RandomV (Monerov).
|
||||
AR2_CHUKWA, // "argon2/chukwa" Argon2id (Chukwa).
|
||||
AR2_WRKZ, // "argon2/wrkz" Argon2id (WRKZ)
|
||||
MAX
|
||||
|
|
|
@ -6,9 +6,9 @@
|
|||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2018-2019 tevador <tevador@gmail.com>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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
|
||||
|
@ -46,9 +46,6 @@ namespace xmrig {
|
|||
static IMemoryPool *pool = nullptr;
|
||||
static std::mutex mutex;
|
||||
|
||||
constexpr size_t twoMiB = 2U * 1024U * 1024U;
|
||||
constexpr size_t oneGiB = 1024U * 1024U * 1024U;
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
|
|
|
@ -6,9 +6,9 @@
|
|||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2018-2019 tevador <tevador@gmail.com>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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
|
||||
|
|
|
@ -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 };
|
||||
|
@ -299,6 +300,10 @@ namespace randomx {
|
|||
code = allocatedCode + (codeOffset.fetch_add(59 * 64) % CodeSize);
|
||||
memcpy(code, codePrologue, prologueSize);
|
||||
memcpy(code + epilogueOffset, codeEpilogue, epilogueSize);
|
||||
# ifdef XMRIG_FIX_RYZEN
|
||||
mainLoopBounds.first = code + prologueSize;
|
||||
mainLoopBounds.second = code + epilogueOffset;
|
||||
# endif
|
||||
}
|
||||
|
||||
JitCompilerX86::~JitCompilerX86() {
|
||||
|
@ -380,10 +385,14 @@ 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;
|
||||
}
|
||||
|
||||
# ifdef XMRIG_FIX_RYZEN
|
||||
xmrig::Rx::setMainLoopBounds(mainLoopBounds);
|
||||
# endif
|
||||
|
||||
codePos = prologueSize;
|
||||
memcpy(code + codePos - 48, &pcfg.eMask, sizeof(pcfg.eMask));
|
||||
memcpy(code + codePos, codeLoopLoad, loopLoadSize);
|
||||
|
@ -398,9 +407,10 @@ namespace randomx {
|
|||
}
|
||||
|
||||
for (int i = 0, n = static_cast<int>(RandomX_CurrentConfig.ProgramSize); i < n; ++i) {
|
||||
Instruction instr = prog(i);
|
||||
Instruction& instr = prog(i);
|
||||
const uint8_t opcode = instr.opcode;
|
||||
*((uint64_t*)&instr) &= (uint64_t(-1) - (0xFFFF << 8)) | ((RegistersCount - 1) << 8) | ((RegistersCount - 1) << 16);
|
||||
(this->*(engine[instr.opcode]))(instr);
|
||||
(this->*(engine[opcode]))(instr);
|
||||
}
|
||||
|
||||
emit(REX_MOV_RR, code, codePos);
|
||||
|
@ -596,32 +606,22 @@ namespace randomx {
|
|||
codePos = pos;
|
||||
}
|
||||
|
||||
static const uint32_t template_IADD_M[8] = {
|
||||
0x0604034c,
|
||||
0x060c034c,
|
||||
0x0614034c,
|
||||
0x061c034c,
|
||||
0x0624034c,
|
||||
0x062c034c,
|
||||
0x0634034c,
|
||||
0x063c034c,
|
||||
};
|
||||
|
||||
void JitCompilerX86::h_IADD_M(const Instruction& instr) {
|
||||
uint8_t* const p = code;
|
||||
int pos = codePos;
|
||||
|
||||
if (instr.src != instr.dst) {
|
||||
const uint32_t dst = instr.dst;
|
||||
if (instr.src != dst) {
|
||||
genAddressReg<true>(instr, p, pos);
|
||||
emit32(template_IADD_M[instr.dst], p, pos);
|
||||
emit32(0x0604034c + (dst << 19), p, pos);
|
||||
}
|
||||
else {
|
||||
emit(REX_ADD_RM, p, pos);
|
||||
emitByte(0x86 + 8 * instr.dst, p, pos);
|
||||
emitByte(0x86 + (dst << 3), p, pos);
|
||||
genAddressImm(instr, p, pos);
|
||||
}
|
||||
|
||||
registerUsage[instr.dst] = pos;
|
||||
registerUsage[dst] = pos;
|
||||
codePos = pos;
|
||||
}
|
||||
|
||||
|
@ -651,19 +651,18 @@ namespace randomx {
|
|||
uint8_t* const p = code;
|
||||
int pos = codePos;
|
||||
|
||||
if (instr.src != instr.dst) {
|
||||
const uint32_t dst = instr.dst;
|
||||
if (instr.src != dst) {
|
||||
genAddressReg<true>(instr, p, pos);
|
||||
emit(REX_SUB_RM, p, pos);
|
||||
emitByte(0x04 + 8 * instr.dst, p, pos);
|
||||
emitByte(0x06, p, pos);
|
||||
emit32(0x06042b4c + (dst << 19), p, pos);
|
||||
}
|
||||
else {
|
||||
emit(REX_SUB_RM, p, pos);
|
||||
emitByte(0x86 + 8 * instr.dst, p, pos);
|
||||
emitByte(0x86 + (dst << 3), p, pos);
|
||||
genAddressImm(instr, p, pos);
|
||||
}
|
||||
|
||||
registerUsage[instr.dst] = pos;
|
||||
registerUsage[dst] = pos;
|
||||
codePos = pos;
|
||||
}
|
||||
|
||||
|
@ -1051,14 +1050,12 @@ namespace randomx {
|
|||
}
|
||||
}
|
||||
|
||||
emit(REX_ADD_I, p, pos);
|
||||
emitByte(0xc0 + reg, p, pos);
|
||||
*(uint32_t*)(p + pos) = 0x00c08149 + (reg << 16);
|
||||
const int shift = instr.getModCond() + RandomX_CurrentConfig.JumpOffset;
|
||||
const uint32_t imm = (instr.getImm32() | (1UL << shift)) & ~(1UL << (shift - 1));
|
||||
emit32(imm, p, pos);
|
||||
emit(REX_TEST, p, pos);
|
||||
emitByte(0xc0 + reg, p, pos);
|
||||
emit32(RandomX_CurrentConfig.ConditionMask_Calculated << shift, p, pos);
|
||||
*(uint32_t*)(p + pos + 3) = (instr.getImm32() | (1UL << shift)) & ~(1UL << (shift - 1));
|
||||
*(uint32_t*)(p + pos + 7) = 0x00c0f749 + (reg << 16);
|
||||
*(uint32_t*)(p + pos + 10) = RandomX_CurrentConfig.ConditionMask_Calculated << shift;
|
||||
pos += 14;
|
||||
|
||||
if (jmp_offset >= -128) {
|
||||
emitByte(JZ_SHORT, p, pos);
|
||||
|
@ -1085,9 +1082,7 @@ namespace randomx {
|
|||
int pos = codePos;
|
||||
|
||||
genAddressRegDst(instr, p, pos);
|
||||
emit(REX_MOV_MR, p, pos);
|
||||
emitByte(0x04 + 8 * instr.src, p, pos);
|
||||
emitByte(0x06, p, pos);
|
||||
emit32(0x0604894c + (static_cast<uint32_t>(instr.src) << 19), p, pos);
|
||||
|
||||
codePos = pos;
|
||||
}
|
||||
|
|
|
@ -69,6 +69,9 @@ namespace randomx {
|
|||
int registerUsage[RegistersCount];
|
||||
uint8_t* allocatedCode;
|
||||
uint8_t* code;
|
||||
# ifdef XMRIG_FIX_RYZEN
|
||||
std::pair<const void*, const void*> mainLoopBounds;
|
||||
# endif
|
||||
int32_t codePos;
|
||||
uint32_t vm_flags;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -97,11 +97,6 @@ RandomX_ConfigurationSafex::RandomX_ConfigurationSafex()
|
|||
ArgonSalt = "RandomSFX\x01";
|
||||
}
|
||||
|
||||
RandomX_ConfigurationV::RandomX_ConfigurationV()
|
||||
{
|
||||
ArgonSalt = "RandomV\x03";
|
||||
}
|
||||
|
||||
RandomX_ConfigurationBase::RandomX_ConfigurationBase()
|
||||
: ArgonMemory(262144)
|
||||
, ArgonIterations(3)
|
||||
|
@ -279,13 +274,16 @@ RandomX_ConfigurationWownero RandomX_WowneroConfig;
|
|||
RandomX_ConfigurationLoki RandomX_LokiConfig;
|
||||
RandomX_ConfigurationArqma RandomX_ArqmaConfig;
|
||||
RandomX_ConfigurationSafex RandomX_SafexConfig;
|
||||
RandomX_ConfigurationV RandomX_VConfig;
|
||||
|
||||
RandomX_ConfigurationBase RandomX_CurrentConfig;
|
||||
|
||||
extern "C" {
|
||||
|
||||
randomx_cache *randomx_create_cache(randomx_flags flags, uint8_t *memory) {
|
||||
if (!memory) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
randomx_cache *cache = nullptr;
|
||||
|
||||
try {
|
||||
|
@ -330,6 +328,10 @@ extern "C" {
|
|||
}
|
||||
|
||||
randomx_dataset *randomx_create_dataset(uint8_t *memory) {
|
||||
if (!memory) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto dataset = new randomx_dataset();
|
||||
dataset->memory = memory;
|
||||
|
||||
|
|
|
@ -183,14 +183,12 @@ struct RandomX_ConfigurationWownero : public RandomX_ConfigurationBase { RandomX
|
|||
struct RandomX_ConfigurationLoki : public RandomX_ConfigurationBase { RandomX_ConfigurationLoki(); };
|
||||
struct RandomX_ConfigurationArqma : public RandomX_ConfigurationBase { RandomX_ConfigurationArqma(); };
|
||||
struct RandomX_ConfigurationSafex : public RandomX_ConfigurationBase { RandomX_ConfigurationSafex(); };
|
||||
struct RandomX_ConfigurationV : public RandomX_ConfigurationBase { RandomX_ConfigurationV(); };
|
||||
|
||||
extern RandomX_ConfigurationMonero RandomX_MoneroConfig;
|
||||
extern RandomX_ConfigurationWownero RandomX_WowneroConfig;
|
||||
extern RandomX_ConfigurationLoki RandomX_LokiConfig;
|
||||
extern RandomX_ConfigurationArqma RandomX_ArqmaConfig;
|
||||
extern RandomX_ConfigurationSafex RandomX_SafexConfig;
|
||||
extern RandomX_ConfigurationV RandomX_VConfig;
|
||||
|
||||
extern RandomX_ConfigurationBase RandomX_CurrentConfig;
|
||||
|
||||
|
|
|
@ -74,6 +74,7 @@ bool xmrig::Rx::init(const Job &job, const RxConfig &config, const CpuConfig &cp
|
|||
|
||||
if (!osInitialized) {
|
||||
msrInit(config);
|
||||
setupMainLoopExceptionFrame();
|
||||
osInitialized = true;
|
||||
}
|
||||
|
||||
|
@ -131,4 +132,8 @@ void xmrig::Rx::msrDestroy()
|
|||
#endif
|
||||
|
||||
|
||||
|
||||
#ifndef XMRIG_FIX_RYZEN
|
||||
void xmrig::Rx::setupMainLoopExceptionFrame()
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -57,9 +57,14 @@ public:
|
|||
static void destroy();
|
||||
static void init(IRxListener *listener);
|
||||
|
||||
# ifdef XMRIG_FIX_RYZEN
|
||||
static void setMainLoopBounds(const std::pair<const void*, const void*>& bounds);
|
||||
# endif
|
||||
|
||||
private:
|
||||
static void msrInit(const RxConfig &config);
|
||||
static void msrDestroy();
|
||||
static void setupMainLoopExceptionFrame();
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -57,9 +57,6 @@ const RandomX_ConfigurationBase *xmrig::RxAlgo::base(Algorithm::Id algorithm)
|
|||
case Algorithm::RX_SFX:
|
||||
return &RandomX_SafexConfig;
|
||||
|
||||
case Algorithm::RX_V:
|
||||
return &RandomX_VConfig;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ public:
|
|||
|
||||
static inline Algorithm::Id id(Algorithm::Id algorithm)
|
||||
{
|
||||
if (algorithm == Algorithm::RX_SFX || algorithm == Algorithm::RX_V) {
|
||||
if (algorithm == Algorithm::RX_SFX) {
|
||||
return Algorithm::RX_0;
|
||||
}
|
||||
|
||||
|
|
|
@ -48,13 +48,11 @@ public:
|
|||
XMRIG_DISABLE_COPY_MOVE(RxBasicStoragePrivate)
|
||||
|
||||
inline RxBasicStoragePrivate() = default;
|
||||
inline ~RxBasicStoragePrivate()
|
||||
{
|
||||
delete m_dataset;
|
||||
}
|
||||
inline ~RxBasicStoragePrivate() { deleteDataset(); }
|
||||
|
||||
inline bool isReady(const Job &job) const { return m_ready && m_seed == job; }
|
||||
inline RxDataset *dataset() const { return m_dataset; }
|
||||
inline void deleteDataset() { delete m_dataset; m_dataset = nullptr; }
|
||||
|
||||
|
||||
inline void setSeed(const RxSeed &seed)
|
||||
|
@ -69,12 +67,22 @@ public:
|
|||
}
|
||||
|
||||
|
||||
inline void createDataset(bool hugePages, bool oneGbPages, RxConfig::Mode mode)
|
||||
inline bool createDataset(bool hugePages, bool oneGbPages, RxConfig::Mode mode)
|
||||
{
|
||||
const uint64_t ts = Chrono::steadyMSecs();
|
||||
|
||||
m_dataset = new RxDataset(hugePages, oneGbPages, true, mode, 0);
|
||||
if (!m_dataset->cache()->get()) {
|
||||
deleteDataset();
|
||||
|
||||
LOG_INFO("%s" RED_BOLD("failed to allocate RandomX memory") BLACK_BOLD(" (%" PRIu64 " ms)"), rx_tag(), Chrono::steadyMSecs() - ts);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
printAllocStatus(ts);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
@ -82,11 +90,11 @@ public:
|
|||
{
|
||||
const uint64_t ts = Chrono::steadyMSecs();
|
||||
|
||||
m_dataset->init(m_seed.data(), threads, priority);
|
||||
m_ready = m_dataset->init(m_seed.data(), threads, priority);
|
||||
|
||||
LOG_INFO("%s" GREEN_BOLD("dataset ready") BLACK_BOLD(" (%" PRIu64 " ms)"), rx_tag(), Chrono::steadyMSecs() - ts);
|
||||
|
||||
m_ready = true;
|
||||
if (m_ready) {
|
||||
LOG_INFO("%s" GREEN_BOLD("dataset ready") BLACK_BOLD(" (%" PRIu64 " ms)"), rx_tag(), Chrono::steadyMSecs() - ts);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -136,6 +144,12 @@ xmrig::RxBasicStorage::~RxBasicStorage()
|
|||
}
|
||||
|
||||
|
||||
bool xmrig::RxBasicStorage::isAllocated() const
|
||||
{
|
||||
return d_ptr->dataset() && d_ptr->dataset()->cache() && d_ptr->dataset()->cache()->get();
|
||||
}
|
||||
|
||||
|
||||
xmrig::HugePagesInfo xmrig::RxBasicStorage::hugePages() const
|
||||
{
|
||||
if (!d_ptr->dataset()) {
|
||||
|
@ -160,8 +174,8 @@ void xmrig::RxBasicStorage::init(const RxSeed &seed, uint32_t threads, bool huge
|
|||
{
|
||||
d_ptr->setSeed(seed);
|
||||
|
||||
if (!d_ptr->dataset()) {
|
||||
d_ptr->createDataset(hugePages, oneGbPages, mode);
|
||||
if (!d_ptr->dataset() && !d_ptr->createDataset(hugePages, oneGbPages, mode)) {
|
||||
return;
|
||||
}
|
||||
|
||||
d_ptr->initDataset(threads, priority);
|
||||
|
|
|
@ -48,6 +48,7 @@ public:
|
|||
~RxBasicStorage() override;
|
||||
|
||||
protected:
|
||||
bool isAllocated() const override;
|
||||
HugePagesInfo hugePages() const override;
|
||||
RxDataset *dataset(const Job &job, uint32_t nodeId) const override;
|
||||
void init(const RxSeed &seed, uint32_t threads, bool hugePages, bool oneGbPages, RxConfig::Mode mode, int priority) override;
|
||||
|
|
|
@ -30,9 +30,7 @@
|
|||
#include "crypto/randomx/randomx.h"
|
||||
|
||||
|
||||
static_assert(RANDOMX_FLAG_JIT == 8, "RANDOMX_FLAG_JIT flag mismatch");
|
||||
static_assert(RANDOMX_FLAG_LARGE_PAGES == 1, "RANDOMX_FLAG_LARGE_PAGES flag mismatch");
|
||||
|
||||
static_assert(RANDOMX_FLAG_JIT == 8, "RANDOMX_FLAG_JIT flag mismatch");
|
||||
|
||||
|
||||
xmrig::RxCache::RxCache(bool hugePages, uint32_t nodeId)
|
||||
|
@ -64,9 +62,14 @@ bool xmrig::RxCache::init(const Buffer &seed)
|
|||
}
|
||||
|
||||
m_seed = seed;
|
||||
randomx_init_cache(m_cache, m_seed.data(), m_seed.size());
|
||||
|
||||
return true;
|
||||
if (m_cache) {
|
||||
randomx_init_cache(m_cache, m_seed.data(), m_seed.size());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
@ -78,6 +81,10 @@ xmrig::HugePagesInfo xmrig::RxCache::hugePages() const
|
|||
|
||||
void xmrig::RxCache::create(uint8_t *memory)
|
||||
{
|
||||
if (!memory) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_cache = randomx_create_cache(RANDOMX_FLAG_JIT, memory);
|
||||
|
||||
if (!m_cache) {
|
||||
|
|
|
@ -65,7 +65,7 @@ constexpr size_t kMsrArraySize = 4;
|
|||
static const std::array<MsrItems, kMsrArraySize> msrPresets = {
|
||||
MsrItems(),
|
||||
MsrItems{{ 0xC0011020, 0x0 }, { 0xC0011021, 0x40, ~0x20ULL }, { 0xC0011022, 0x510000 }, { 0xC001102b, 0x1808cc16 }},
|
||||
MsrItems{{ 0x1a4, 0x6 }},
|
||||
MsrItems{{ 0x1a4, 0xf }},
|
||||
MsrItems()
|
||||
};
|
||||
|
||||
|
|
|
@ -88,7 +88,7 @@ xmrig::RxDataset::~RxDataset()
|
|||
|
||||
bool xmrig::RxDataset::init(const Buffer &seed, uint32_t numThreads, int priority)
|
||||
{
|
||||
if (!m_cache) {
|
||||
if (!m_cache || !m_cache->get()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -120,7 +120,7 @@ public:
|
|||
}
|
||||
|
||||
|
||||
inline void createDatasets(bool hugePages, bool oneGbPages)
|
||||
inline bool createDatasets(bool hugePages, bool oneGbPages)
|
||||
{
|
||||
const uint64_t ts = Chrono::steadyMSecs();
|
||||
|
||||
|
@ -133,6 +133,10 @@ public:
|
|||
if (isCacheRequired()) {
|
||||
std::thread thread(allocateCache, this, m_nodeset.front(), hugePages);
|
||||
thread.join();
|
||||
|
||||
if (!m_cache) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_datasets.empty()) {
|
||||
|
@ -149,6 +153,8 @@ public:
|
|||
}
|
||||
|
||||
m_allocated = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
@ -237,6 +243,13 @@ private:
|
|||
bindToNUMANode(nodeId);
|
||||
|
||||
auto cache = new RxCache(hugePages, nodeId);
|
||||
if (!cache->get()) {
|
||||
delete cache;
|
||||
|
||||
LOG_INFO("%s" RED_BOLD("failed to allocate RandomX memory") BLACK_BOLD(" (%" PRIu64 " ms)"), rx_tag(), Chrono::steadyMSecs() - ts);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
d_ptr->m_cache = cache;
|
||||
|
@ -336,6 +349,12 @@ xmrig::RxNUMAStorage::~RxNUMAStorage()
|
|||
}
|
||||
|
||||
|
||||
bool xmrig::RxNUMAStorage::isAllocated() const
|
||||
{
|
||||
return d_ptr->isAllocated();
|
||||
}
|
||||
|
||||
|
||||
xmrig::HugePagesInfo xmrig::RxNUMAStorage::hugePages() const
|
||||
{
|
||||
if (!d_ptr->isAllocated()) {
|
||||
|
@ -360,8 +379,8 @@ void xmrig::RxNUMAStorage::init(const RxSeed &seed, uint32_t threads, bool hugeP
|
|||
{
|
||||
d_ptr->setSeed(seed);
|
||||
|
||||
if (!d_ptr->isAllocated()) {
|
||||
d_ptr->createDatasets(hugePages, oneGbPages);
|
||||
if (!d_ptr->isAllocated() && !d_ptr->createDatasets(hugePages, oneGbPages)) {
|
||||
return;
|
||||
}
|
||||
|
||||
d_ptr->initDatasets(threads, priority);
|
||||
|
|
|
@ -51,6 +51,7 @@ public:
|
|||
~RxNUMAStorage() override;
|
||||
|
||||
protected:
|
||||
bool isAllocated() const override;
|
||||
HugePagesInfo hugePages() const override;
|
||||
RxDataset *dataset(const Job &job, uint32_t nodeId) const override;
|
||||
void init(const RxSeed &seed, uint32_t threads, bool hugePages, bool oneGbPages, RxConfig::Mode mode, int priority) override;
|
||||
|
|
|
@ -126,7 +126,7 @@ void xmrig::RxQueue::enqueue(const RxSeed &seed, const std::vector<uint32_t> &no
|
|||
|
||||
bool xmrig::RxQueue::isReadyUnsafe(const Job &job) const
|
||||
{
|
||||
return m_storage != nullptr && m_state == STATE_IDLE && m_seed == job;
|
||||
return m_storage != nullptr && m_storage->isAllocated() && m_state == STATE_IDLE && m_seed == job;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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,33 @@ static bool wrmsr(const MsrItems &preset, bool save)
|
|||
}
|
||||
|
||||
|
||||
#ifdef XMRIG_FIX_RYZEN
|
||||
static thread_local std::pair<const void*, const void*> 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<void*>(ucp->uc_mcontext.gregs[REG_RIP]);
|
||||
const std::pair<const void*, const void*>& loopBounds = mainLoopBounds;
|
||||
|
||||
if ((loopBounds.first <= p) && (p < loopBounds.second)) {
|
||||
ucp->uc_mcontext.gregs[REG_RIP] = reinterpret_cast<size_t>(loopBounds.second);
|
||||
}
|
||||
else {
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
void Rx::setMainLoopBounds(const std::pair<const void*, const void*>& bounds)
|
||||
{
|
||||
mainLoopBounds = bounds;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
|
@ -208,3 +237,15 @@ 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
|
||||
}
|
||||
|
|
|
@ -303,6 +303,43 @@ static bool wrmsr(const MsrItems &preset, bool save)
|
|||
}
|
||||
|
||||
|
||||
#ifdef XMRIG_FIX_RYZEN
|
||||
static thread_local std::pair<const void*, const void*> 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<void*>(ExceptionInfo->ContextRecord->Rip);
|
||||
const std::pair<const void*, const void*>& loopBounds = mainLoopBounds;
|
||||
|
||||
if ((loopBounds.first <= p) && (p < loopBounds.second)) {
|
||||
ExceptionInfo->ContextRecord->Rip = reinterpret_cast<DWORD64>(loopBounds.second);
|
||||
return EXCEPTION_CONTINUE_EXECUTION;
|
||||
}
|
||||
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
void Rx::setMainLoopBounds(const std::pair<const void*, const void*>& bounds)
|
||||
{
|
||||
mainLoopBounds = bounds;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
|
@ -333,3 +370,11 @@ 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
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue