Fixed secure JIT on Linux and code cleanup.

This commit is contained in:
XMRig 2020-12-12 19:18:47 +07:00
parent 497863441a
commit 775867fc3e
No known key found for this signature in database
GPG key ID: 446A53638BE94409
8 changed files with 62 additions and 54 deletions

View file

@ -61,9 +61,10 @@ namespace randomx {
template<class Allocator> template<class Allocator>
void deallocCache(randomx_cache* cache) { void deallocCache(randomx_cache* cache) {
if (cache->memory != nullptr) if (cache->memory != nullptr) {
Allocator::freeMemory(cache->memory, RANDOMX_CACHE_MAX_SIZE); Allocator::freeMemory(cache->memory, RANDOMX_CACHE_MAX_SIZE);
if (cache->jit != nullptr) }
delete cache->jit; delete cache->jit;
} }

View file

@ -114,6 +114,10 @@ JitCompilerA64::~JitCompilerA64()
void JitCompilerA64::generateProgram(Program& program, ProgramConfiguration& config, uint32_t) void JitCompilerA64::generateProgram(Program& program, ProgramConfiguration& config, uint32_t)
{ {
# ifdef XMRIG_SECURE_JIT
enableWriting();
# endif
uint32_t codePos = MainLoopBegin + 4; uint32_t codePos = MainLoopBegin + 4;
// and w16, w10, ScratchpadL3Mask64 // and w16, w10, ScratchpadL3Mask64
@ -334,8 +338,12 @@ void JitCompilerA64::generateSuperscalarHash(SuperscalarProgram(&programs)[N])
template void JitCompilerA64::generateSuperscalarHash(SuperscalarProgram(&programs)[RANDOMX_CACHE_MAX_ACCESSES]); template void JitCompilerA64::generateSuperscalarHash(SuperscalarProgram(&programs)[RANDOMX_CACHE_MAX_ACCESSES]);
DatasetInitFunc* JitCompilerA64::getDatasetInitFunc() DatasetInitFunc* JitCompilerA64::getDatasetInitFunc() const
{ {
# ifdef XMRIG_SECURE_JIT
enableExecution();
# endif
return (DatasetInitFunc*)(code + (((uint8_t*)randomx_init_dataset_aarch64) - ((uint8_t*)randomx_program_aarch64))); return (DatasetInitFunc*)(code + (((uint8_t*)randomx_init_dataset_aarch64) - ((uint8_t*)randomx_program_aarch64)));
} }
@ -344,21 +352,16 @@ size_t JitCompilerA64::getCodeSize()
return CodeSize; return CodeSize;
} }
void JitCompilerA64::enableWriting() void JitCompilerA64::enableWriting() const
{ {
xmrig::VirtualMemory::protectRW(code, CodeSize + CalcDatasetItemSize()); xmrig::VirtualMemory::protectRW(code, CodeSize + CalcDatasetItemSize());
} }
void JitCompilerA64::enableExecution() void JitCompilerA64::enableExecution() const
{ {
xmrig::VirtualMemory::protectRX(code, CodeSize + CalcDatasetItemSize()); xmrig::VirtualMemory::protectRX(code, CodeSize + CalcDatasetItemSize());
} }
void JitCompilerA64::enableAll()
{
xmrig::VirtualMemory::protectRWX(code, CodeSize + CalcDatasetItemSize());
}
void JitCompilerA64::emitMovImmediate(uint32_t dst, uint32_t imm, uint8_t* code, uint32_t& codePos) void JitCompilerA64::emitMovImmediate(uint32_t dst, uint32_t imm, uint8_t* code, uint32_t& codePos)
{ {
uint32_t k = codePos; uint32_t k = codePos;

View file

@ -59,16 +59,24 @@ namespace randomx {
void generateDatasetInitCode() {} void generateDatasetInitCode() {}
ProgramFunc* getProgramFunc() { return reinterpret_cast<ProgramFunc*>(code); } inline ProgramFunc *getProgramFunc() const {
DatasetInitFunc* getDatasetInitFunc(); # ifdef XMRIG_SECURE_JIT
enableExecution();
# endif
return reinterpret_cast<ProgramFunc*>(code);
}
DatasetInitFunc* getDatasetInitFunc() const;
uint8_t* getCode() { return code; } uint8_t* getCode() { return code; }
size_t getCodeSize(); size_t getCodeSize();
void enableWriting(); void enableWriting() const;
void enableExecution(); void enableExecution() const;
void enableAll();
static InstructionGeneratorA64 engine[256]; static InstructionGeneratorA64 engine[256];
private:
uint32_t reg_changed_offset[8]; uint32_t reg_changed_offset[8];
uint8_t* code; uint8_t* code;
uint32_t literalPos; uint32_t literalPos;
@ -95,6 +103,7 @@ namespace randomx {
template<uint32_t tmp_reg_fp> template<uint32_t tmp_reg_fp>
void emitMemLoadFP(uint32_t src, Instruction& instr, uint8_t* code, uint32_t& codePos); void emitMemLoadFP(uint32_t src, Instruction& instr, uint8_t* code, uint32_t& codePos);
public:
void h_IADD_RS(Instruction&, uint32_t&); void h_IADD_RS(Instruction&, uint32_t&);
void h_IADD_M(Instruction&, uint32_t&); void h_IADD_M(Instruction&, uint32_t&);
void h_ISUB_R(Instruction&, uint32_t&); void h_ISUB_R(Instruction&, uint32_t&);

View file

@ -74,6 +74,5 @@ namespace randomx {
} }
void enableWriting() {} void enableWriting() {}
void enableExecution() {} void enableExecution() {}
void enableAll() {}
}; };
} }

