Merge branch 'dev'

This commit is contained in:
XMRig 2021-01-26 15:25:20 +07:00
commit e38d277143
No known key found for this signature in database
GPG key ID: 446A53638BE94409
70 changed files with 2869 additions and 1047 deletions

View file

@ -1,3 +1,12 @@
# v6.8.0
- [#2052](https://github.com/xmrig/xmrig/pull/2052) Added DMI/SMBIOS reader.
- Added information about memory modules on the miner startup and for online benchmark.
- Added new HTTP API endpoint: `GET /2/dmi`.
- Added new command line option `--no-dmi` or config option `"dmi"`.
- Added new CMake option `-DWITH_DMI=OFF`.
- [#2057](https://github.com/xmrig/xmrig/pull/2057) Improved MSR subsystem code quality.
- [#2058](https://github.com/xmrig/xmrig/pull/2058) RandomX JIT x86: removed unnecessary instructions.
# v6.7.2
- [#2039](https://github.com/xmrig/xmrig/pull/2039) Fixed solo mining.

View file

@ -26,6 +26,7 @@ option(WITH_PROFILING "Enable profiling for developers" OFF)
option(WITH_SSE4_1 "Enable SSE 4.1 for Blake2" ON)
option(WITH_BENCHMARK "Enable builtin RandomX benchmark and stress test" ON)
option(WITH_SECURE_JIT "Enable secure access to JIT memory" OFF)
option(WITH_DMI "Enable DMI/SMBIOS reader" ON)
option(BUILD_STATIC "Build static binary" OFF)
option(ARM_TARGET "Force use specific ARM target 8 or 7" 0)
@ -169,7 +170,7 @@ else()
endif()
add_definitions(-DXMRIG_MINER_PROJECT -DXMRIG_JSON_SINGLE_LINE_ARRAY)
add_definitions(-D__STDC_FORMAT_MACROS -DUNICODE)
add_definitions(-D__STDC_FORMAT_MACROS -DUNICODE -D_FILE_OFFSET_BITS=64)
find_package(UV REQUIRED)
@ -197,6 +198,9 @@ if (WITH_EMBEDDED_CONFIG)
add_definitions(/DXMRIG_FEATURE_EMBEDDED_CONFIG)
endif()
include(src/hw/api/api.cmake)
include(src/hw/dmi/dmi.cmake)
include_directories(src)
include_directories(src/3rdparty)
include_directories(${UV_INCLUDE_DIR})

View file

@ -100,13 +100,29 @@ if (WITH_RANDOMX)
message("-- WITH_MSR=ON")
if (XMRIG_OS_WIN)
list(APPEND SOURCES_CRYPTO src/crypto/rx/Rx_win.cpp)
list(APPEND SOURCES_CRYPTO
src/crypto/rx/RxFix_win.cpp
src/hw/msr/Msr_win.cpp
)
elseif (XMRIG_OS_LINUX)
list(APPEND SOURCES_CRYPTO src/crypto/rx/Rx_linux.cpp)
list(APPEND SOURCES_CRYPTO
src/crypto/rx/RxFix_linux.cpp
src/hw/msr/Msr_linux.cpp
)
endif()
list(APPEND HEADERS_CRYPTO src/crypto/rx/msr/MsrItem.h)
list(APPEND SOURCES_CRYPTO src/crypto/rx/msr/MsrItem.cpp)
list(APPEND HEADERS_CRYPTO
src/crypto/rx/RxFix.h
src/crypto/rx/RxMsr.h
src/hw/msr/Msr.h
src/hw/msr/MsrItem.h
)
list(APPEND SOURCES_CRYPTO
src/crypto/rx/RxMsr.cpp
src/hw/msr/Msr.cpp
src/hw/msr/MsrItem.cpp
)
else()
remove_definitions(/DXMRIG_FEATURE_MSR)
remove_definitions(/DXMRIG_FIX_RYZEN)

View file

@ -5,8 +5,8 @@
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2019 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <support@xmrig.com>
* Copyright 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2021 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
@ -39,6 +39,11 @@
#include "version.h"
#ifdef XMRIG_FEATURE_DMI
# include "hw/dmi/DmiReader.h"
#endif
#ifdef XMRIG_ALGO_RANDOMX
# include "crypto/rx/RxConfig.h"
#endif
@ -71,7 +76,7 @@ inline static const char *asmName(Assembly::Id assembly)
#endif
static void print_memory(Config *config)
static void print_pages(const Config *config)
{
Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") "%s",
"HUGE PAGES", config->cpu().isHugePages() ? (VirtualMemory::isHugepagesAvailable() ? kHugepagesSupported : RED_BOLD("unavailable")) : RED_BOLD("disabled"));
@ -87,7 +92,7 @@ static void print_memory(Config *config)
}
static void print_cpu(Config *)
static void print_cpu(const Config *)
{
const auto info = Cpu::info();
@ -116,7 +121,7 @@ static void print_cpu(Config *)
}
static void print_memory()
static void print_memory(const Config *config)
{
constexpr size_t oneGiB = 1024U * 1024U * 1024U;
const auto freeMem = static_cast<double>(uv_get_free_memory());
@ -124,16 +129,49 @@ static void print_memory()
const double percent = freeMem > 0 ? ((totalMem - freeMem) / totalMem * 100.0) : 100.0;
Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN_BOLD("%.1f/%.1f GB") BLACK_BOLD(" (%.0f%%)"),
Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN_BOLD("%.1f/%.1f") CYAN(" GB") BLACK_BOLD(" (%.0f%%)"),
"MEMORY",
(totalMem - freeMem) / oneGiB,
totalMem / oneGiB,
percent
);
# ifdef XMRIG_FEATURE_DMI
if (!config->isDMI()) {
return;
}
DmiReader reader;
if (!reader.read()) {
return;
}
const bool vm = Cpu::info()->isVM();
for (const auto &memory : reader.memory()) {
if (!memory.isValid()) {
continue;
}
if (memory.size()) {
Log::print(WHITE_BOLD(" %-13s") "%s: " CYAN_BOLD("%" PRIu64) CYAN(" GB ") WHITE_BOLD("%s @ %" PRIu64 " MHz ") BLACK_BOLD("%s"),
"", memory.slot().data(), memory.size() / oneGiB, memory.type(), memory.speed() / 1000000ULL, memory.product().data());
}
else if (!vm) {
Log::print(WHITE_BOLD(" %-13s") "%s: " BLACK_BOLD("<empty>"), "", memory.slot().data());
}
}
const auto &board = vm ? reader.system() : reader.board();
if (board.isValid()) {
Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") WHITE_BOLD("%s") " - " WHITE_BOLD("%s"), "MOTHERBOARD", board.vendor().data(), board.product().data());
}
# endif
}
static void print_threads(Config *config)
static void print_threads(const Config *config)
{
Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") WHITE_BOLD("%s%d%%"),
"DONATE",
@ -175,14 +213,16 @@ static void print_commands(Config *)
void xmrig::Summary::print(Controller *controller)
{
controller->config()->printVersions();
print_memory(controller->config());
print_cpu(controller->config());
print_memory();
print_threads(controller->config());
controller->config()->pools().print();
const auto config = controller->config();
print_commands(controller->config());
config->printVersions();
print_pages(config);
print_cpu(config);
print_memory(config);
print_threads(config);
config->pools().print();
print_commands(config);
}

View file

@ -5,8 +5,8 @@
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2021 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

View file

@ -1,6 +1,6 @@
/* XMRig
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2020 XMRig <support@xmrig.com>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 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
@ -86,18 +86,21 @@ public:
inline constexpr static bool is64bit() { return false; }
# endif
virtual Arch arch() const = 0;
virtual Assembly::Id assembly() const = 0;
virtual bool has(Flag feature) const = 0;
virtual bool hasAES() const = 0;
virtual bool hasAVX() const = 0;
virtual bool hasAVX2() const = 0;
virtual bool hasBMI2() const = 0;
virtual bool hasCatL3() const = 0;
virtual bool hasOneGbPages() const = 0;
virtual bool hasXOP() const = 0;
virtual bool hasCatL3() const = 0;
virtual bool isVM() const = 0;
virtual bool jccErratum() const = 0;
virtual const char *backend() const = 0;
virtual const char *brand() const = 0;
virtual const std::vector<int32_t> &units() const = 0;
virtual CpuThreads threads(const Algorithm &algorithm, uint32_t limit) const = 0;
virtual MsrMod msrMod() const = 0;
virtual rapidjson::Value toJSON(rapidjson::Document &doc) const = 0;
@ -108,8 +111,6 @@ public:
virtual size_t packages() const = 0;
virtual size_t threads() const = 0;
virtual Vendor vendor() const = 0;
virtual Arch arch() const = 0;
virtual bool jccErratum() const = 0;
};

View file

@ -1,7 +1,7 @@
/* XMRig
* Copyright (c) 2017-2019 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2020 XMRig <support@xmrig.com>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 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
@ -190,6 +190,11 @@ xmrig::BasicCpuInfo::BasicCpuInfo() :
m_flags.set(FLAG_CAT_L3, has_cat_l3());
m_flags.set(FLAG_VM, is_vm());
m_units.resize(m_threads);
for (int32_t i = 0; i < static_cast<int32_t>(m_threads); ++i) {
m_units[i] = i;
}
# ifdef XMRIG_FEATURE_ASM
if (hasAES()) {
char vendor[13] = { 0 };

View file

@ -1,12 +1,7 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2019 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <support@xmrig.com>
* Copyright (c) 2017-2019 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 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
@ -45,34 +40,36 @@ protected:
CpuThreads threads(const Algorithm &algorithm, uint32_t limit) const override;
rapidjson::Value toJSON(rapidjson::Document &doc) const override;
inline Assembly::Id assembly() const override { return m_assembly; }
inline bool has(Flag flag) const override { return m_flags.test(flag); }
inline bool hasAES() const override { return has(FLAG_AES); }
inline bool hasAVX() const override { return has(FLAG_AVX); }
inline bool hasAVX2() const override { return has(FLAG_AVX2); }
inline bool hasBMI2() const override { return has(FLAG_BMI2); }
inline bool hasOneGbPages() const override { return has(FLAG_PDPE1GB); }
inline bool hasXOP() const override { return has(FLAG_XOP); }
inline bool hasCatL3() const override { return has(FLAG_CAT_L3); }
inline bool isVM() const override { return has(FLAG_VM); }
inline const char *brand() const override { return m_brand; }
inline MsrMod msrMod() const override { return m_msrMod; }
inline size_t cores() const override { return 0; }
inline size_t L2() const override { return 0; }
inline size_t L3() const override { return 0; }
inline size_t nodes() const override { return 0; }
inline size_t packages() const override { return 1; }
inline size_t threads() const override { return m_threads; }
inline Vendor vendor() const override { return m_vendor; }
inline Arch arch() const override { return m_arch; }
inline bool jccErratum() const override { return m_jccErratum; }
inline Arch arch() const override { return m_arch; }
inline Assembly::Id assembly() const override { return m_assembly; }
inline bool has(Flag flag) const override { return m_flags.test(flag); }
inline bool hasAES() const override { return has(FLAG_AES); }
inline bool hasAVX() const override { return has(FLAG_AVX); }
inline bool hasAVX2() const override { return has(FLAG_AVX2); }
inline bool hasBMI2() const override { return has(FLAG_BMI2); }
inline bool hasCatL3() const override { return has(FLAG_CAT_L3); }
inline bool hasOneGbPages() const override { return has(FLAG_PDPE1GB); }
inline bool hasXOP() const override { return has(FLAG_XOP); }
inline bool isVM() const override { return has(FLAG_VM); }
inline bool jccErratum() const override { return m_jccErratum; }
inline const char *brand() const override { return m_brand; }
inline const std::vector<int32_t> &units() const override { return m_units; }
inline MsrMod msrMod() const override { return m_msrMod; }
inline size_t cores() const override { return 0; }
inline size_t L2() const override { return 0; }
inline size_t L3() const override { return 0; }
inline size_t nodes() const override { return 0; }
inline size_t packages() const override { return 1; }
inline size_t threads() const override { return m_threads; }
inline Vendor vendor() const override { return m_vendor; }
protected:
char m_brand[64 + 6]{};
size_t m_threads;
Vendor m_vendor = VENDOR_UNKNOWN;
Arch m_arch = ARCH_UNKNOWN;
bool m_jccErratum = false;
char m_brand[64 + 6]{};
size_t m_threads;
std::vector<int32_t> m_units;
Vendor m_vendor = VENDOR_UNKNOWN;
private:
# ifndef XMRIG_ARM

View file

@ -1,6 +1,6 @@
/* XMRig
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2020 XMRig <support@xmrig.com>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 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
@ -50,6 +50,11 @@ extern String cpu_name_arm();
xmrig::BasicCpuInfo::BasicCpuInfo() :
m_threads(std::thread::hardware_concurrency())
{
m_units.resize(m_threads);
for (int32_t i = 0; i < static_cast<int32_t>(m_threads); ++i) {
m_units[i] = i;
}
# ifdef XMRIG_ARMv8
memcpy(m_brand, "ARMv8", 5);
# else

View file

@ -1,6 +1,6 @@
/* XMRig
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2020 XMRig <support@xmrig.com>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 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
@ -125,8 +125,6 @@ static inline bool isCacheExclusive(hwloc_obj_t obj)
xmrig::HwlocCpuInfo::HwlocCpuInfo()
{
m_threads = 0;
hwloc_topology_init(&m_topology);
hwloc_topology_load(m_topology);
@ -170,7 +168,8 @@ xmrig::HwlocCpuInfo::HwlocCpuInfo()
findCache(root, 2, 3, [this](hwloc_obj_t found) { this->m_cache[found->attr->cache.depth] += found->attr->cache.size; });
m_threads = countByType(m_topology, HWLOC_OBJ_PU);
setThreads(countByType(m_topology, HWLOC_OBJ_PU));
m_cores = countByType(m_topology, HWLOC_OBJ_CORE);
m_nodes = std::max(hwloc_bitmap_weight(hwloc_topology_get_complete_nodeset(m_topology)), 1);
m_packages = countByType(m_topology, HWLOC_OBJ_PACKAGE);
@ -277,10 +276,8 @@ xmrig::CpuThreads xmrig::HwlocCpuInfo::allThreads(const Algorithm &algorithm, ui
CpuThreads threads;
threads.reserve(m_threads);
hwloc_obj_t pu = nullptr;
while ((pu = hwloc_get_next_obj_by_type(m_topology, HWLOC_OBJ_PU, pu)) != nullptr) {
threads.add(pu->os_index, 0);
for (const int32_t pu : m_units) {
threads.add(pu, 0);
}
if (threads.isEmpty()) {
@ -395,3 +392,24 @@ void xmrig::HwlocCpuInfo::processTopLevelCache(hwloc_obj_t cache, const Algorith
}
# endif
}
void xmrig::HwlocCpuInfo::setThreads(size_t threads)
{
if (!threads) {
return;
}
m_threads = threads;
if (m_units.size() != m_threads) {
m_units.resize(m_threads);
}
hwloc_obj_t pu = nullptr;
size_t i = 0;
while ((pu = hwloc_get_next_obj_by_type(m_topology, HWLOC_OBJ_PU, pu)) != nullptr) {
m_units[i++] = static_cast<int32_t>(pu->os_index);
}
}

View file

@ -1,6 +1,6 @@
/* XMRig
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2020 XMRig <support@xmrig.com>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 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
@ -66,7 +66,7 @@ protected:
private:
CpuThreads allThreads(const Algorithm &algorithm, uint32_t limit) const;
void processTopLevelCache(hwloc_obj_t obj, const Algorithm &algorithm, CpuThreads &threads, size_t limit) const;
void setThreads(size_t threads);
static uint32_t m_features;

View file

@ -1,12 +1,6 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2021 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

View file

@ -1,12 +1,6 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2021 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
@ -31,7 +25,6 @@
#include "base/kernel/interfaces/IBaseListener.h"
#include "base/tools/Object.h"
#include "base/tools/String.h"

View file

@ -1,10 +1,6 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2018 XMRig <support@xmrig.com>
* Copyright 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2021 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
@ -24,6 +20,9 @@
#define XMRIG_IAPILISTENER_H
#include "base/tools/Object.h"
namespace xmrig {
@ -33,6 +32,9 @@ class IApiRequest;
class IApiListener
{
public:
XMRIG_DISABLE_COPY_MOVE(IApiListener)
IApiListener() = default;
virtual ~IApiListener() = default;
# ifdef XMRIG_FEATURE_API

View file

@ -1,12 +1,6 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2021 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
@ -27,6 +21,7 @@
#include "3rdparty/rapidjson/fwd.h"
#include "base/tools/Object.h"
namespace xmrig {
@ -38,6 +33,8 @@ class String;
class IApiRequest
{
public:
XMRIG_DISABLE_COPY_MOVE(IApiRequest)
enum Method {
METHOD_DELETE,
METHOD_GET,
@ -67,7 +64,8 @@ public:
};
virtual ~IApiRequest() = default;
IApiRequest() = default;
virtual ~IApiRequest() = default;
virtual bool accept() = 0;
virtual bool hasParseError() const = 0;

View file

@ -1,12 +1,6 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2021 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
@ -26,6 +20,9 @@
#define XMRIG_IBASELISTENER_H
#include "base/tools/Object.h"
namespace xmrig {
@ -35,7 +32,10 @@ class Config;
class IBaseListener
{
public:
virtual ~IBaseListener() = default;
XMRIG_DISABLE_COPY_MOVE(IBaseListener)
IBaseListener() = default;
virtual ~IBaseListener() = default;
virtual void onConfigChanged(Config *config, Config *previousConfig) = 0;
};

View file

@ -5,8 +5,8 @@
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2021 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
@ -84,6 +84,7 @@ public:
BenchSeedKey = 1046,
BenchHashKey = 1047,
BenchTokenKey = 1048,
DmiKey = 1049,
// xmrig common
CPUPriorityKey = 1021,

View file

@ -5,8 +5,8 @@
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2021 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
@ -134,7 +134,7 @@ void xmrig::Pools::load(const IJsonReader &reader)
m_data.clear();
# ifdef XMRIG_FEATURE_BENCHMARK
m_benchmark = std::shared_ptr<BenchConfig>(BenchConfig::create(reader.getObject(BenchConfig::kBenchmark)));
m_benchmark = std::shared_ptr<BenchConfig>(BenchConfig::create(reader.getObject(BenchConfig::kBenchmark), reader.getBool("dmi", true)));
if (m_benchmark) {
m_data.emplace_back(m_benchmark);

View file

@ -5,8 +5,8 @@
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2021 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

View file

@ -1,6 +1,6 @@
/* XMRig
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 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
@ -34,6 +34,10 @@
#include "base/tools/Cvt.h"
#include "version.h"
#ifdef XMRIG_FEATURE_DMI
# include "hw/dmi/DmiReader.h"
#endif
xmrig::BenchClient::BenchClient(const std::shared_ptr<BenchConfig> &benchmark, IClientListener* listener) :
m_listener(listener),
@ -336,6 +340,15 @@ void xmrig::BenchClient::send(Request request)
doc.AddMember("steady_ready_ts", m_readyTime, allocator);
doc.AddMember("cpu", Cpu::toJSON(doc), allocator);
# ifdef XMRIG_FEATURE_DMI
if (m_benchmark->isDMI()) {
DmiReader reader;
if (reader.read()) {
doc.AddMember("dmi", reader.toJSON(doc), allocator);
}
}
# endif
FetchRequest req(HTTP_POST, m_ip, BenchConfig::kApiPort, "/1/benchmark", doc, BenchConfig::kApiTLS, true);
fetch(tag(), std::move(req), m_httpListener);
}

View file

@ -1,6 +1,6 @@
/* XMRig
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 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

View file

@ -1,6 +1,6 @@
/* XMRig
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 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
@ -52,8 +52,9 @@ const char *BenchConfig::kApiHost = "127.0.0.1";
} // namespace xmrig
xmrig::BenchConfig::BenchConfig(uint32_t size, const String &id, const rapidjson::Value &object) :
xmrig::BenchConfig::BenchConfig(uint32_t size, const String &id, const rapidjson::Value &object, bool dmi) :
m_algorithm(Json::getString(object, kAlgo)),
m_dmi(dmi),
m_submit(Json::getBool(object, kSubmit)),
m_id(id),
m_seed(Json::getString(object, kSeed)),
@ -72,7 +73,7 @@ xmrig::BenchConfig::BenchConfig(uint32_t size, const String &id, const rapidjson
}
xmrig::BenchConfig *xmrig::BenchConfig::create(const rapidjson::Value &object)
xmrig::BenchConfig *xmrig::BenchConfig::create(const rapidjson::Value &object, bool dmi)
{
if (!object.IsObject() || object.ObjectEmpty()) {
return nullptr;
@ -85,7 +86,7 @@ xmrig::BenchConfig *xmrig::BenchConfig::create(const rapidjson::Value &object)
return nullptr;
}
return new BenchConfig(size, id, object);
return new BenchConfig(size, id, object, dmi);
}

View file

@ -1,6 +1,6 @@
/* XMRig
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 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
@ -49,10 +49,11 @@ public:
static constexpr const uint16_t kApiPort = 18805;
# endif
BenchConfig(uint32_t size, const String &id, const rapidjson::Value &object);
BenchConfig(uint32_t size, const String &id, const rapidjson::Value &object, bool dmi);
static BenchConfig *create(const rapidjson::Value &object);
static BenchConfig *create(const rapidjson::Value &object, bool dmi);
inline bool isDMI() const { return m_dmi; }
inline bool isSubmit() const { return m_submit; }
inline const Algorithm &algorithm() const { return m_algorithm; }
inline const String &id() const { return m_id; }
@ -67,6 +68,7 @@ private:
static uint32_t getSize(const char *benchmark);
Algorithm m_algorithm;
bool m_dmi;
bool m_submit;
String m_id;
String m_seed;

View file

@ -80,6 +80,7 @@
],
"print-time": 60,
"health-print-time": 60,
"dmi": true,
"retries": 5,
"retry-pause": 5,
"syslog": false,

View file

@ -1,12 +1,6 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2021 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
@ -31,6 +25,12 @@
#include "net/Network.h"
#ifdef XMRIG_FEATURE_API
# include "base/api/Api.h"
# include "hw/api/HwApi.h"
#endif
#include <cassert>
@ -42,8 +42,6 @@ xmrig::Controller::Controller(Process *process) :
xmrig::Controller::~Controller()
{
delete m_network;
VirtualMemory::destroy();
}
@ -54,7 +52,12 @@ int xmrig::Controller::init()
VirtualMemory::init(config()->cpu().memPoolSize(), config()->cpu().isHugePages());
m_network = new Network(this);
m_network = std::make_shared<Network>(this);
# ifdef XMRIG_FEATURE_API
m_hwApi = std::make_shared<HwApi>();
api()->addListener(m_hwApi.get());
# endif
return 0;
}
@ -64,7 +67,7 @@ void xmrig::Controller::start()
{
Base::start();
m_miner = new Miner(this);
m_miner = std::make_shared<Miner>(this);
network()->connect();
}
@ -74,29 +77,26 @@ void xmrig::Controller::stop()
{
Base::stop();
delete m_network;
m_network = nullptr;
m_network.reset();
m_miner->stop();
delete m_miner;
m_miner = nullptr;
m_miner.reset();
}
xmrig::Miner *xmrig::Controller::miner() const
{
assert(m_miner != nullptr);
assert(m_miner);
return m_miner;
return m_miner.get();
}
xmrig::Network *xmrig::Controller::network() const
{
assert(m_network != nullptr);
assert(m_network);
return m_network;
return m_network.get();
}

View file

@ -1,12 +1,6 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2021 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
@ -27,12 +21,15 @@
#include "base/kernel/Base.h"
#include "base/tools/Object.h"
#include <memory>
namespace xmrig {
class HwApi;
class Job;
class Miner;
class Network;
@ -55,8 +52,12 @@ public:
void execCommand(char command);
private:
Miner *m_miner = nullptr;
Network *m_network = nullptr;
std::shared_ptr<Miner> m_miner;
std::shared_ptr<Network> m_network;
# ifdef XMRIG_FEATURE_API
std::shared_ptr<HwApi> m_hwApi;
# endif
};

View file

@ -5,8 +5,8 @@
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2021 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
@ -23,9 +23,9 @@
*/
#include <algorithm>
#include <cinttypes>
#include <cstring>
#include <uv.h>
#include <cinttypes>
#include "core/config/Config.h"
@ -55,16 +55,19 @@ namespace xmrig {
#ifdef XMRIG_FEATURE_OPENCL
static const char *kOcl = "opencl";
const char *Config::kOcl = "opencl";
#endif
#ifdef XMRIG_FEATURE_CUDA
static const char *kCuda = "cuda";
const char *Config::kCuda = "cuda";
#endif
#if defined(XMRIG_FEATURE_NVML) || defined (XMRIG_FEATURE_ADL)
static const char *kHealthPrintTime = "health-print-time";
const char *Config::kHealthPrintTime = "health-print-time";
#endif
#ifdef XMRIG_FEATURE_DMI
const char *Config::kDMI = "dmi";
#endif
@ -88,6 +91,10 @@ public:
# if defined(XMRIG_FEATURE_NVML) || defined (XMRIG_FEATURE_ADL)
uint32_t healthPrintTime = 60;
# endif
# ifdef XMRIG_FEATURE_DMI
bool dmi = true;
# endif
};
}
@ -143,6 +150,14 @@ uint32_t xmrig::Config::healthPrintTime() const
#endif
#ifdef XMRIG_FEATURE_DMI
bool xmrig::Config::isDMI() const
{
return d_ptr->dmi;
}
#endif
bool xmrig::Config::isShouldSave() const
{
if (!isAutoSave()) {
@ -191,6 +206,10 @@ bool xmrig::Config::read(const IJsonReader &reader, const char *fileName)
d_ptr->healthPrintTime = reader.getUint(kHealthPrintTime, d_ptr->healthPrintTime);
# endif
# ifdef XMRIG_FEATURE_DMI
d_ptr->dmi = reader.getBool(kDMI, d_ptr->dmi);
# endif
return true;
}
@ -236,6 +255,11 @@ void xmrig::Config::getJSON(rapidjson::Document &doc) const
# if defined(XMRIG_FEATURE_NVML) || defined (XMRIG_FEATURE_ADL)
doc.AddMember(StringRef(kHealthPrintTime), healthPrintTime(), allocator);
# endif
# ifdef XMRIG_FEATURE_DMI
doc.AddMember(StringRef(kDMI), isDMI(), allocator);
# endif
doc.AddMember(StringRef(kSyslog), isSyslog(), allocator);
# ifdef XMRIG_FEATURE_TLS

View file

@ -5,8 +5,8 @@
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2021 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
@ -50,6 +50,22 @@ class Config : public BaseConfig
public:
XMRIG_DISABLE_COPY_MOVE(Config);
# ifdef XMRIG_FEATURE_OPENCL
static const char *kOcl;
# endif
# ifdef XMRIG_FEATURE_CUDA
static const char *kCuda;
# endif
# if defined(XMRIG_FEATURE_NVML) || defined (XMRIG_FEATURE_ADL)
static const char *kHealthPrintTime;
# endif
# ifdef XMRIG_FEATURE_DMI
static const char *kDMI;
# endif
Config();
~Config() override;
@ -70,7 +86,13 @@ public:
# if defined(XMRIG_FEATURE_NVML) || defined (XMRIG_FEATURE_ADL)
uint32_t healthPrintTime() const;
# else
uint32_t healthPrintTime() const { return 0; }
uint32_t healthPrintTime() const { return 0; }
# endif
# ifdef XMRIG_FEATURE_DMI
bool isDMI() const;
# else
static constexpr inline bool isDMI() { return false; }
# endif
bool isShouldSave() const;

View file

@ -5,8 +5,8 @@
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2021 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
@ -23,11 +23,11 @@
*/
#include "core/config/ConfigTransform.h"
#include "base/kernel/interfaces/IConfig.h"
#include "backend/cpu/CpuConfig.h"
#include "base/net/stratum/Pool.h"
#include "base/net/stratum/Pools.h"
#include "core/config/ConfigTransform.h"
#include "core/config/Config.h"
#include "crypto/cn/CnHash.h"
@ -51,14 +51,6 @@ static const char *kEnabled = "enabled";
static const char *kIntensity = "intensity";
static const char *kThreads = "threads";
#ifdef XMRIG_FEATURE_OPENCL
static const char *kOcl = "opencl";
#endif
#ifdef XMRIG_FEATURE_CUDA
static const char *kCuda = "cuda";
#endif
static inline uint64_t intensity(uint64_t av)
{
@ -122,7 +114,7 @@ void xmrig::ConfigTransform::finalize(rapidjson::Document &doc)
# ifdef XMRIG_FEATURE_OPENCL
if (m_opencl) {
set(doc, kOcl, kEnabled, true);
set(doc, Config::kOcl, kEnabled, true);
}
# endif
}
@ -208,47 +200,54 @@ void xmrig::ConfigTransform::transform(rapidjson::Document &doc, int key, const
break;
case IConfig::OclCacheKey: /* --opencl-no-cache */
return set(doc, kOcl, "cache", false);
return set(doc, Config::kOcl, "cache", false);
case IConfig::OclLoaderKey: /* --opencl-loader */
return set(doc, kOcl, "loader", arg);
return set(doc, Config::kOcl, "loader", arg);
case IConfig::OclDevicesKey: /* --opencl-devices */
m_opencl = true;
return set(doc, kOcl, "devices-hint", arg);
return set(doc, Config::kOcl, "devices-hint", arg);
case IConfig::OclPlatformKey: /* --opencl-platform */
if (strlen(arg) < 3) {
return set(doc, kOcl, "platform", static_cast<uint64_t>(strtol(arg, nullptr, 10)));
return set(doc, Config::kOcl, "platform", static_cast<uint64_t>(strtol(arg, nullptr, 10)));
}
return set(doc, kOcl, "platform", arg);
return set(doc, Config::kOcl, "platform", arg);
# endif
# ifdef XMRIG_FEATURE_CUDA
case IConfig::CudaKey: /* --cuda */
return set(doc, kCuda, kEnabled, true);
return set(doc, Config::kCuda, kEnabled, true);
case IConfig::CudaLoaderKey: /* --cuda-loader */
return set(doc, kCuda, "loader", arg);
return set(doc, Config::kCuda, "loader", arg);
case IConfig::CudaDevicesKey: /* --cuda-devices */
set(doc, kCuda, kEnabled, true);
return set(doc, kCuda, "devices-hint", arg);
set(doc, Config::kCuda, kEnabled, true);
return set(doc, Config::kCuda, "devices-hint", arg);
case IConfig::CudaBFactorKey: /* --cuda-bfactor-hint */
return set(doc, kCuda, "bfactor-hint", static_cast<uint64_t>(strtol(arg, nullptr, 10)));
return set(doc, Config::kCuda, "bfactor-hint", static_cast<uint64_t>(strtol(arg, nullptr, 10)));
case IConfig::CudaBSleepKey: /* --cuda-bsleep-hint */
return set(doc, kCuda, "bsleep-hint", static_cast<uint64_t>(strtol(arg, nullptr, 10)));
return set(doc, Config::kCuda, "bsleep-hint", static_cast<uint64_t>(strtol(arg, nullptr, 10)));
# endif
# ifdef XMRIG_FEATURE_NVML
case IConfig::NvmlKey: /* --no-nvml */
return set(doc, kCuda, "nvml", false);
return set(doc, Config::kCuda, "nvml", false);
# endif
# if defined(XMRIG_FEATURE_NVML) || defined (XMRIG_FEATURE_ADL)
case IConfig::HealthPrintTimeKey: /* --health-print-time */
return set(doc, "health-print-time", static_cast<uint64_t>(strtol(arg, nullptr, 10)));
return set(doc, Config::kHealthPrintTime, static_cast<uint64_t>(strtol(arg, nullptr, 10)));
# endif
# ifdef XMRIG_FEATURE_DMI
case IConfig::DmiKey: /* --no-dmi */
return set(doc, Config::kDMI, false);
# endif
# ifdef XMRIG_FEATURE_BENCHMARK

View file

@ -5,8 +5,8 @@
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2021 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

View file

@ -1,12 +1,6 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 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
@ -22,6 +16,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_CONFIG_DEFAULT_H
#define XMRIG_CONFIG_DEFAULT_H
@ -29,6 +24,7 @@
namespace xmrig {
// This feature require CMake option: -DWITH_EMBEDDED_CONFIG=ON
#ifdef XMRIG_FEATURE_EMBEDDED_CONFIG
const static char *default_config =
R"===(
@ -45,9 +41,9 @@ R"===(
"restricted": true
},
"autosave": true,
"version": 1,
"background": false,
"colors": true,
"title": true,
"randomx": {
"init": -1,
"init-avx2": -1,
@ -80,6 +76,7 @@ R"===(
"cache": true,
"loader": null,
"platform": "AMD",
"adl": true,
"cn/0": false,
"cn-lite/0": false
},
@ -90,7 +87,7 @@ R"===(
"cn/0": false,
"cn-lite/0": false
},
"donate-level": 5,
"donate-level": 1,
"donate-over-proxy": 1,
"log-file": null,
"pools": [
@ -107,15 +104,27 @@ R"===(
"tls": false,
"tls-fingerprint": null,
"daemon": false,
"socks5": null,
"self-select": null
}
],
"print-time": 60,
"health-print-time": 60,
"dmi": true,
"retries": 5,
"retry-pause": 5,
"syslog": false,
"tls": {
"enabled": false,
"protocols": null,
"cert": null,
"cert_key": null,
"ciphers": null,
"ciphersuites": null,
"dhparam": null
},
"user-agent": null,
"verbose": 0,
"watch": true,
"pause-on-battery": false
}

View file

@ -155,7 +155,12 @@ static const option options[] = {
# endif
# ifdef XMRIG_FEATURE_NVML
{ "no-nvml", 0, nullptr, IConfig::NvmlKey },
# endif
# if defined(XMRIG_FEATURE_NVML) || defined (XMRIG_FEATURE_ADL)
{ "health-print-time", 1, nullptr, IConfig::HealthPrintTimeKey },
# endif
# ifdef XMRIG_FEATURE_DMI
{ "no-dmi", 0, nullptr, IConfig::DmiKey },
# endif
{ nullptr, 0, nullptr, 0 }
};

View file

@ -190,6 +190,10 @@ static inline const std::string &usage()
u += " --hash=HASH compare benchmark result with specified hash\n";
# endif
# ifdef XMRIG_FEATURE_DMI
u += " --no-dmi disable DMI/SMBIOS reader\n";
# endif
return u;
}

View file

@ -371,7 +371,7 @@ hashAndFillAes1Rx4_impl* softAESImpl = &hashAndFillAes1Rx4<1,1>;
void SelectSoftAESImpl(size_t threadsCount)
{
constexpr int test_length_ms = 100;
constexpr uint64_t test_length_ms = 100;
const std::array<hashAndFillAes1Rx4_impl *, 4> impl = {
&hashAndFillAes1Rx4<1,1>,
&hashAndFillAes1Rx4<2,1>,

View file

@ -1,7 +1,7 @@
/*
Copyright (c) 2018-2020, tevador <tevador@gmail.com>
Copyright (c) 2019-2020, SChernykh <https://github.com/SChernykh>
Copyright (c) 2019-2020, XMRig <https://github.com/xmrig>, <support@xmrig.com>
Copyright (c) 2019-2021, SChernykh <https://github.com/SChernykh>
Copyright (c) 2019-2021, XMRig <https://github.com/xmrig>, <support@xmrig.com>
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
@ -417,17 +417,15 @@ namespace randomx {
void JitCompilerX86::generateProgramPrologue(Program& prog, ProgramConfiguration& pcfg) {
codePos = ADDR(randomx_program_prologue_first_load) - ADDR(randomx_program_prologue);
code[codePos + 2] = 0xc0 + pcfg.readReg0;
code[codePos + 5] = 0xc0 + pcfg.readReg1;
*(uint32_t*)(code + codePos + 10) = RandomX_CurrentConfig.ScratchpadL3Mask64_Calculated;
*(uint32_t*)(code + codePos + 20) = RandomX_CurrentConfig.ScratchpadL3Mask64_Calculated;
*(uint32_t*)(code + codePos + 4) = RandomX_CurrentConfig.ScratchpadL3Mask64_Calculated;
*(uint32_t*)(code + codePos + 14) = RandomX_CurrentConfig.ScratchpadL3Mask64_Calculated;
if (hasAVX) {
uint32_t* p = (uint32_t*)(code + codePos + 67);
uint32_t* p = (uint32_t*)(code + codePos + 61);
*p = (*p & 0xFF000000U) | 0x0077F8C5U;
}
# ifdef XMRIG_FIX_RYZEN
xmrig::Rx::setMainLoopBounds(mainLoopBounds);
xmrig::RxFix::setMainLoopBounds(mainLoopBounds);
# endif
memcpy(code + prologueSize - 48, &pcfg.eMask, sizeof(pcfg.eMask));

View file

@ -93,8 +93,6 @@ DECL(randomx_program_prologue):
movapd xmm15, xmmword ptr [scaleMask+rip]
DECL(randomx_program_prologue_first_load):
xor rax, r8
xor rax, r8
mov rdx, rax
and eax, RANDOMX_SCRATCHPAD_MASK
ror rdx, 32

View file

@ -81,8 +81,6 @@ randomx_program_prologue PROC
randomx_program_prologue ENDP
randomx_program_prologue_first_load PROC
xor rax, r8
xor rax, r8
mov rdx, rax
and eax, RANDOMX_SCRATCHPAD_MASK
ror rdx, 32

View file

@ -1,7 +1,7 @@
/* XMRig
* Copyright (c) 2018-2019 tevador <tevador@gmail.com>
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 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
@ -27,6 +27,12 @@
#include "crypto/randomx/aes_hash.hpp"
#ifdef XMRIG_FEATURE_MSR
# include "crypto/rx/RxFix.h"
# include "crypto/rx/RxMsr.h"
#endif
namespace xmrig {
@ -34,8 +40,6 @@ class RxPrivate;
static bool osInitialized = false;
static bool msrInitialized = false;
static bool msrEnabled = false;
static RxPrivate *d_ptr = nullptr;
@ -65,9 +69,9 @@ xmrig::RxDataset *xmrig::Rx::dataset(const Job &job, uint32_t nodeId)
void xmrig::Rx::destroy()
{
if (osInitialized) {
msrDestroy();
}
# ifdef XMRIG_FEATURE_MSR
RxMsr::destroy();
# endif
delete d_ptr;
@ -85,11 +89,9 @@ template<typename T>
bool xmrig::Rx::init(const T &seed, const RxConfig &config, const CpuConfig &cpu)
{
if (seed.algorithm().family() != Algorithm::RANDOM_X) {
if (msrInitialized) {
msrDestroy();
msrInitialized = false;
msrEnabled = false;
}
# ifdef XMRIG_FEATURE_MSR
RxMsr::destroy();
# endif
return true;
}
@ -98,13 +100,17 @@ bool xmrig::Rx::init(const T &seed, const RxConfig &config, const CpuConfig &cpu
randomx_set_huge_pages_jit(cpu.isHugePagesJit());
randomx_set_optimized_dataset_init(config.initDatasetAVX2());
if (!msrInitialized) {
msrEnabled = msrInit(config, cpu.threads().get(seed.algorithm()).data());
msrInitialized = true;
# ifdef XMRIG_FEATURE_MSR
if (!RxMsr::isInitialized()) {
RxMsr::init(config, cpu.threads().get(seed.algorithm()).data());
}
# endif
if (!osInitialized) {
setupMainLoopExceptionFrame();
# ifdef XMRIG_FIX_RYZEN
RxFix::setupMainLoopExceptionFrame();
# endif
if (!cpu.isHwAES()) {
SelectSoftAESImpl(cpu.threads().get(seed.algorithm()).count());
}
@ -131,24 +137,7 @@ bool xmrig::Rx::isReady(const T &seed)
#ifdef XMRIG_FEATURE_MSR
bool xmrig::Rx::isMSR()
{
return msrEnabled;
}
#else
bool xmrig::Rx::msrInit(const RxConfig &, const std::vector<CpuThread> &)
{
return false;
}
void xmrig::Rx::msrDestroy()
{
}
#endif
#ifndef XMRIG_FIX_RYZEN
void xmrig::Rx::setupMainLoopExceptionFrame()
{
return RxMsr::isEnabled();
}
#endif

View file

@ -1,7 +1,7 @@
/* XMRig
* Copyright (c) 2018-2019 tevador <tevador@gmail.com>
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 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
@ -52,20 +52,11 @@ public:
template<typename T> static bool init(const T &seed, const RxConfig &config, const CpuConfig &cpu);
template<typename T> static bool isReady(const T &seed);
# ifdef XMRIG_FIX_RYZEN
static void setMainLoopBounds(const std::pair<const void*, const void*>& bounds);
# endif
# ifdef XMRIG_FEATURE_MSR
static bool isMSR();
# else
static constexpr bool isMSR() { return false; }
# endif
private:
static bool msrInit(const RxConfig &config, const std::vector<CpuThread>& threads);
static void msrDestroy();
static void setupMainLoopExceptionFrame();
};

View file

@ -30,7 +30,7 @@
#ifdef XMRIG_FEATURE_MSR
# include "crypto/rx/msr/MsrItem.h"
# include "hw/msr/MsrItem.h"
#endif

42
src/crypto/rx/RxFix.h Normal file
View file

@ -0,0 +1,42 @@
/* XMRig
* Copyright (c) 2018-2019 tevador <tevador@gmail.com>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 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
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_RXFIX_H
#define XMRIG_RXFIX_H
#include <utility>
namespace xmrig
{
class RxFix
{
public:
static void setMainLoopBounds(const std::pair<const void *, const void *> &bounds);
static void setupMainLoopExceptionFrame();
};
} /* namespace xmrig */
#endif /* XMRIG_RXFIX_H */

View file

@ -0,0 +1,71 @@
/* XMRig
* Copyright (c) 2018-2019 tevador <tevador@gmail.com>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 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
* 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 <http://www.gnu.org/licenses/>.
*/
#include "crypto/rx/RxFix.h"
#include "base/io/log/Log.h"
#include <csignal>
#include <cstdlib>
#include <ucontext.h>
namespace xmrig {
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();
}
}
} // namespace xmrig
void xmrig::RxFix::setMainLoopBounds(const std::pair<const void *, const void *> &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);
}