View file

@ -174,16 +174,12 @@ namespace randomx {
return codePos < prologueSize ? 0 : codePos - prologueSize; return codePos < prologueSize ? 0 : codePos - prologueSize;
} }
void JitCompilerX86::enableAll() { void JitCompilerX86::enableWriting() const {
xmrig::VirtualMemory::protectRWX(code, CodeSize); xmrig::VirtualMemory::protectRW(allocatedCode, allocatedSize);
} }
void JitCompilerX86::enableWriting() { void JitCompilerX86::enableExecution() const {
xmrig::VirtualMemory::protectRW(code, CodeSize); xmrig::VirtualMemory::protectRX(allocatedCode, allocatedSize);
}
void JitCompilerX86::enableExecution() {
xmrig::VirtualMemory::protectRX(code, CodeSize);
} }
static inline void cpuid(uint32_t level, int32_t output[4]) static inline void cpuid(uint32_t level, int32_t output[4])
@ -216,7 +212,8 @@ namespace randomx {
cpuid(0x80000001, info); cpuid(0x80000001, info);
hasXOP = ((info[2] & (1 << 11)) != 0); hasXOP = ((info[2] & (1 << 11)) != 0);
allocatedCode = (uint8_t*)allocExecutableMemory(CodeSize * 2, hugePagesJIT && hugePagesEnable); allocatedSize = CodeSize * 2;
allocatedCode = static_cast<uint8_t*>(allocExecutableMemory(allocatedSize, hugePagesJIT && hugePagesEnable));
// Shift code base address to improve caching - all threads will use different L2/L3 cache sets // Shift code base address to improve caching - all threads will use different L2/L3 cache sets
code = allocatedCode + (codeOffset.fetch_add(codeOffsetIncrement) % CodeSize); code = allocatedCode + (codeOffset.fetch_add(codeOffsetIncrement) % CodeSize);
@ -240,7 +237,7 @@ namespace randomx {
JitCompilerX86::~JitCompilerX86() { JitCompilerX86::~JitCompilerX86() {
codeOffset.fetch_sub(codeOffsetIncrement); codeOffset.fetch_sub(codeOffsetIncrement);
freePagedMemory(allocatedCode, CodeSize); freePagedMemory(allocatedCode, allocatedSize);
} }
void JitCompilerX86::prepare() { void JitCompilerX86::prepare() {
@ -253,6 +250,10 @@ namespace randomx {
void JitCompilerX86::generateProgram(Program& prog, ProgramConfiguration& pcfg, uint32_t flags) { void JitCompilerX86::generateProgram(Program& prog, ProgramConfiguration& pcfg, uint32_t flags) {
PROFILE_SCOPE(RandomX_JIT_compile); PROFILE_SCOPE(RandomX_JIT_compile);
# ifdef XMRIG_SECURE_JIT
enableWriting();
# endif
vm_flags = flags; vm_flags = flags;
generateProgramPrologue(prog, pcfg); generateProgramPrologue(prog, pcfg);

View file

@ -57,22 +57,33 @@ namespace randomx {
template<size_t N> template<size_t N>
void generateSuperscalarHash(SuperscalarProgram (&programs)[N]); void generateSuperscalarHash(SuperscalarProgram (&programs)[N]);
void generateDatasetInitCode(); void generateDatasetInitCode();
ProgramFunc* getProgramFunc() {
return (ProgramFunc*)code; inline ProgramFunc *getProgramFunc() const {
# ifdef XMRIG_SECURE_JIT
enableExecution();
# endif
return reinterpret_cast<ProgramFunc*>(code);
} }
DatasetInitFunc* getDatasetInitFunc() {
inline DatasetInitFunc *getDatasetInitFunc() const {
# ifdef XMRIG_SECURE_JIT
enableExecution();
# endif
return (DatasetInitFunc*)code; return (DatasetInitFunc*)code;
} }
uint8_t* getCode() { uint8_t* getCode() {
return code; return code;
} }
size_t getCodeSize(); size_t getCodeSize();
void enableWriting(); void enableWriting() const;
void enableExecution(); void enableExecution() const;
void enableAll();
alignas(64) static InstructionGeneratorX86 engine[256]; alignas(64) static InstructionGeneratorX86 engine[256];
private:
int registerUsage[RegistersCount] = {}; int registerUsage[RegistersCount] = {};
uint8_t* code = nullptr; uint8_t* code = nullptr;
uint32_t codePos = 0; uint32_t codePos = 0;
@ -87,7 +98,8 @@ namespace randomx {
bool hasAVX; bool hasAVX;
bool hasXOP; bool hasXOP;
uint8_t* allocatedCode; uint8_t* allocatedCode = nullptr;
size_t allocatedSize = 0;
void generateProgramPrologue(Program&, ProgramConfiguration&); void generateProgramPrologue(Program&, ProgramConfiguration&);
void generateProgramEpilogue(Program&, ProgramConfiguration&); void generateProgramEpilogue(Program&, ProgramConfiguration&);
@ -124,6 +136,7 @@ namespace randomx {
codePos += count; codePos += count;
} }
public:
void h_IADD_RS(const Instruction&); void h_IADD_RS(const Instruction&);
void h_IADD_M(const Instruction&); void h_IADD_M(const Instruction&);
void h_ISUB_R(const Instruction&); void h_ISUB_R(const Instruction&);

View file

@ -49,17 +49,7 @@ namespace randomx {
compiler.prepare(); compiler.prepare();
VmBase<softAes>::generateProgram(seed); VmBase<softAes>::generateProgram(seed);
randomx_vm::initialize(); randomx_vm::initialize();
# ifdef XMRIG_SECURE_JIT
compiler.enableWriting();
# endif
compiler.generateProgram(program, config, randomx_vm::getFlags()); compiler.generateProgram(program, config, randomx_vm::getFlags());
# ifdef XMRIG_SECURE_JIT
compiler.enableExecution();
# endif
mem.memory = datasetPtr->memory + datasetOffset; mem.memory = datasetPtr->memory + datasetOffset;
execute(); execute();
} }
@ -68,9 +58,9 @@ namespace randomx {
void CompiledVm<softAes>::execute() { void CompiledVm<softAes>::execute() {
PROFILE_SCOPE(RandomX_JIT_execute); PROFILE_SCOPE(RandomX_JIT_execute);
#ifdef XMRIG_ARM # ifdef XMRIG_ARM
memcpy(reg.f, config.eMask, sizeof(config.eMask)); memcpy(reg.f, config.eMask, sizeof(config.eMask));
#endif # endif
compiler.getProgramFunc()(reg, mem, scratchpad, RandomX_CurrentConfig.ProgramIterations); compiler.getProgramFunc()(reg, mem, scratchpad, RandomX_CurrentConfig.ProgramIterations);
} }

View file

@ -44,10 +44,6 @@ namespace randomx {
# endif # endif
compiler.generateSuperscalarHash(cache->programs); compiler.generateSuperscalarHash(cache->programs);
# ifdef XMRIG_SECURE_JIT
compiler.enableExecution();
# endif
} }
template<int softAes> template<int softAes>
@ -61,10 +57,6 @@ namespace randomx {
compiler.generateProgramLight(program, config, datasetOffset); compiler.generateProgramLight(program, config, datasetOffset);
# ifdef XMRIG_SECURE_JIT
compiler.enableExecution();
# endif
CompiledVm<softAes>::execute(); CompiledVm<softAes>::execute();
} }