View file

@ -0,0 +1,74 @@
/* XMRig
* Copyright (c) 2018-2019 tevador <tevador@gmail.com>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 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
* 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 <http://www.gnu.org/licenses/>.
*/
#include "crypto/rx/RxFix.h"
#include "base/io/log/Log.h"
#include <windows.h>
namespace xmrig {
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;
}
} // namespace xmrig
void xmrig::RxFix::setMainLoopBounds(const std::pair<const void *, const void *> &bounds)
{
mainLoopBounds = bounds;
}
void xmrig::RxFix::setupMainLoopExceptionFrame()
{
AddVectoredExceptionHandler(1, MainLoopHandler);
}

183
src/crypto/rx/RxMsr.cpp Normal file
View file

@ -0,0 +1,183 @@
/* XMRig
* Copyright (c) 2018-2019 tevador <tevador@gmail.com>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 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
* 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 <http://www.gnu.org/licenses/>.
*/
#include "crypto/rx/RxMsr.h"
#include "backend/cpu/Cpu.h"
#include "backend/cpu/CpuThread.h"
#include "base/io/log/Log.h"
#include "base/tools/Chrono.h"
#include "crypto/rx/RxConfig.h"
#include "hw/msr/Msr.h"
#include <algorithm>
#include <set>
namespace xmrig {
bool RxMsr::m_cacheQoS = false;
bool RxMsr::m_enabled = false;
bool RxMsr::m_initialized = false;
static MsrItems items;
#ifdef XMRIG_OS_WIN
static constexpr inline int32_t get_cpu(int32_t) { return -1; }
#else
static constexpr inline int32_t get_cpu(int32_t cpu) { return cpu; }
#endif
static bool wrmsr(const MsrItems &preset, const std::vector<CpuThread> &threads, bool cache_qos, bool save)
{
auto msr = Msr::get();
if (!msr) {
return false;
}
if (save) {
items.reserve(preset.size());
for (const auto &i : preset) {
auto item = msr->read(i.reg());
if (!item.isValid()) {
items.clear();
return false;
}
LOG_VERBOSE("%s " CYAN_BOLD("0x%08" PRIx32) CYAN(":0x%016" PRIx64) CYAN_BOLD(" -> 0x%016" PRIx64), Msr::tag(), i.reg(), item.value(), MsrItem::maskedValue(item.value(), i.value(), i.mask()));
items.emplace_back(item);
}
}
// Which CPU cores will have access to the full L3 cache
std::set<int32_t> cacheEnabled;
bool cacheQoSDisabled = threads.empty();
if (cache_qos) {
const auto &units = Cpu::info()->units();
for (const auto &t : threads) {
const auto affinity = static_cast<int32_t>(t.affinity());
// If some thread has no affinity or wrong affinity, disable cache QoS
if (affinity < 0 || std::find(units.begin(), units.end(), affinity) == units.end()) {
cacheQoSDisabled = true;
LOG_WARN("%s " YELLOW_BOLD("cache QoS can only be enabled when all mining threads have affinity set"), Msr::tag());
break;
}
cacheEnabled.insert(affinity);
}
}
return msr->write([&msr, &preset, cache_qos, &cacheEnabled, cacheQoSDisabled](int32_t cpu) {
for (const auto &item : preset) {
if (!msr->write(item, get_cpu(cpu))) {
return false;
}
}
if (!cache_qos) {
return true;
}
// Assign Class Of Service 0 to current CPU core (default, full L3 cache available)
if (cacheQoSDisabled || cacheEnabled.count(cpu)) {
return msr->write(0xC8F, 0, get_cpu(cpu));
}
// Disable L3 cache for Class Of Service 1
if (!msr->write(0xC91, 0, get_cpu(cpu))) {
// Some CPUs don't let set it to all zeros
if (!msr->write(0xC91, 1, get_cpu(cpu))) {
return false;
}
}
// Assign Class Of Service 1 to current CPU core
return msr->write(0xC8F, 1ULL << 32, get_cpu(cpu));
});
}
} // namespace xmrig
bool xmrig::RxMsr::init(const RxConfig &config, const std::vector<CpuThread> &threads)
{
if (isInitialized()) {
return isEnabled();
}
m_initialized = true;
m_enabled = false;
const auto &preset = config.msrPreset();
if (preset.empty()) {
return false;
}
const uint64_t ts = Chrono::steadyMSecs();
m_cacheQoS = config.cacheQoS();
if (m_cacheQoS && !Cpu::info()->hasCatL3()) {
LOG_WARN("%s " YELLOW_BOLD("this CPU doesn't support cat_l3, cache QoS is unavailable"), Msr::tag());
m_cacheQoS = false;
}
if ((m_enabled = wrmsr(preset, threads, m_cacheQoS, config.rdmsr()))) {
LOG_NOTICE("%s " GREEN_BOLD("register values for \"%s\" preset have been set successfully") BLACK_BOLD(" (%" PRIu64 " ms)"), Msr::tag(), config.msrPresetName(), Chrono::steadyMSecs() - ts);
}
else {
LOG_ERR("%s " RED_BOLD("FAILED TO APPLY MSR MOD, HASHRATE WILL BE LOW"), Msr::tag());
}
return isEnabled();
}
void xmrig::RxMsr::destroy()
{
if (!isInitialized()) {
return;
}
m_initialized = false;
m_enabled = false;
if (items.empty()) {
return;
}
const uint64_t ts = Chrono::steadyMSecs();
if (!wrmsr(items, std::vector<CpuThread>(), m_cacheQoS, false)) {
LOG_ERR("%s " RED_BOLD("failed to restore initial state" BLACK_BOLD(" (%" PRIu64 " ms)")), Msr::tag(), Chrono::steadyMSecs() - ts);
}
}

54
src/crypto/rx/RxMsr.h Normal file
View file

@ -0,0 +1,54 @@
/* XMRig
* Copyright (c) 2018-2019 tevador <tevador@gmail.com>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 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
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_RXMSR_H
#define XMRIG_RXMSR_H
#include <vector>
namespace xmrig
{
class CpuThread;
class RxConfig;
class RxMsr
{
public:
static inline bool isEnabled() { return m_enabled; }
static inline bool isInitialized() { return m_initialized; }
static bool init(const RxConfig &config, const std::vector<CpuThread> &threads);
static void destroy();
private:
static bool m_cacheQoS;
static bool m_enabled;
static bool m_initialized;
};
} /* namespace xmrig */
#endif /* XMRIG_RXMSR_H */

View file

@ -1,313 +0,0 @@
/* XMRig
* Copyright (c) 2018-2019 tevador <tevador@gmail.com>
* Copyright (c) 2000 Transmeta Corporation <https://github.com/intel/msr-tools>
* Copyright (c) 2004-2008 H. Peter Anvin <https://github.com/intel/msr-tools>
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright (c) 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
* 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 <http://www.gnu.org/licenses/>.
*/
#include "crypto/rx/Rx.h"
#include "backend/cpu/Cpu.h"
#include "backend/cpu/CpuThread.h"
#include "base/io/log/Log.h"
#include "base/tools/Chrono.h"
#include "crypto/rx/RxConfig.h"
#include <array>
#include <cctype>
#include <cinttypes>
#include <cstdio>
#include <dirent.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <ucontext.h>
namespace xmrig {
static const char *tag = YELLOW_BG_BOLD(WHITE_BOLD_S " msr ") " ";
static MsrItems savedState;
static inline int dir_filter(const struct dirent *dirp)
{
return isdigit(dirp->d_name[0]) ? 1 : 0;
}
bool rdmsr_on_cpu(uint32_t reg, uint32_t cpu, uint64_t &value)
{
char msr_file_name[64]{};
sprintf(msr_file_name, "/dev/cpu/%u/msr", cpu);
int fd = open(msr_file_name, O_RDONLY);
if (fd < 0) {
return false;
}
const bool success = pread(fd, &value, sizeof value, reg) == sizeof value;
close(fd);
return success;
}
static MsrItem rdmsr(uint32_t reg)
{
uint64_t value = 0;
if (!rdmsr_on_cpu(reg, 0, value)) {
LOG_WARN(CLEAR "%s" YELLOW_BOLD_S "cannot read MSR 0x%08" PRIx32, tag, reg);
return {};
}
return { reg, value };
}
static uint64_t get_masked_value(uint64_t old_value, uint64_t new_value, uint64_t mask)
{
return (new_value & mask) | (old_value & ~mask);
}
static bool wrmsr_on_cpu(uint32_t reg, uint32_t cpu, uint64_t value, uint64_t mask)
{
// If a bit in mask is set to 1, use new value, otherwise use old value
if (mask != MsrItem::kNoMask) {
uint64_t old_value;
if (rdmsr_on_cpu(reg, cpu, old_value)) {
value = get_masked_value(old_value, value, mask);
}
}
char msr_file_name[64]{};
sprintf(msr_file_name, "/dev/cpu/%u/msr", cpu);
int fd = open(msr_file_name, O_WRONLY);
if (fd < 0) {
return false;
}
const bool success = pwrite(fd, &value, sizeof value, reg) == sizeof value;
close(fd);
return success;
}
template<typename T>
static bool wrmsr_on_all_cpus(uint32_t reg, uint64_t value, uint64_t mask, T&& callback)
{
struct dirent **namelist;
int dir_entries = scandir("/dev/cpu", &namelist, dir_filter, 0);
int errors = 0;
while (dir_entries--) {
if (!callback(reg, strtoul(namelist[dir_entries]->d_name, nullptr, 10), value, mask)) {
++errors;
}
free(namelist[dir_entries]);
}
free(namelist);
if (errors) {
LOG_WARN(CLEAR "%s" YELLOW_BOLD_S "cannot set MSR 0x%08" PRIx32 " to 0x%08" PRIx64, tag, reg, value);
}
return errors == 0;
}
static bool wrmsr_modprobe()
{
if (system("/sbin/modprobe msr allow_writes=on > /dev/null 2>&1") != 0) {
LOG_WARN(CLEAR "%s" YELLOW_BOLD_S "msr kernel module is not available", tag);
return false;
}
return true;
}
static bool wrmsr(const MsrItems& preset, const std::vector<CpuThread>& threads, bool cache_qos, bool save)
{
if (!wrmsr_modprobe()) {
return false;
}
if (save) {
for (const auto &i : preset) {
auto item = rdmsr(i.reg());
LOG_VERBOSE(CLEAR "%s" CYAN_BOLD("0x%08" PRIx32) CYAN(":0x%016" PRIx64) CYAN_BOLD(" -> 0x%016" PRIx64), tag, i.reg(), item.value(), get_masked_value(item.value(), i.value(), i.mask()));
if (item.isValid()) {
savedState.emplace_back(item);
}
}
}
for (const auto &i : preset) {
if (!wrmsr_on_all_cpus(i.reg(), i.value(), i.mask(), [](uint32_t reg, uint32_t cpu, uint64_t value, uint64_t mask) { return wrmsr_on_cpu(reg, cpu, value, mask); })) {
return false;
}
}
const uint32_t n = Cpu::info()->threads();
// Which CPU cores will have access to the full L3 cache
std::vector<bool> cacheEnabled(n, false);
bool cacheQoSDisabled = threads.empty();
for (const CpuThread& t : threads) {
// If some thread has no affinity or wrong affinity, disable cache QoS
if ((t.affinity() < 0) || (t.affinity() >= n)) {
cacheQoSDisabled = true;
if (cache_qos) {
LOG_WARN(CLEAR "%s" YELLOW_BOLD_S "Cache QoS can only be enabled when all mining threads have affinity set", tag);
}
break;
}
cacheEnabled[t.affinity()] = true;
}
if (cache_qos && !Cpu::info()->hasCatL3()) {
if (!threads.empty()) {
LOG_WARN(CLEAR "%s" YELLOW_BOLD_S "This CPU doesn't support cat_l3, cache QoS is unavailable", tag);
}
cache_qos = false;
}
bool result = true;
if (cache_qos) {
result = wrmsr_on_all_cpus(0xC8F, 0, MsrItem::kNoMask, [&cacheEnabled, cacheQoSDisabled](uint32_t, uint32_t cpu, uint64_t, uint64_t) {
if (cacheQoSDisabled || (cpu >= cacheEnabled.size()) || cacheEnabled[cpu]) {
// Assign Class Of Service 0 to current CPU core (default, full L3 cache available)
if (!wrmsr_on_cpu(0xC8F, cpu, 0, MsrItem::kNoMask)) {
return false;
}
}
else {
// Disable L3 cache for Class Of Service 1
if (!wrmsr_on_cpu(0xC91, cpu, 0, MsrItem::kNoMask)) {
// Some CPUs don't let set it to all zeros
if (!wrmsr_on_cpu(0xC91, cpu, 1, MsrItem::kNoMask)) {
return false;
}
}
// Assign Class Of Service 1 to current CPU core
if (!wrmsr_on_cpu(0xC8F, cpu, 1ULL << 32, MsrItem::kNoMask)) {
return false;
}
}
return true;
});
}
return result;
}
#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
bool xmrig::Rx::msrInit(const RxConfig &config, const std::vector<CpuThread> &threads)
{
const auto &preset = config.msrPreset();
if (preset.empty()) {
return false;
}
const uint64_t ts = Chrono::steadyMSecs();
if (wrmsr(preset, threads, config.cacheQoS(), config.rdmsr())) {
LOG_NOTICE(CLEAR "%s" GREEN_BOLD_S "register values for \"%s\" preset have been set successfully" BLACK_BOLD(" (%" PRIu64 " ms)"), tag, config.msrPresetName(), Chrono::steadyMSecs() - ts);
return true;
}
LOG_ERR(CLEAR "%s" RED_BOLD_S "FAILED TO APPLY MSR MOD, HASHRATE WILL BE LOW", tag);
return false;
}
void xmrig::Rx::msrDestroy()
{
if (savedState.empty()) {
return;
}
const uint64_t ts = Chrono::steadyMSecs();
if (!wrmsr(savedState, std::vector<CpuThread>(), true, false)) {
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
}

View file

@ -1,431 +0,0 @@
/* XMRig
* Copyright (c) 2018-2019 tevador <tevador@gmail.com>
* Copyright (c) 2000 Transmeta Corporation <https://github.com/intel/msr-tools>
* Copyright (c) 2004-2008 H. Peter Anvin <https://github.com/intel/msr-tools>
* Copyright (c) 2007-2009 hiyohiyo <https://openlibsys.org>, <hiyohiyo@crystalmark.info>
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright (c) 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
* 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 <http://www.gnu.org/licenses/>.
*/
#include "crypto/rx/Rx.h"
#include "backend/cpu/Cpu.h"
#include "backend/cpu/CpuThread.h"
#include "base/io/log/Log.h"
#include "base/kernel/Platform.h"
#include "base/tools/Chrono.h"
#include "crypto/rx/RxConfig.h"
#include <windows.h>
#include <array>
#include <string>
#include <thread>
#define SERVICE_NAME L"WinRing0_1_2_0"
namespace xmrig {
static bool reuseDriver = false;
static const char *tag = YELLOW_BG_BOLD(WHITE_BOLD_S " msr ") " ";
static MsrItems savedState;
static SC_HANDLE hManager;
static SC_HANDLE hService;
static bool wrmsr_uninstall_driver()
{
if (!hService) {
return true;
}
bool result = true;
if (!reuseDriver) {
SERVICE_STATUS serviceStatus;
if (!ControlService(hService, SERVICE_CONTROL_STOP, &serviceStatus)) {
result = false;
}
if (!DeleteService(hService)) {
LOG_ERR(CLEAR "%s" RED_S "failed to remove WinRing0 driver, error %u", tag, GetLastError());
result = false;
}
}
CloseServiceHandle(hService);
hService = nullptr;
return result;
}
static HANDLE wrmsr_install_driver()
{
DWORD err = 0;
hManager = OpenSCManager(nullptr, nullptr, SC_MANAGER_ALL_ACCESS);
if (!hManager) {
err = GetLastError();
if (err == ERROR_ACCESS_DENIED) {
LOG_WARN(CLEAR "%s" YELLOW_BOLD_S "to write MSR registers Administrator privileges required.", tag);
}
else {
LOG_ERR(CLEAR "%s" RED_S "failed to open service control manager, error %u", tag, err);
}
return nullptr;
}
std::vector<wchar_t> dir;
dir.resize(MAX_PATH);
do {
dir.resize(dir.size() * 2);
GetModuleFileNameW(nullptr, dir.data(), dir.size());
err = GetLastError();
} while (err == ERROR_INSUFFICIENT_BUFFER);
if (err != ERROR_SUCCESS) {
LOG_ERR(CLEAR "%s" RED_S "failed to get path to driver, error %u", tag, err);
return nullptr;
}
for (auto it = dir.end() - 1; it != dir.begin(); --it) {
if ((*it == L'\\') || (*it == L'/')) {
++it;
*it = L'\0';
break;
}
}
std::wstring driverPath = dir.data();
driverPath += L"WinRing0x64.sys";
hService = OpenServiceW(hManager, SERVICE_NAME, SERVICE_ALL_ACCESS);
if (hService) {
LOG_WARN(CLEAR "%s" YELLOW("service ") YELLOW_BOLD("WinRing0_1_2_0") YELLOW(" already exists"), tag);
SERVICE_STATUS status;
const auto rc = QueryServiceStatus(hService, &status);
if (rc) {
DWORD dwBytesNeeded;
QueryServiceConfigA(hService, nullptr, 0, &dwBytesNeeded);
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
std::vector<BYTE> buffer(dwBytesNeeded);
auto config = reinterpret_cast<LPQUERY_SERVICE_CONFIGA>(buffer.data());
if (QueryServiceConfigA(hService, config, buffer.size(), &dwBytesNeeded)) {
LOG_INFO(CLEAR "%s" YELLOW("service path: ") YELLOW_BOLD("\"%s\""), tag, config->lpBinaryPathName);
}
}
}
if (rc && status.dwCurrentState == SERVICE_RUNNING) {
reuseDriver = true;
}
else if (!wrmsr_uninstall_driver()) {
return nullptr;
}
}
if (!reuseDriver) {
hService = CreateServiceW(hManager, SERVICE_NAME, SERVICE_NAME, SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, driverPath.c_str(), nullptr, nullptr, nullptr, nullptr, nullptr);
if (!hService) {
LOG_ERR(CLEAR "%s" RED_S "failed to install WinRing0 driver, error %u", tag, GetLastError());
return nullptr;
}
if (!StartService(hService, 0, nullptr)) {
err = GetLastError();
if (err != ERROR_SERVICE_ALREADY_RUNNING) {
if (err == ERROR_FILE_NOT_FOUND) {
LOG_ERR(CLEAR "%s" RED("failed to start WinRing0 driver: ") RED_BOLD("\"WinRing0x64.sys not found\""), tag);
}
else {
LOG_ERR(CLEAR "%s" RED_S "failed to start WinRing0 driver, error %u", tag, err);
}
wrmsr_uninstall_driver();
return nullptr;
}
}
}
HANDLE hDriver = CreateFileW(L"\\\\.\\" SERVICE_NAME, GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
if (!hDriver) {
LOG_ERR(CLEAR "%s" RED_S "failed to connect to WinRing0 driver, error %u", tag, GetLastError());
return nullptr;
}
return hDriver;
}
#define IOCTL_READ_MSR CTL_CODE(40000, 0x821, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_WRITE_MSR CTL_CODE(40000, 0x822, METHOD_BUFFERED, FILE_ANY_ACCESS)
static bool rdmsr(HANDLE driver, uint32_t reg, uint64_t &value)
{
DWORD size = 0;
return DeviceIoControl(driver, IOCTL_READ_MSR, &reg, sizeof(reg), &value, sizeof(value), &size, nullptr) != 0;
}
static MsrItem rdmsr(HANDLE driver, uint32_t reg)
{
uint64_t value = 0;
if (!rdmsr(driver, reg, value)) {
LOG_WARN(CLEAR "%s" YELLOW_BOLD_S "cannot read MSR 0x%08" PRIx32, tag, reg);
return {};
}
return { reg, value };
}
static uint64_t get_masked_value(uint64_t old_value, uint64_t new_value, uint64_t mask)
{
return (new_value & mask) | (old_value & ~mask);
}
static bool wrmsr(HANDLE driver, uint32_t reg, uint64_t value, uint64_t mask)
{
struct {
uint32_t reg = 0;
uint32_t value[2]{};
} input;
static_assert(sizeof(input) == 12, "Invalid struct size for WinRing0 driver");
// If a bit in mask is set to 1, use new value, otherwise use old value
if (mask != MsrItem::kNoMask) {
uint64_t old_value;
if (rdmsr(driver, reg, old_value)) {
value = get_masked_value(old_value, value, mask);
}
}
input.reg = reg;
*(reinterpret_cast<uint64_t*>(input.value)) = value;
DWORD output;
DWORD k;
if (!DeviceIoControl(driver, IOCTL_WRITE_MSR, &input, sizeof(input), &output, sizeof(output), &k, nullptr)) {
LOG_WARN(CLEAR "%s" YELLOW_BOLD_S "cannot set MSR 0x%08" PRIx32 " to 0x%08" PRIx64, tag, reg, value);
return false;
}
return true;
}
static bool wrmsr(const MsrItems &preset, const std::vector<CpuThread>& threads, bool cache_qos, bool save)
{
bool success = true;
HANDLE driver = wrmsr_install_driver();
if (!driver) {
wrmsr_uninstall_driver();
if (hManager) {
CloseServiceHandle(hManager);
}
return false;
}
if (save) {
for (const auto &i : preset) {
auto item = rdmsr(driver, i.reg());
LOG_VERBOSE(CLEAR "%s" CYAN_BOLD("0x%08" PRIx32) CYAN(":0x%016" PRIx64) CYAN_BOLD(" -> 0x%016" PRIx64), tag, i.reg(), item.value(), get_masked_value(item.value(), i.value(), i.mask()));
if (item.isValid()) {
savedState.emplace_back(item);
}
}
}
const uint32_t n = Cpu::info()->threads();
// Which CPU cores will have access to the full L3 cache
std::vector<bool> cacheEnabled(n, false);
bool cacheQoSDisabled = threads.empty();
for (const CpuThread& t : threads) {
// If some thread has no affinity or wrong affinity, disable cache QoS
if ((t.affinity() < 0) || (t.affinity() >= n)) {
cacheQoSDisabled = true;
if (cache_qos) {
LOG_WARN(CLEAR "%s" YELLOW_BOLD_S "Cache QoS can only be enabled when all mining threads have affinity set", tag);
}
break;
}
cacheEnabled[t.affinity()] = true;
}
if (cache_qos && !Cpu::info()->hasCatL3()) {
if (!threads.empty()) {
LOG_WARN(CLEAR "%s" YELLOW_BOLD_S "This CPU doesn't support cat_l3, cache QoS is unavailable", tag);
}
cache_qos = false;
}
std::thread wrmsr_thread([n, driver, &preset, &cacheEnabled, cache_qos, cacheQoSDisabled, &success]() {
for (uint32_t i = 0; i < n; ++i) {
if (!Platform::setThreadAffinity(i)) {
continue;
}
for (const auto &i : preset) {
success &= wrmsr(driver, i.reg(), i.value(), i.mask());
}
if (cache_qos) {
if (cacheQoSDisabled || cacheEnabled[i]) {
// Assign Class Of Service 0 to current CPU core (default, full L3 cache available)
success &= wrmsr(driver, 0xC8F, 0, MsrItem::kNoMask);
}
else {
// Disable L3 cache for Class Of Service 1
if (!wrmsr(driver, 0xC91, 0, MsrItem::kNoMask)) {
// Some CPUs don't let set it to all zeros
if (!wrmsr(driver, 0xC91, 1, MsrItem::kNoMask)) {
success = false;
}
}
// Assign Class Of Service 1 to current CPU core
success &= wrmsr(driver, 0xC8F, 1ULL << 32, MsrItem::kNoMask);
}
}
if (!success) {
break;
}
}
});
wrmsr_thread.join();
CloseHandle(driver);
wrmsr_uninstall_driver();
CloseServiceHandle(hManager);
return success;
}
#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
bool xmrig::Rx::msrInit(const RxConfig &config, const std::vector<CpuThread>& threads)
{
const auto &preset = config.msrPreset();
if (preset.empty()) {
return false;
}
const uint64_t ts = Chrono::steadyMSecs();
if (wrmsr(preset, threads, config.cacheQoS(), config.rdmsr())) {
LOG_NOTICE(CLEAR "%s" GREEN_BOLD_S "register values for \"%s\" preset has been set successfully" BLACK_BOLD(" (%" PRIu64 " ms)"), tag, config.msrPresetName(), Chrono::steadyMSecs() - ts);
return true;
}
LOG_ERR(CLEAR "%s" RED_BOLD_S "FAILED TO APPLY MSR MOD, HASHRATE WILL BE LOW", tag);
return false;
}
void xmrig::Rx::msrDestroy()
{
if (savedState.empty()) {
return;
}
const uint64_t ts = Chrono::steadyMSecs();
if (!wrmsr(savedState, std::vector<CpuThread>(), true, false)) {
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
}

View file

@ -34,7 +34,7 @@
* Example of how it works for the setting of 1%:
* You miner will mine into your usual pool for random time (in range from 49.5 to 148.5 minutes),
* then switch to the developer's pool for 1 minute, then switch again to your pool for 99 minutes
* and then switch agaiin to developer's pool for 1 minute, these rounds will continue until miner working.
* and then switch again to developer's pool for 1 minute, these rounds will continue until miner working.
*
* Randomised only first round, to prevent waves on the donation pool.
*

45
src/hw/api/HwApi.cpp Normal file
View file

@ -0,0 +1,45 @@
/* XMRig
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 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
* 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 <http://www.gnu.org/licenses/>.
*/
#include "hw/api/HwApi.h"
#include "base/api/interfaces/IApiRequest.h"
#include "base/tools/String.h"
#ifdef XMRIG_FEATURE_DMI
# include "hw/dmi/DmiReader.h"
#endif
void xmrig::HwApi::onRequest(IApiRequest &request)
{
if (request.method() == IApiRequest::METHOD_GET) {
# ifdef XMRIG_FEATURE_DMI
if (request.url() == "/2/dmi") {
if (!m_dmi) {
m_dmi = std::make_shared<DmiReader>();
m_dmi->read();
}
request.accept();
m_dmi->toJSON(request.reply(), request.doc());
}
# endif
}
}

53
src/hw/api/HwApi.h Normal file
View file

@ -0,0 +1,53 @@
/* XMRig
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 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
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_HWAPI_H
#define XMRIG_HWAPI_H
#include "base/api/interfaces/IApiListener.h"
#include <memory>
namespace xmrig {
struct DmiReader;
class HwApi : public IApiListener
{
public:
HwApi() = default;
protected:
void onRequest(IApiRequest &request) override;
private:
# ifdef XMRIG_FEATURE_DMI
std::shared_ptr<DmiReader> m_dmi;
# endif
};
} /* namespace xmrig */
#endif /* XMRIG_HWAPI_H */

11
src/hw/api/api.cmake Normal file
View file

@ -0,0 +1,11 @@
if (WITH_HTTP)
add_definitions(/DXMRIG_FEATURE_DMI)
list(APPEND HEADERS
src/hw/api/HwApi.h
)
list(APPEND SOURCES
src/hw/api/HwApi.cpp
)
endif()

50
src/hw/dmi/DmiBoard.cpp Normal file
View file

@ -0,0 +1,50 @@
/* XMRig
* Copyright (c) 2000-2002 Alan Cox <alan@redhat.com>
* Copyright (c) 2005-2020 Jean Delvare <jdelvare@suse.de>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 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
* 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 <http://www.gnu.org/licenses/>.
*/
#include "hw/dmi/DmiBoard.h"
#include "3rdparty/rapidjson/document.h"
#include "hw/dmi/DmiTools.h"
void xmrig::DmiBoard::decode(dmi_header *h)
{
if (h->length < 0x08) {
return;
}
m_vendor = dmi_string(h, 0x04);
m_product = dmi_string(h, 0x05);
}
#ifdef XMRIG_FEATURE_API
rapidjson::Value xmrig::DmiBoard::toJSON(rapidjson::Document &doc) const
{
using namespace rapidjson;
auto &allocator = doc.GetAllocator();
Value out(kObjectType);
out.AddMember("vendor", m_vendor.toJSON(doc), allocator);
out.AddMember("product", m_product.toJSON(doc), allocator);
return out;
}
#endif

58
src/hw/dmi/DmiBoard.h Normal file
View file

@ -0,0 +1,58 @@
/* XMRig
* Copyright (c) 2000-2002 Alan Cox <alan@redhat.com>
* Copyright (c) 2005-2020 Jean Delvare <jdelvare@suse.de>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 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
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_DMIBOARD_H
#define XMRIG_DMIBOARD_H
#include "base/tools/String.h"
namespace xmrig {
struct dmi_header;
class DmiBoard
{
public:
DmiBoard() = default;
inline const String &product() const { return m_product; }
inline const String &vendor() const { return m_vendor; }
inline bool isValid() const { return !m_product.isEmpty() && !m_vendor.isEmpty(); }
void decode(dmi_header *h);
# ifdef XMRIG_FEATURE_API
rapidjson::Value toJSON(rapidjson::Document &doc) const;
# endif
private:
String m_product;
String m_vendor;
};
} /* namespace xmrig */
#endif /* XMRIG_DMIBOARD_H */

219
src/hw/dmi/DmiMemory.cpp Normal file
View file

@ -0,0 +1,219 @@
/* XMRig
* Copyright (c) 2000-2002 Alan Cox <alan@redhat.com>
* Copyright (c) 2005-2020 Jean Delvare <jdelvare@suse.de>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 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
* 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 <http://www.gnu.org/licenses/>.
*/
#include "hw/dmi/DmiMemory.h"
#include "3rdparty/rapidjson/document.h"
#include "hw/dmi/DmiTools.h"
#include <algorithm>
#include <array>
namespace xmrig {
static inline uint16_t dmi_memory_device_width(uint16_t code)
{
return (code == 0xFFFF || code == 0) ? 0 : code;
}
static const char *dmi_memory_device_form_factor(uint8_t code)
{
static const std::array<const char *, 0x10> form_factor
{
"Other",
"Unknown",
"SIMM",
"SIP",
"Chip",
"DIP",
"ZIP",
"Proprietary Card",
"DIMM",
"TSOP",
"Row Of Chips",
"RIMM",
"SODIMM",
"SRIMM",
"FB-DIMM",
"Die"
};
if (code >= 0x01 && code <= form_factor.size()) {
return form_factor[code - 0x01];
}
return form_factor[1];
}
static const char *dmi_memory_device_type(uint8_t code)
{
static const std::array<const char *, 0x23> type
{
"Other", /* 0x01 */
"Unknown",
"DRAM",
"EDRAM",
"VRAM",
"SRAM",
"RAM",
"ROM",
"Flash",
"EEPROM",
"FEPROM",
"EPROM",
"CDRAM",
"3DRAM",
"SDRAM",
"SGRAM",
"RDRAM",
"DDR",
"DDR2",
"DDR2 FB-DIMM",
"Reserved",
"Reserved",
"Reserved",
"DDR3",
"FBD2",
"DDR4",
"LPDDR",
"LPDDR2",
"LPDDR3",
"LPDDR4",
"Logical non-volatile device",
"HBM",
"HBM2",
"DDR5",
"LPDDR5"
};
if (code >= 0x01 && code <= type.size()) {
return type[code - 0x01];
}
return type[1];
}
static uint64_t dmi_memory_device_speed(uint16_t code1, uint32_t code2)
{
return (code1 == 0xFFFF) ? code2 : code1;
}
} // namespace xmrig
xmrig::DmiMemory::DmiMemory(dmi_header *h)
{
if (h->length < 0x15) {
return;
}
m_totalWidth = dmi_memory_device_width(dmi_get<uint16_t>(h, 0x08));
m_width = dmi_memory_device_width(dmi_get<uint16_t>(h, 0x0A));
auto size = dmi_get<uint16_t>(h, 0x0C);
if (h->length >= 0x20 && size == 0x7FFF) {
m_size = (dmi_get<uint32_t>(h, 0x1C) & 0x7FFFFFFFUL) * 1024ULL * 1024ULL;
}
else if (size) {
m_size = (1024ULL * (size & 0x7FFF) * ((size & 0x8000) ? 1 : 1024ULL));
}
m_formFactor = h->data[0x0E];
m_slot = dmi_string(h, 0x10);
m_bank = dmi_string(h, 0x11);
m_type = h->data[0x12];
if (!m_size || h->length < 0x17) {
return;
}
m_speed = dmi_memory_device_speed(dmi_get<uint16_t>(h, 0x15), h->length >= 0x5C ? dmi_get<uint32_t>(h, 0x54) : 0) * 1000000ULL;
if (h->length < 0x1B) {
return;
}
m_vendor = dmi_string(h, 0x17);
m_product = dmi_string(h, 0x1A);
if (h->length < 0x1C) {
return;
}
m_rank = h->data[0x1B] & 0x0F;
if (h->length < 0x22) {
return;
}
const uint64_t configuredSpeed = dmi_memory_device_speed(dmi_get<uint16_t>(h, 0x20), h->length >= 0x5C ? dmi_get<uint32_t>(h, 0x58) : 0) * 1000000ULL;
m_speed = configuredSpeed ? configuredSpeed : m_speed;
if (h->length < 0x28) {
return;
}
m_voltage = dmi_get<uint16_t>(h, 0x26);
}
const char *xmrig::DmiMemory::formFactor() const
{
return dmi_memory_device_form_factor(m_formFactor);
}
const char *xmrig::DmiMemory::type() const
{
return dmi_memory_device_type(m_type);
}
#ifdef XMRIG_FEATURE_API
rapidjson::Value xmrig::DmiMemory::toJSON(rapidjson::Document &doc) const
{
using namespace rapidjson;
auto &allocator = doc.GetAllocator();
Value out(kObjectType);
out.AddMember("slot", m_slot.toJSON(doc), allocator);
out.AddMember("type", StringRef(type()), allocator);
out.AddMember("form_factor", StringRef(formFactor()), allocator);
out.AddMember("size", m_size, allocator);
out.AddMember("speed", m_speed, allocator);
out.AddMember("rank", m_rank, allocator);
out.AddMember("voltage", m_voltage, allocator);
out.AddMember("width", m_width, allocator);
out.AddMember("total_width", m_totalWidth, allocator);
out.AddMember("vendor", m_vendor.toJSON(doc), allocator);
out.AddMember("product", m_product.toJSON(doc), allocator);
out.AddMember("bank", m_bank.toJSON(doc), allocator);
return out;
}
#endif

78
src/hw/dmi/DmiMemory.h Normal file
View file

@ -0,0 +1,78 @@
/* XMRig
* Copyright (c) 2000-2002 Alan Cox <alan@redhat.com>
* Copyright (c) 2005-2020 Jean Delvare <jdelvare@suse.de>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 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
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_DMIMEMORY_H
#define XMRIG_DMIMEMORY_H
#include "base/tools/String.h"
namespace xmrig {
struct dmi_header;
class DmiMemory
{
public:
DmiMemory() = default;
DmiMemory(dmi_header *h);
inline bool isValid() const { return !m_slot.isEmpty(); }
inline const String &bank() const { return m_bank; }
inline const String &product() const { return m_product; }
inline const String &slot() const { return m_slot; }
inline const String &vendor() const { return m_vendor; }
inline uint16_t totalWidth() const { return m_totalWidth; }
inline uint16_t voltage() const { return m_voltage; }
inline uint16_t width() const { return m_width; }
inline uint64_t size() const { return m_size; }
inline uint64_t speed() const { return m_speed; }
inline uint8_t rank() const { return m_rank; }
const char *formFactor() const;
const char *type() const;
# ifdef XMRIG_FEATURE_API
rapidjson::Value toJSON(rapidjson::Document &doc) const;
# endif
private:
String m_bank;
String m_product;
String m_slot;
String m_vendor;
uint16_t m_totalWidth = 0;
uint16_t m_voltage = 0;
uint16_t m_width = 0;
uint64_t m_size = 0;
uint64_t m_speed = 0;
uint8_t m_formFactor = 0;
uint8_t m_rank = 0;
uint8_t m_type = 0;
};
} /* namespace xmrig */
#endif /* XMRIG_DMIMEMORY_H */

139
src/hw/dmi/DmiReader.cpp Normal file
View file

@ -0,0 +1,139 @@
/* XMRig
* Copyright (c) 2000-2002 Alan Cox <alan@redhat.com>
* Copyright (c) 2005-2020 Jean Delvare <jdelvare@suse.de>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 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
* 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 <http://www.gnu.org/licenses/>.
*/
#include "hw/dmi/DmiReader.h"
#include "3rdparty/fmt/core.h"
#include "3rdparty/rapidjson/document.h"
#include "hw/dmi/DmiTools.h"
namespace xmrig {
static void dmi_get_header(dmi_header *h, uint8_t *data)
{
h->type = data[0];
h->length = data[1];
h->handle = dmi_get<uint16_t>(data + 2);
h->data = data;
}
} // namespace xmrig
#ifdef XMRIG_FEATURE_API
rapidjson::Value xmrig::DmiReader::toJSON(rapidjson::Document &doc) const
{
rapidjson::Value obj;
toJSON(obj, doc);
return obj;
}
void xmrig::DmiReader::toJSON(rapidjson::Value &out, rapidjson::Document &doc) const
{
using namespace rapidjson;
auto &allocator = doc.GetAllocator();
out.SetObject();
Value memory(kArrayType);
memory.Reserve(m_memory.size(), allocator);
for (const auto &value : m_memory) {
memory.PushBack(value.toJSON(doc), allocator);
}
out.AddMember("smbios", Value(fmt::format("{}.{}.{}", m_version >> 16, m_version >> 8 & 0xff, m_version & 0xff).c_str(), allocator), allocator);
out.AddMember("system", m_system.toJSON(doc), allocator);
out.AddMember("board", m_board.toJSON(doc), allocator);
out.AddMember("memory", memory, allocator);
}
#endif
bool xmrig::DmiReader::decode(uint8_t *buf, const Cleanup &cleanup)
{
const bool rc = decode(buf);
cleanup();
return rc;
}
bool xmrig::DmiReader::decode(uint8_t *buf)
{
if (!buf) {
return false;
}
uint8_t *data = buf;
int i = 0;
while (data + 4 <= buf + m_size) {
dmi_header h{};
dmi_get_header(&h, data);
if (h.length < 4 || h.type == 127) {
break;
}
i++;
uint8_t *next = data + h.length;
while (static_cast<uint32_t>(next - buf + 1) < m_size && (next[0] != 0 || next[1] != 0)) {
next++;
}
# ifdef XMRIG_OS_APPLE
while ((unsigned long)(next - buf + 1) < m_size && (next[0] == 0 && next[1] == 0))
# endif
next += 2;
if (static_cast<uint32_t>(next - buf) > m_size) {
data = next;
break;
}
switch (h.type) {
case 1:
m_system.decode(&h);
break;
case 2:
m_board.decode(&h);
break;
case 17:
m_memory.emplace_back(&h);
break;
default:
break;
}
data = next;
}
return true;
}

70
src/hw/dmi/DmiReader.h Normal file
View file

@ -0,0 +1,70 @@
/* XMRig
* Copyright (c) 2000-2002 Alan Cox <alan@redhat.com>
* Copyright (c) 2005-2020 Jean Delvare <jdelvare@suse.de>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 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
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_DMIREADER_H
#define XMRIG_DMIREADER_H
#include "hw/dmi/DmiBoard.h"
#include "hw/dmi/DmiMemory.h"
#include <functional>
namespace xmrig {
class DmiReader
{
public:
DmiReader() = default;
inline const DmiBoard &board() const { return m_board; }
inline const DmiBoard &system() const { return m_system; }
inline const std::vector<DmiMemory> &memory() const { return m_memory; }
inline uint32_t size() const { return m_size; }
inline uint32_t version() const { return m_version; }
bool read();
# ifdef XMRIG_FEATURE_API
rapidjson::Value toJSON(rapidjson::Document &doc) const;
void toJSON(rapidjson::Value &out, rapidjson::Document &doc) const;
# endif
private:
using Cleanup = std::function<void()>;
bool decode(uint8_t *buf, const Cleanup &cleanup);
bool decode(uint8_t *buf);
DmiBoard m_board;
DmiBoard m_system;
std::vector<DmiMemory> m_memory;
uint32_t m_size = 0;
uint32_t m_version = 0;
};
} /* namespace xmrig */
#endif /* XMRIG_DMIREADER_H */

View file

@ -0,0 +1,108 @@
/* XMRig
* Copyright (c) 2002-2006 Hugo Weber <address@hidden>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 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
* 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 <http://www.gnu.org/licenses/>.
*/
#include "hw/dmi/DmiReader.h"
#include "hw/dmi/DmiTools.h"
#include <Carbon/Carbon.h>
namespace xmrig {
static int checksum(const uint8_t *buf, size_t len)
{
uint8_t sum = 0;
for (size_t a = 0; a < len; a++) {
sum += buf[a];
}
return (sum == 0);
}
static uint8_t *dmi_table(uint32_t base, uint32_t &len, io_service_t service)
{
CFMutableDictionaryRef properties = nullptr;
if (IORegistryEntryCreateCFProperties(service, &properties, kCFAllocatorDefault, kNilOptions) != kIOReturnSuccess) {
return nullptr;
}
CFDataRef data;
uint8_t *buf = nullptr;
if (CFDictionaryGetValueIfPresent(properties, CFSTR("SMBIOS"), (const void **)&data)) {
assert(len == CFDataGetLength(data));
len = CFDataGetLength(data);
buf = reinterpret_cast<uint8_t *>(malloc(len));
CFDataGetBytes(data, CFRangeMake(0, len), buf);
}
CFRelease(properties);
return buf;
}
static uint8_t *smbios_decode(uint8_t *buf, uint32_t &size, uint32_t &version, io_service_t service)
{
if (buf[0x05] > 0x20 || !checksum(buf, buf[0x05]) || memcmp(buf + 0x10, "_DMI_", 5) != 0 || !checksum(buf + 0x10, 0x0F)) {
return nullptr;
}
version = ((buf[0x06] << 8) + buf[0x07]) << 8;
size = dmi_get<uint16_t>(buf + 0x16);
return dmi_table(dmi_get<uint32_t>(buf + 0x18), size, service);
}
} // namespace xmrig
bool xmrig::DmiReader::read()
{
mach_port_t port;
IOMasterPort(MACH_PORT_NULL, &port);
io_service_t service = IOServiceGetMatchingService(port, IOServiceMatching("AppleSMBIOS"));
if (service == MACH_PORT_NULL) {
return false;
}
CFDataRef data = reinterpret_cast<CFDataRef>(IORegistryEntryCreateCFProperty(service, CFSTR("SMBIOS-EPS"), kCFAllocatorDefault, kNilOptions));
if (!data) {
return false;
}
uint8_t buf[0x20]{};
CFDataGetBytes(data, CFRangeMake(0, sizeof(buf)), buf);
CFRelease(data);
auto smb = smbios_decode(buf, m_size, m_version, service);
const bool rc = smb ? decode(smb) : false;
IOObjectRelease(service);
return rc;
}

View file

@ -0,0 +1,415 @@
/* XMRig
* Copyright (c) 2000-2002 Alan Cox <alan@redhat.com>
* Copyright (c) 2005-2020 Jean Delvare <jdelvare@suse.de>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 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
* 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 <http://www.gnu.org/licenses/>.
*/
#include "hw/dmi/DmiReader.h"
#include "hw/dmi/DmiTools.h"
#include <cerrno>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <cstdio>
#ifdef __FreeBSD__
# include <kenv.h>
#endif
#define FLAG_NO_FILE_OFFSET (1 << 0)
namespace xmrig {
static const char *kMemDevice = "/dev/mem";
static const char *kSysEntryFile = "/sys/firmware/dmi/tables/smbios_entry_point";
static const char *kSysTableFile = "/sys/firmware/dmi/tables/DMI";
static inline void safe_memcpy(void *dest, const void *src, size_t n)
{
# ifdef XMRIG_ARM
for (size_t i = 0; i < n; i++) {
*((uint8_t *)dest + i) = *((const uint8_t *)src + i);
}
# else
memcpy(dest, src, n);
# endif
}
static int myread(int fd, uint8_t *buf, size_t count, const char *prefix)
{
ssize_t r = 1;
size_t r2 = 0;
while (r2 != count && r != 0) {
r = read(fd, buf + r2, count - r2);
if (r == -1) {
if (errno != EINTR) {
return -1;
}
}
else {
r2 += r;
}
}
if (r2 != count) {
return -1;
}
return 0;
}
/*
* Reads all of file from given offset, up to max_len bytes.
* A buffer of at most max_len bytes is allocated by this function, and
* needs to be freed by the caller.
* This provides a similar usage model to mem_chunk()
*
* Returns a pointer to the allocated buffer, or NULL on error, and
* sets max_len to the length actually read.
*/
static uint8_t *read_file(off_t base, size_t *max_len, const char *filename)
{
const int fd = open(filename, O_RDONLY);
uint8_t *p = nullptr;
if (fd == -1) {
return nullptr;
}
struct stat statbuf{};
if (fstat(fd, &statbuf) == 0) {
if (base >= statbuf.st_size) {
goto out;
}
if (*max_len > static_cast<size_t>(statbuf.st_size) - base) {
*max_len = statbuf.st_size - base;
}
}
if ((p = reinterpret_cast<uint8_t *>(malloc(*max_len))) == nullptr) {
goto out;
}
if (lseek(fd, base, SEEK_SET) == -1) {
goto err_free;
}
if (myread(fd, p, *max_len, filename) == 0) {
goto out;
}
err_free:
free(p);
p = nullptr;
out:
close(fd);
return p;
}
/*
* Copy a physical memory chunk into a memory buffer.
* This function allocates memory.
*/
static uint8_t *mem_chunk(off_t base, size_t len, const char *devmem)
{
const int fd = open(devmem, O_RDONLY);
uint8_t *p = nullptr;
uint8_t *mmp = nullptr;
struct stat statbuf{};
# ifdef _SC_PAGESIZE
const off_t mmoffset = base % sysconf(_SC_PAGESIZE);
# else
const off_t mmoffset = base % getpagesize();
# endif
if (fd == -1) {
return nullptr;
}
if ((p = reinterpret_cast<uint8_t *>(malloc(len))) == nullptr) {
goto out;
}
if (fstat(fd, &statbuf) == -1) {
goto err_free;
}
if (S_ISREG(statbuf.st_mode) && base + (off_t)len > statbuf.st_size) {
goto err_free;
}
mmp = reinterpret_cast<uint8_t *>(mmap(nullptr, mmoffset + len, PROT_READ, MAP_SHARED, fd, base - mmoffset));
if (mmp == MAP_FAILED) {
goto try_read;
}
safe_memcpy(p, mmp + mmoffset, len);
munmap(mmp, mmoffset + len);
goto out;
try_read:
if (lseek(fd, base, SEEK_SET) == -1) {
goto err_free;
}
if (myread(fd, p, len, devmem) == 0) {
goto out;
}
err_free:
free(p);
p = nullptr;
out:
close(fd);
return p;
}
static int checksum(const uint8_t *buf, size_t len)
{
uint8_t sum = 0;
for (size_t a = 0; a < len; a++) {
sum += buf[a];
}
return (sum == 0);
}
static uint8_t *dmi_table(off_t base, uint32_t &len, const char *devmem, uint32_t flags)
{
if (flags & FLAG_NO_FILE_OFFSET) {
size_t size = len;
auto buf = read_file(0, &size, devmem);
len = size;
return buf;
}
return mem_chunk(base, len, devmem);
}
static uint8_t *smbios3_decode(uint8_t *buf, const char *devmem, uint32_t &size, uint32_t &version, uint32_t flags)
{
if (buf[0x06] > 0x20 || !checksum(buf, buf[0x06])) {
return nullptr;
}
version = (buf[0x07] << 16) + (buf[0x08] << 8) + buf[0x09];
size = dmi_get<uint32_t>(buf + 0x0C);
const u64 offset = dmi_get<u64>(buf + 0x10);
return dmi_table(((off_t)offset.h << 32) | offset.l, size, devmem, flags);
}
static uint8_t *smbios_decode(uint8_t *buf, const char *devmem, uint32_t &size, uint32_t &version, uint32_t flags)
{
if (buf[0x05] > 0x20 || !checksum(buf, buf[0x05]) || memcmp(buf + 0x10, "_DMI_", 5) != 0 || !checksum(buf + 0x10, 0x0F)) {
return nullptr;
}
version = (buf[0x06] << 8) + buf[0x07];
switch (version) {
case 0x021F:
case 0x0221:
version = 0x0203;
break;
case 0x0233:
version = 0x0206;
break;
}
version = version << 8;
size = dmi_get<uint16_t>(buf + 0x16);
return dmi_table(dmi_get<uint32_t>(buf + 0x18), size, devmem, flags);
}
static uint8_t *legacy_decode(uint8_t *buf, const char *devmem, uint32_t &size, uint32_t &version, uint32_t flags)
{
if (!checksum(buf, 0x0F)) {
return nullptr;
}
version = ((buf[0x0E] & 0xF0) << 12) + ((buf[0x0E] & 0x0F) << 8);
size = dmi_get<uint16_t>(buf + 0x06);
return dmi_table(dmi_get<uint32_t>(buf + 0x08), size, devmem, flags);
}
#define EFI_NOT_FOUND (-1)
#define EFI_NO_SMBIOS (-2)
static off_t address_from_efi()
{
# if defined(__linux__)
FILE *efi_systab;
const char *filename;
char linebuf[64];
off_t address = 0;
# elif defined(__FreeBSD__)
char addrstr[KENV_MVALLEN + 1];
# endif
# if defined(__linux__)
if ((efi_systab = fopen(filename = "/sys/firmware/efi/systab", "r")) == nullptr && (efi_systab = fopen(filename = "/proc/efi/systab", "r")) == nullptr) {
return EFI_NOT_FOUND;
}
address = EFI_NO_SMBIOS;
while ((fgets(linebuf, sizeof(linebuf) - 1, efi_systab)) != nullptr) {
char *addrp = strchr(linebuf, '=');
*(addrp++) = '\0';
if (strcmp(linebuf, "SMBIOS3") == 0 || strcmp(linebuf, "SMBIOS") == 0) {
address = strtoull(addrp, nullptr, 0);
break;
}
}
fclose(efi_systab);
return address;
# elif defined(__FreeBSD__)
if (kenv(KENV_GET, "hint.smbios.0.mem", addrstr, sizeof(addrstr)) == -1) {
return EFI_NOT_FOUND;
}
return strtoull(addrstr, nullptr, 0);
# endif
return EFI_NOT_FOUND;
}
} // namespace xmrig
bool xmrig::DmiReader::read()
{
size_t size = 0x20;
uint8_t *buf = read_file(0, &size, kSysEntryFile);
uint8_t *smb = nullptr;
if (buf) {
smb = nullptr;
if (size >= 24 && memcmp(buf, "_SM3_", 5) == 0) {
smb = smbios3_decode(buf, kSysTableFile, m_size, m_version, FLAG_NO_FILE_OFFSET);
}
else if (size >= 31 && memcmp(buf, "_SM_", 4) == 0) {
smb = smbios_decode(buf, kSysTableFile, m_size, m_version, FLAG_NO_FILE_OFFSET);
}
else if (size >= 15 && memcmp(buf, "_DMI_", 5) == 0) {
smb = legacy_decode(buf, kSysTableFile, m_size, m_version, FLAG_NO_FILE_OFFSET);
}
if (smb) {
return decode(smb, [smb, buf]() { free(smb); free(buf); });
}
free(buf);
}
const auto efi = address_from_efi();
if (efi == EFI_NO_SMBIOS) {
return false;
}
if (efi != EFI_NOT_FOUND) {
if ((buf = mem_chunk(efi, 0x20, kMemDevice)) == nullptr) {
return false;
}
smb = nullptr;
if (memcmp(buf, "_SM3_", 5) == 0) {
smb = smbios3_decode(buf, kMemDevice, m_size, m_version, 0);
}
else if (memcmp(buf, "_SM_", 4) == 0) {
smb = smbios_decode(buf, kSysTableFile, m_size, m_version, 0);
}
if (smb) {
return decode(smb, [smb, buf]() { free(smb); free(buf); });
}
free(buf);
}
# if defined(__x86_64__) || defined(_M_AMD64)
if ((buf = mem_chunk(0xF0000, 0x10000, kMemDevice)) == nullptr) {
return false;
}
smb = nullptr;
for (off_t fp = 0; fp <= 0xFFE0; fp += 16) {
if (memcmp(buf + fp, "_SM3_", 5) == 0) {
smb = smbios3_decode(buf + fp, kMemDevice, m_size, m_version, 0);
}
if (smb) {
return decode(smb, [smb, buf]() { free(smb); free(buf); });
}
}
for (off_t fp = 0; fp <= 0xFFF0; fp += 16) {
if (memcmp(buf + fp, "_SM_", 4) == 0 && fp <= 0xFFE0) {
smb = smbios3_decode(buf + fp, kMemDevice, m_size, m_version, 0);
}
else if (!smb && memcmp(buf + fp, "_DMI_", 5) == 0) {
smb = legacy_decode(buf + fp, kMemDevice, m_size, m_version, 0);
}
if (smb) {
return decode(smb, [smb, buf]() { free(smb); free(buf); });
}
}
free(buf);
# endif
return false;
}

View file

@ -0,0 +1,68 @@
/* XMRig
* Copyright (c) 2002-2006 Hugo Weber <address@hidden>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 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
* 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 <http://www.gnu.org/licenses/>.
*/
#include "hw/dmi/DmiReader.h"
#include "hw/dmi/DmiTools.h"
#include <windows.h>
namespace xmrig {
/*
* Struct needed to get the SMBIOS table using GetSystemFirmwareTable API.
*/
struct RawSMBIOSData {
uint8_t Used20CallingMethod;
uint8_t SMBIOSMajorVersion;
uint8_t SMBIOSMinorVersion;
uint8_t DmiRevision;
uint32_t Length;
uint8_t SMBIOSTableData[];
};
} // namespace xmrig
bool xmrig::DmiReader::read()
{
const uint32_t size = GetSystemFirmwareTable('RSMB', 0, nullptr, 0);
auto smb = reinterpret_cast<RawSMBIOSData *>(HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size));
if (!smb) {
return false;
}
if (GetSystemFirmwareTable('RSMB', 0, smb, size) != size) {
HeapFree(GetProcessHeap(), 0, smb);
return false;
}
m_version = (smb->SMBIOSMajorVersion << 16) + (smb->SMBIOSMinorVersion << 8) + smb->DmiRevision;
m_size = smb->Length;
return decode(smb->SMBIOSTableData, [smb]() {
HeapFree(GetProcessHeap(), 0, smb);
});
}

75
src/hw/dmi/DmiTools.cpp Normal file
View file

@ -0,0 +1,75 @@
/* XMRig
* Copyright (c) 2000-2002 Alan Cox <alan@redhat.com>
* Copyright (c) 2005-2020 Jean Delvare <jdelvare@suse.de>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 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
* 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 <http://www.gnu.org/licenses/>.
*/
#include "hw/dmi/DmiTools.h"
#include <cstring>
namespace xmrig {
/* Replace non-ASCII characters with dots */
static void ascii_filter(char *bp, size_t len)
{
for (size_t i = 0; i < len; i++) {
if (bp[i] < 32 || bp[i] >= 127) {
bp[i] = '.';
}
}
}
static char *_dmi_string(dmi_header *dm, uint8_t s, bool filter)
{
char *bp = reinterpret_cast<char *>(dm->data);
bp += dm->length;
while (s > 1 && *bp) {
bp += strlen(bp);
bp++;
s--;
}
if (!*bp) {
return nullptr;
}
if (filter) {
ascii_filter(bp, strlen(bp));
}
return bp;
}
const char *dmi_string(dmi_header *dm, size_t offset)
{
if (offset < 4) {
return nullptr;
}
return _dmi_string(dm, dm->data[offset], true);
}
} // namespace xmrig

60
src/hw/dmi/DmiTools.h Normal file
View file

@ -0,0 +1,60 @@
/* XMRig
* Copyright (c) 2000-2002 Alan Cox <alan@redhat.com>
* Copyright (c) 2005-2020 Jean Delvare <jdelvare@suse.de>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 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
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_DMITOOLS_H
#define XMRIG_DMITOOLS_H
#include <cstddef>
#include <cstdint>
namespace xmrig {
struct dmi_header
{
uint8_t type;
uint8_t length;
uint16_t handle;
uint8_t *data;
};
struct u64 {
uint32_t l;
uint32_t h;
};
template<typename T>
inline T dmi_get(const uint8_t *data) { return *reinterpret_cast<const T *>(data); }
template<typename T>
inline T dmi_get(const dmi_header *h, size_t offset) { return *reinterpret_cast<const T *>(h->data + offset); }
const char *dmi_string(dmi_header *dm, size_t offset);
} /* namespace xmrig */
#endif /* XMRIG_DMITOOLS_H */

35
src/hw/dmi/dmi.cmake Normal file
View file

@ -0,0 +1,35 @@
if (WITH_DMI AND (XMRIG_OS_WIN OR XMRIG_OS_LINUX OR XMRIG_OS_FREEBSD OR (XMRIG_OS_MACOS AND NOT XMRIG_ARM)))
set(WITH_DMI ON)
else()
set(WITH_DMI OFF)
endif()
if (WITH_DMI)
add_definitions(/DXMRIG_FEATURE_DMI)
list(APPEND HEADERS
src/hw/dmi/DmiBoard.h
src/hw/dmi/DmiMemory.h
src/hw/dmi/DmiReader.h
src/hw/dmi/DmiTools.h
)
list(APPEND SOURCES
src/hw/dmi/DmiBoard.cpp
src/hw/dmi/DmiMemory.cpp
src/hw/dmi/DmiReader.cpp
src/hw/dmi/DmiTools.cpp
)
if (XMRIG_OS_WIN)
list(APPEND SOURCES src/hw/dmi/DmiReader_win.cpp)
elseif(XMRIG_OS_LINUX OR XMRIG_OS_FREEBSD)
list(APPEND SOURCES src/hw/dmi/DmiReader_unix.cpp)
elseif(XMRIG_OS_MACOS)
list(APPEND SOURCES src/hw/dmi/DmiReader_mac.cpp)
find_library(CORESERVICES_LIBRARY CoreServices)
list(APPEND EXTRA_LIBS ${CORESERVICES_LIBRARY})
endif()
else()
remove_definitions(/DXMRIG_FEATURE_DMI)
endif()

88
src/hw/msr/Msr.cpp Normal file
View file

@ -0,0 +1,88 @@
/* XMRig
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 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
* 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 <http://www.gnu.org/licenses/>.
*/
#include "hw/msr/Msr.h"
#include "base/io/log/Log.h"
namespace xmrig {
static const char *kTag = YELLOW_BG_BOLD(WHITE_BOLD_S " msr ");
static std::weak_ptr<Msr> instance;
} // namespace xmrig
const char *xmrig::Msr::tag()
{
return kTag;
}
std::shared_ptr<xmrig::Msr> xmrig::Msr::get()
{
auto msr = instance.lock();
if (!msr) {
msr = std::make_shared<Msr>();
instance = msr;
}
if (msr->isAvailable()) {
return msr;
}
return {};
}
bool xmrig::Msr::write(uint32_t reg, uint64_t value, int32_t cpu, uint64_t mask, bool verbose)
{
if (mask != MsrItem::kNoMask) {
uint64_t old_value;
if (rdmsr(reg, cpu, old_value)) {
value = MsrItem::maskedValue(old_value, value, mask);
}
}
const bool result = wrmsr(reg, value, cpu);
if (!result && verbose) {
LOG_WARN("%s " YELLOW_BOLD("cannot set MSR 0x%08" PRIx32 " to 0x%016" PRIx64), tag(), reg, value);
}
return result;
}
xmrig::MsrItem xmrig::Msr::read(uint32_t reg, int32_t cpu, bool verbose) const
{
uint64_t value = 0;
if (rdmsr(reg, cpu, value)) {
return { reg, value };
}
if (verbose) {
LOG_WARN("%s " YELLOW_BOLD("cannot read MSR 0x%08" PRIx32), tag(), reg);
}
return {};
}

69
src/hw/msr/Msr.h Normal file
View file

@ -0,0 +1,69 @@
/* XMRig
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 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
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_MSR_H
#define XMRIG_MSR_H
#include "base/tools/Object.h"
#include "hw/msr/MsrItem.h"
#include <functional>
#include <memory>
namespace xmrig
{
class MsrPrivate;
class Msr
{
public:
XMRIG_DISABLE_COPY_MOVE(Msr)
using Callback = std::function<bool(int32_t cpu)>;
Msr();
~Msr();
static const char *tag();
static std::shared_ptr<Msr> get();
inline bool write(const MsrItem &item, int32_t cpu = -1, bool verbose = true) { return write(item.reg(), item.value(), cpu, item.mask(), verbose); }
bool isAvailable() const;
bool write(uint32_t reg, uint64_t value, int32_t cpu = -1, uint64_t mask = MsrItem::kNoMask, bool verbose = true);
bool write(Callback &&callback);
MsrItem read(uint32_t reg, int32_t cpu = -1, bool verbose = true) const;
private:
bool rdmsr(uint32_t reg, int32_t cpu, uint64_t &value) const;
bool wrmsr(uint32_t reg, uint64_t value, int32_t cpu);
MsrPrivate *d_ptr = nullptr;
};
} /* namespace xmrig */
#endif /* XMRIG_MSR_H */

View file

@ -1,14 +1,6 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2019 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
* Copyright 2018-2019 tevador <tevador@gmail.com>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 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
@ -25,7 +17,7 @@
*/
#include "crypto/rx/msr/MsrItem.h"
#include "hw/msr/MsrItem.h"
#include "3rdparty/rapidjson/document.h"

View file

@ -1,14 +1,6 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2019 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
* Copyright 2018-2019 tevador <tevador@gmail.com>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 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
@ -39,9 +31,6 @@ namespace xmrig
{
class RxDataset;
class MsrItem
{
public:
@ -57,6 +46,11 @@ public:
inline uint64_t value() const { return m_value; }
inline uint64_t mask() const { return m_mask; }
static inline uint64_t maskedValue(uint64_t old_value, uint64_t new_value, uint64_t mask)
{
return (new_value & mask) | (old_value & ~mask);
}
rapidjson::Value toJSON(rapidjson::Document &doc) const;
String toString() const;

122
src/hw/msr/Msr_linux.cpp Normal file
View file

@ -0,0 +1,122 @@
/* XMRig
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 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
* 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 <http://www.gnu.org/licenses/>.
*/
#include "hw/msr/Msr.h"
#include "3rdparty/fmt/core.h"
#include "backend/cpu/Cpu.h"
#include "base/io/log/Log.h"
#include <array>
#include <cctype>
#include <cinttypes>
#include <cstdio>
#include <dirent.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
namespace xmrig {
static int msr_open(int32_t cpu, int flags)
{
const auto name = fmt::format("/dev/cpu/{}/msr", cpu < 0 ? Cpu::info()->units().front() : cpu);
return open(name.c_str(), flags);
}
class MsrPrivate
{
public:
bool available = true;
};
} // namespace xmrig
xmrig::Msr::Msr() : d_ptr(new MsrPrivate())
{
if (system("/sbin/modprobe msr allow_writes=on > /dev/null 2>&1") != 0) {
LOG_WARN("%s " YELLOW_BOLD("msr kernel module is not available"), Msr::tag());
d_ptr->available = false;
}
}
xmrig::Msr::~Msr()
{
delete d_ptr;
}
bool xmrig::Msr::isAvailable() const
{
return d_ptr->available;
}
bool xmrig::Msr::write(Callback &&callback)
{
const auto &units = Cpu::info()->units();
for (int32_t pu : units) {
if (!callback(pu)) {
return false;
}
}
return true;
}
bool xmrig::Msr::rdmsr(uint32_t reg, int32_t cpu, uint64_t &value) const
{
const int fd = msr_open(cpu, O_RDONLY);
if (fd < 0) {
return false;
}
const bool success = pread(fd, &value, sizeof value, reg) == sizeof value;
close(fd);
return success;
}
bool xmrig::Msr::wrmsr(uint32_t reg, uint64_t value, int32_t cpu)
{
const int fd = msr_open(cpu, O_WRONLY);
if (fd < 0) {
return false;
}
const bool success = pwrite(fd, &value, sizeof value, reg) == sizeof value;
close(fd);
return success;
}

255
src/hw/msr/Msr_win.cpp Normal file
View file

@ -0,0 +1,255 @@
/* XMRig
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2021 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
* 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 <http://www.gnu.org/licenses/>.
*/
#include "hw/msr/Msr.h"
#include "backend/cpu/Cpu.h"
#include "base/io/log/Log.h"
#include "base/kernel/Platform.h"
#include <string>
#include <thread>
#include <vector>
#include <windows.h>
#define SERVICE_NAME L"WinRing0_1_2_0"
#define IOCTL_READ_MSR CTL_CODE(40000, 0x821, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_WRITE_MSR CTL_CODE(40000, 0x822, METHOD_BUFFERED, FILE_ANY_ACCESS)
namespace xmrig {
static const wchar_t *kServiceName = SERVICE_NAME;
class MsrPrivate
{
public:
bool uninstall()
{
if (driver != INVALID_HANDLE_VALUE) {
CloseHandle(driver);
}
if (!service) {
return true;
}
bool result = true;
if (!reuse) {
SERVICE_STATUS serviceStatus;
if (!ControlService(service, SERVICE_CONTROL_STOP, &serviceStatus)) {
result = false;
}
if (!DeleteService(service)) {
LOG_ERR("%s " RED("failed to remove WinRing0 driver, error %u"), Msr::tag(), GetLastError());
result = false;
}
}
CloseServiceHandle(service);
service = nullptr;
return result;
}
bool reuse = false;
HANDLE driver = INVALID_HANDLE_VALUE;
SC_HANDLE manager = nullptr;
SC_HANDLE service = nullptr;
};
} // namespace xmrig
xmrig::Msr::Msr() : d_ptr(new MsrPrivate())
{
DWORD err = 0;
d_ptr->manager = OpenSCManager(nullptr, nullptr, SC_MANAGER_ALL_ACCESS);
if (!d_ptr->manager) {
if ((err = GetLastError()) == ERROR_ACCESS_DENIED) {
LOG_WARN("%s " YELLOW_BOLD("to access MSR registers Administrator privileges required."), tag());
}
else {
LOG_ERR("%s " RED("failed to open service control manager, error %u"), tag(), err);
}
return;
}
std::vector<wchar_t> dir;
do {
dir.resize(dir.empty() ? MAX_PATH : dir.size() * 2);
GetModuleFileNameW(nullptr, dir.data(), dir.size());
err = GetLastError();
} while (err == ERROR_INSUFFICIENT_BUFFER);
if (err != ERROR_SUCCESS) {
LOG_ERR("%s " RED("failed to get path to driver, error %u"), tag(), err);
return;
}
for (auto it = dir.end() - 1; it != dir.begin(); --it) {
if ((*it == L'\\') || (*it == L'/')) {
++it;
*it = L'\0';
break;
}
}
const std::wstring path = std::wstring(dir.data()) + L"WinRing0x64.sys";
d_ptr->service = OpenServiceW(d_ptr->manager, kServiceName, SERVICE_ALL_ACCESS);
if (d_ptr->service) {
LOG_WARN("%s " YELLOW("service ") YELLOW_BOLD("WinRing0_1_2_0") YELLOW(" already exists"), tag());
SERVICE_STATUS status;
const auto rc = QueryServiceStatus(d_ptr->service, &status);
if (rc) {
DWORD dwBytesNeeded = 0;
QueryServiceConfigA(d_ptr->service, nullptr, 0, &dwBytesNeeded);
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
std::vector<BYTE> buffer(dwBytesNeeded);
auto config = reinterpret_cast<LPQUERY_SERVICE_CONFIGA>(buffer.data());
if (QueryServiceConfigA(d_ptr->service, config, buffer.size(), &dwBytesNeeded)) {
LOG_INFO("%s " YELLOW("service path: ") YELLOW_BOLD("\"%s\""), tag(), config->lpBinaryPathName);
}
}
}
if (rc && status.dwCurrentState == SERVICE_RUNNING) {
d_ptr->reuse = true;
}
else if (!d_ptr->uninstall()) {
return;
}
}
if (!d_ptr->reuse) {
d_ptr->service = CreateServiceW(d_ptr->manager, kServiceName, kServiceName, SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, path.c_str(), nullptr, nullptr, nullptr, nullptr, nullptr);
if (!d_ptr->service) {
LOG_ERR("%s " RED("failed to install WinRing0 driver, error %u"), tag(), GetLastError());
return;
}
if (!StartService(d_ptr->service, 0, nullptr)) {
err = GetLastError();
if (err != ERROR_SERVICE_ALREADY_RUNNING) {
if (err == ERROR_FILE_NOT_FOUND) {
LOG_ERR("%s " RED("failed to start WinRing0 driver: ") RED_BOLD("\"WinRing0x64.sys not found\""), tag());
}
else {
LOG_ERR("%s " RED("failed to start WinRing0 driver, error %u"), tag(), err);
}
d_ptr->uninstall();
return;
}
}
}
d_ptr->driver = CreateFileW(L"\\\\.\\" SERVICE_NAME, GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
if (d_ptr->driver == INVALID_HANDLE_VALUE) {
LOG_ERR("%s " RED("failed to connect to WinRing0 driver, error %u"), tag(), GetLastError());;
}
}
xmrig::Msr::~Msr()
{
d_ptr->uninstall();
delete d_ptr;
}
bool xmrig::Msr::isAvailable() const
{
return d_ptr->driver != INVALID_HANDLE_VALUE;
}
bool xmrig::Msr::write(Callback &&callback)
{
const auto &units = Cpu::info()->units();
bool success = false;
std::thread thread([&callback, &units, &success]() {
for (int32_t pu : units) {
if (!Platform::setThreadAffinity(pu)) {
continue;
}
if (!callback(pu)) {
return;
}
}
success = true;
});
thread.join();
return success;
}
bool xmrig::Msr::rdmsr(uint32_t reg, int32_t cpu, uint64_t &value) const
{
assert(cpu < 0);
DWORD size = 0;
return DeviceIoControl(d_ptr->driver, IOCTL_READ_MSR, &reg, sizeof(reg), &value, sizeof(value), &size, nullptr) != 0;
}
bool xmrig::Msr::wrmsr(uint32_t reg, uint64_t value, int32_t cpu)
{
assert(cpu < 0);
struct {
uint32_t reg = 0;
uint32_t value[2]{};
} input;
static_assert(sizeof(input) == 12, "Invalid struct size for WinRing0 driver");
input.reg = reg;
*(reinterpret_cast<uint64_t*>(input.value)) = value;
DWORD output;
DWORD k;
return DeviceIoControl(d_ptr->driver, IOCTL_WRITE_MSR, &input, sizeof(input), &output, sizeof(output), &k, nullptr) != 0;
}

View file

@ -28,15 +28,15 @@
#define APP_ID "xmrig"
#define APP_NAME "XMRig"
#define APP_DESC "XMRig miner"
#define APP_VERSION "6.7.2"
#define APP_VERSION "6.8.0-dev"
#define APP_DOMAIN "xmrig.com"
#define APP_SITE "www.xmrig.com"
#define APP_COPYRIGHT "Copyright (C) 2016-2021 xmrig.com"
#define APP_KIND "miner"
#define APP_VER_MAJOR 6
#define APP_VER_MINOR 7
#define APP_VER_PATCH 2
#define APP_VER_MINOR 8
#define APP_VER_PATCH 0
#ifdef _MSC_VER
# if (_MSC_VER >= 1920)