1
0
mirror of https://github.com/xmrig/xmrig.git synced 2025-12-06 23:52:38 -05:00

Compare commits

...

74 Commits

Author SHA1 Message Date
XMRig
1bcfd0cdea v6.8.1 2021-02-03 07:00:39 +07:00
XMRig
9396ecf93d Merge branch 'dev' 2021-02-03 06:57:11 +07:00
xmrig
a4af964696 Update CHANGELOG.md 2021-02-03 06:04:30 +07:00
XMRig
2c8d8ee2ab Fixed macOS build and compile warning. 2021-02-02 13:53:45 +07:00
xmrig
631a8ca802 Merge pull request #2077 from SChernykh/dev
Fix for illegal instruction crash on ARM
2021-02-02 04:57:36 +07:00
SChernykh
346892e170 Update jit_compiler_a64.cpp 2021-02-01 22:52:02 +01:00
SChernykh
db03573804 ARM JIT: added missing cache flush 2021-02-01 22:42:35 +01:00
SChernykh
e74573f81f Fixed code allocation for ARM 2021-02-01 22:36:11 +01:00
xmrig
0e70974d7d Merge pull request #2076 from xmrig/feature-flexible-hugepages
Added support for flexible huge page sizes on Linux.
2021-02-02 04:07:41 +07:00
xmrig
3a3ee91324 Merge pull request #2075 from SChernykh/dev
Fixed crashes on ARM
2021-02-02 03:06:58 +07:00
SChernykh
4108428872 Fixed crashes on ARM 2021-02-01 17:07:45 +01:00
XMRig
4c3425a958 Added "--hugepage-size" command line option. 2021-02-01 05:06:24 +07:00
XMRig
09624c4f9b Added support for flexible huge page sizes on Linux. 2021-01-31 23:38:57 +07:00
XMRig
8faef28e7d Detect Apple M1 on Linux. 2021-01-31 05:41:32 +07:00
XMRig
62450f4ed8 Update ARM CPUs names. 2021-01-31 03:53:22 +07:00
XMRig
2c52a5a352 #2066 Fixed AMD GPUs health data readings. 2021-01-30 02:42:59 +07:00
XMRig
7d52bd7454 Extend normalization rules. 2021-01-29 18:22:24 +07:00
XMRig
f68b105bd9 Normalize DMI memory slot name. 2021-01-29 04:23:50 +07:00
XMRig
9ca1a6129b #2066 Quick fix for AMD GPUs health data. 2021-01-29 01:23:35 +07:00
xmrig
7a3df1c0bb Merge pull request #2067 from SChernykh/dev
Fix compilation error when RandomX and Argon2 are disabled
2021-01-28 20:44:03 +07:00
SChernykh
22a1b8d82d Fix compilation error when RandomX and Argon2 are disabled 2021-01-28 14:38:28 +01:00
xmrig
0a462fbef5 Merge pull request #2064 from SChernykh/dev
Added documentation for config.json CPU options
2021-01-28 19:41:15 +07:00
SChernykh
f302b4b0ef Added documentation for config.json CPU options 2021-01-28 13:37:27 +01:00
XMRig
65fe26dc6c Don't print empty memory slots if the total count above 8. 2021-01-28 00:00:00 +07:00
XMRig
e6d4921e21 v6.8.1-dev 2021-01-26 16:40:10 +07:00
XMRig
f82d67e76e Merge branch 'master' into dev 2021-01-26 16:38:37 +07:00
XMRig
4e671a945d v6.8.0 2021-01-26 15:26:16 +07:00
XMRig
e38d277143 Merge branch 'dev' 2021-01-26 15:25:20 +07:00
XMRig
8eb9b4d37a Update default config example. 2021-01-26 15:15:08 +07:00
xmrig
2d45cc64c1 Update CHANGELOG.md 2021-01-26 15:08:05 +07:00
XMRig
b9081e992b Code cleanup 2021-01-25 22:00:42 +07:00
XMRig
1424b2975f Fixed DMI memory speed. 2021-01-24 15:56:02 +07:00
XMRig
0fa5db8fa3 Code cleanup. 2021-01-24 15:02:22 +07:00
xmrig
5999dccd57 Merge pull request #2058 from SChernykh/dev
RandomX JIT x86: remove unnecessary instructions
2021-01-24 13:59:56 +07:00
SChernykh
78922a0772 RandomX JIT x86: remove unnecessary instructions
Adopted from https://github.com/tevador/RandomX/pull/201
2021-01-23 22:28:50 +01:00
XMRig
bc3914883a Merge branch 'alvv-z-patch-1' into dev 2021-01-24 02:30:22 +07:00
XMRig
86dae9e149 Merge branch 'patch-1' of https://github.com/alvv-z/xmrig into alvv-z-patch-1 2021-01-24 02:30:05 +07:00
xmrig
05b2260393 Merge pull request #2057 from xmrig/feature-msr2
Improved MSR subsystem code quality
2021-01-24 02:28:54 +07:00
XMRig
672f6df6c1 Fixed Cache QoS restore on exit where it not supported. 2021-01-24 02:23:27 +07:00
XMRig
9dae559b73 Added RxMsr class. 2021-01-23 23:23:39 +07:00
XMRig
b9d813c403 Move Ryzen related fixes to RxFix class. 2021-01-23 00:27:56 +07:00
XMRig
c48e2e6af8 Added new class Msr. 2021-01-22 23:50:25 +07:00
xmrig
76fba819fe Merge pull request #2055 from GoDzM4TT3O/patch-1
Add missing "cstdio" library
2021-01-22 22:19:41 +07:00
GoDzM4TT3O
6bab624885 Add missing "cstdio" library
Compilation fails if the above library is missing. This fixes a compilation error.
2021-01-22 14:18:28 +01:00
XMRig
3730bcd434 Merge branch 'master' into feature-msr2 2021-01-22 16:55:57 +07:00
XMRig
3b7d30a91d v6.8.0-dev 2021-01-22 00:27:38 +07:00
XMRig
c8588903e3 Enable DMI reader by default. 2021-01-22 00:12:34 +07:00
xmrig
0b4fec15dd Merge pull request #2052 from xmrig/feature-dmi
Added DMI/SMBIOS reader
2021-01-22 00:09:10 +07:00
XMRig
ef8cc28f3f Added DMI data to online benchmark. 2021-01-21 23:22:01 +07:00
XMRig
8471f7fad3 Added "GET /2/dmi" API endpoint. 2021-01-20 22:54:02 +07:00
alvv-z
b99dc440af Spelling Check
agaiin -> again
2021-01-20 12:36:47 +01:00
XMRig
9a02007900 Added config option "dmi" and command line option "--no-dmi". 2021-01-20 16:02:48 +07:00
XMRig
efc5e5d811 Fix summary. 2021-01-20 00:45:36 +07:00
XMRig
dea5be0a57 Added basic system reader. 2021-01-20 00:43:01 +07:00
XMRig
24c290963a Added DMI reader for macOS. 2021-01-19 14:16:03 +07:00
XMRig
9dffcdaddd Enable FreeBSD support. 2021-01-19 01:45:17 +07:00
XMRig
3df47052ed Added legacy DMI readers for Linux. 2021-01-19 01:23:09 +07:00
XMRig
3b8d081c8c Add support for older DMI formats on Linux. 2021-01-18 22:56:57 +07:00
XMRig
05e6f66169 Added basic Linux support. 2021-01-18 16:53:42 +07:00
XMRig
11e0d3de3a Added DMI reader (Windows only). 2021-01-18 11:23:29 +07:00
XMRig
ea367da064 #2043 Fix compile warning. 2021-01-17 17:48:35 +07:00
xmrig
a999a56775 Merge pull request #2041 from coldiron/typo-fixes
fixed grammar in a couple of awkward error messages
2021-01-16 10:15:29 +07:00
Richard Mitsuk Lavitt
590252bd5e fixed grammar in a couple of awkward error messages 2021-01-15 14:33:38 -06:00
XMRig
cc2de4f768 v6.7.3-dev 2021-01-15 20:11:28 +07:00
XMRig
aeea0e0a6c Merge branch 'master' into dev 2021-01-15 20:09:26 +07:00
XMRig
82d698a1e5 v6.7.2 2021-01-15 19:31:41 +07:00
XMRig
95b2b5e028 Merge branch 'dev' 2021-01-15 19:31:09 +07:00
xmrig
eae84d47e7 Update CHANGELOG.md 2021-01-15 19:30:22 +07:00
XMRig
45d12314f4 Sync changes. 2021-01-15 19:18:52 +07:00
xmrig
fa11cb623d Merge pull request #2039 from SChernykh/dev
Fixed solo mining
2021-01-15 18:49:04 +07:00
SChernykh
7da04c6a2c Always use cvt_bin2hex 2021-01-15 12:46:27 +01:00
SChernykh
5c449913af Fixed solo mining
It was broken since 6.7.0
2021-01-15 11:18:36 +01:00
XMRig
af019fed8e v6.7.2-dev 2021-01-11 18:29:56 +07:00
XMRig
8872630c46 Merge branch 'master' into dev 2021-01-11 18:29:06 +07:00
88 changed files with 3238 additions and 1254 deletions

View File

@@ -1,3 +1,22 @@
# v6.8.1
- [#2064](https://github.com/xmrig/xmrig/pull/2064) Added documentation for config.json CPU options.
- [#2066](https://github.com/xmrig/xmrig/issues/2066) Fixed AMD GPUs health data readings on Linux.
- [#2067](https://github.com/xmrig/xmrig/pull/2067) Fixed compilation error when RandomX and Argon2 are disabled.
- [#2076](https://github.com/xmrig/xmrig/pull/2076) Added support for flexible huge page sizes on Linux.
- [#2077](https://github.com/xmrig/xmrig/pull/2077) Fixed `illegal instruction` crash on ARM.
# 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.
# v6.7.1
- [#1995](https://github.com/xmrig/xmrig/issues/1995) Fixed log initialization.
- [#1998](https://github.com/xmrig/xmrig/pull/1998) Added hashrate in the benchmark finished message.

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

@@ -75,6 +75,35 @@ Each number represent one thread and means CPU affinity, this is default format
```
Internal format, but can be user defined.
## RandomX options
#### `init`
Thread count to initialize RandomX dataset. Auto-detect (`-1`) or any number greater than 0 to use that many threads.
#### `init-avx2`
Use AVX2 for dataset initialization. Faster on some CPUs. Auto-detect (`-1`), disabled (`0`), always enabled on CPUs that support AVX2 (`1`).
#### `mode`
RandomX mining mode: `auto`, `fast` (2 GB memory), `light` (256 MB memory).
#### `1gb-pages`
Use 1GB hugepages for RandomX dataset (Linux only). Enabled (`true`) or disabled (`false`). It gives 1-3% speedup.
#### `rdmsr`
Restore MSR register values to their original values on exit. Used together with `wrmsr`. Enabled (`true`) or disabled (`false`).
#### `wrmsr`
[MSR mod](https://xmrig.com/docs/miner/randomx-optimization-guide/msr). Enabled (`true`) or disabled (`false`). It gives up to 15% speedup depending on your system.
#### `cache_qos`
[Cache QoS](https://xmrig.com/docs/miner/randomx-optimization-guide/qos). Enabled (`true`) or disabled (`false`). It's useful when you can't or don't want to mine on all CPU cores to make mining hashrate more stable.
#### `numa`
NUMA support (better hashrate on multi-CPU servers and Ryzen Threadripper 1xxx/2xxx). Enabled (`true`) or disabled (`false`).
#### `scratchpad_prefetch_mode`
Which instruction to use in RandomX loop to prefetch data from scratchpad. `1` is default and fastest in most cases. Can be off (`0`), `prefetcht0` instruction (`1`), `prefetchnta` instruction (`2`, a bit faster on Coffee Lake and a few other CPUs), `mov` instruction (`3`).
## Shared options
#### `enabled`
@@ -83,23 +112,32 @@ Enable (`true`) or disable (`false`) CPU backend, by default `true`.
#### `huge-pages`
Enable (`true`) or disable (`false`) huge pages support, by default `true`.
#### `huge-pages-jit`
Enable (`true`) or disable (`false`) huge pages support for RandomX JIT code, by default `false`. It gives a very small boost on Ryzen CPUs, but hashrate is unstable between launches. Use with caution.
#### `hw-aes`
Force enable (`true`) or disable (`false`) hardware AES support. Default value `null` means miner autodetect this feature. Usually don't need change this option, this option useful for some rare cases when miner can't detect hardware AES, but it available. If you force enable this option, but your hardware not support it, miner will crash.
#### `priority`
Mining threads priority, value from `1` (lowest priority) to `5` (highest possible priority). Default value `null` means miner don't change threads priority at all.
Mining threads priority, value from `1` (lowest priority) to `5` (highest possible priority). Default value `null` means miner don't change threads priority at all. Setting priority higher than 2 can make your PC unresponsive.
#### `memory-pool` (since v4.3.0)
Use continuous, persistent memory block for mining threads, useful for preserve huge pages allocation while algorithm swithing. Possible values `false` (feature disabled, by default) or `true` or specific count of 2 MB huge pages. It helps to avoid loosing huge pages for scratchpads when RandomX dataset is updated and mining threads restart after a 2-3 days of mining.
#### `yield` (since v5.1.1)
Prefer system better system response/stability `true` (default value) or maximum hashrate `false`.
#### `asm`
Enable/configure or disable ASM optimizations. Possible values: `true`, `false`, `"intel"`, `"ryzen"`, `"bulldozer"`.
#### `argon2-impl` (since v3.1.0)
Allow override automatically detected Argon2 implementation, this option added mostly for debug purposes, default value `null` means autodetect. Other possible values: `"x86_64"`, `"SSE2"`, `"SSSE3"`, `"XOP"`, `"AVX2"`, `"AVX-512F"`. Manual selection has no safe guards, if you CPU not support required instuctions, miner will crash.
Allow override automatically detected Argon2 implementation, this option added mostly for debug purposes, default value `null` means autodetect. This is used in RandomX dataset initialization and also in some other mining algorithms. Other possible values: `"x86_64"`, `"SSE2"`, `"SSSE3"`, `"XOP"`, `"AVX2"`, `"AVX-512F"`. Manual selection has no safe guards - if your CPU doesn't support required instuctions, miner will crash.
#### `astrobwt-max-size`
AstroBWT algorithm: skip hashes with large stage 2 size, default: `550`, min: `400`, max: `1200`. Optimal value depends on your CPU/GPU
#### `astrobwt-avx2`
AstroBWT algorithm: use AVX2 code. It's faster on some CPUs and slower on other
#### `max-threads-hint` (since v4.2.0)
Maximum CPU threads count (in percentage) hint for autoconfig. [CPU_MAX_USAGE.md](CPU_MAX_USAGE.md)
#### `memory-pool` (since v4.3.0)
Use continuous, persistent memory block for mining threads, useful for preserve huge pages allocation while algorithm swithing. Possible values `false` (feature disabled, by default) or `true` or specific count of 2 MB huge pages.
#### `yield` (since v5.1.1)
Prefer system better system response/stability `true` (default value) or maximum hashrate `false`.

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 printEmpty = reader.memory().size() <= 8;
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.id().data(), memory.size() / oneGiB, memory.type(), memory.speed() / 1000000ULL, memory.product().data());
}
else if (printEmpty) {
Log::print(WHITE_BOLD(" %-13s") "%s: " BLACK_BOLD("<empty>"), "", memory.slot().data());
}
}
const auto &board = Cpu::info()->isVM() ? 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,13 +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 Lee Clagett <https://github.com/vtnerd>
* 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
@@ -42,10 +35,15 @@ public:
PciTopology() = default;
PciTopology(uint32_t bus, uint32_t device, uint32_t function) : m_valid(true), m_bus(bus), m_device(device), m_function(function) {}
inline bool isValid() const { return m_valid; }
inline uint8_t bus() const { return m_bus; }
inline uint8_t device() const { return m_device; }
inline uint8_t function() const { return m_function; }
inline bool isEqual(const PciTopology &other) const { return m_valid == other.m_valid && toUint32() == other.toUint32(); }
inline bool isValid() const { return m_valid; }
inline uint8_t bus() const { return m_bus; }
inline uint8_t device() const { return m_device; }
inline uint8_t function() const { return m_function; }
inline bool operator!=(const PciTopology &other) const { return !isEqual(other); }
inline bool operator<(const PciTopology &other) const { return toUint32() < other.toUint32(); }
inline bool operator==(const PciTopology &other) const { return isEqual(other); }
String toString() const
{
@@ -60,6 +58,8 @@ public:
}
private:
inline uint32_t toUint32() const { return m_bus << 16 | m_device << 8 | m_function; }
bool m_valid = false;
uint8_t m_bus = 0;
uint8_t m_device = 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-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
@@ -77,7 +71,7 @@ rapidjson::Value xmrig::CpuConfig::toJSON(rapidjson::Document &doc) const
Value obj(kObjectType);
obj.AddMember(StringRef(kEnabled), m_enabled, allocator);
obj.AddMember(StringRef(kHugePages), m_hugePages, allocator);
obj.AddMember(StringRef(kHugePages), m_hugePageSize == 0 || m_hugePageSize == kDefaultHugePageSizeKb ? Value(isHugePages()) : Value(static_cast<uint32_t>(m_hugePageSize)), allocator);
obj.AddMember(StringRef(kHugePagesJit), m_hugePagesJit, allocator);
obj.AddMember(StringRef(kHwAes), m_aes == AES_AUTO ? Value(kNullType) : Value(m_aes == AES_HW), allocator);
obj.AddMember(StringRef(kPriority), priority() != -1 ? Value(priority()) : Value(kNullType), allocator);
@@ -137,14 +131,14 @@ void xmrig::CpuConfig::read(const rapidjson::Value &value)
{
if (value.IsObject()) {
m_enabled = Json::getBool(value, kEnabled, m_enabled);
m_hugePages = Json::getBool(value, kHugePages, m_hugePages);
m_hugePagesJit = Json::getBool(value, kHugePagesJit, m_hugePagesJit);
m_limit = Json::getUint(value, kMaxThreadsHint, m_limit);
m_yield = Json::getBool(value, kYield, m_yield);
setAesMode(Json::getValue(value, kHwAes));
setPriority(Json::getInt(value, kPriority, -1));
setHugePages(Json::getValue(value, kHugePages));
setMemoryPool(Json::getValue(value, kMemoryPool));
setPriority(Json::getInt(value, kPriority, -1));
# ifdef XMRIG_FEATURE_ASM
m_assembly = Json::getValue(value, kAsm);
@@ -218,6 +212,19 @@ void xmrig::CpuConfig::setAesMode(const rapidjson::Value &value)
}
void xmrig::CpuConfig::setHugePages(const rapidjson::Value &value)
{
if (value.IsBool()) {
m_hugePageSize = value.GetBool() ? kDefaultHugePageSizeKb : 0U;
}
else if (value.IsUint()) {
const uint32_t size = value.GetUint();
m_hugePageSize = size < kOneGbPageSizeKb ? size : kDefaultHugePageSizeKb;
}
}
void xmrig::CpuConfig::setMemoryPool(const rapidjson::Value &value)
{
if (value.IsBool()) {

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 (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
@@ -75,8 +69,9 @@ public:
std::vector<CpuLaunchData> get(const Miner *miner, const Algorithm &algorithm) const;
void read(const rapidjson::Value &value);
inline bool astrobwtAVX2() const { return m_astrobwtAVX2; }
inline bool isEnabled() const { return m_enabled; }
inline bool isHugePages() const { return m_hugePages; }
inline bool isHugePages() const { return m_hugePageSize > 0; }
inline bool isHugePagesJit() const { return m_hugePagesJit; }
inline bool isShouldSave() const { return m_shouldSave; }
inline bool isYield() const { return m_yield; }
@@ -84,13 +79,17 @@ public:
inline const String &argon2Impl() const { return m_argon2Impl; }
inline const Threads<CpuThreads> &threads() const { return m_threads; }
inline int astrobwtMaxSize() const { return m_astrobwtMaxSize; }
inline bool astrobwtAVX2() const { return m_astrobwtAVX2; }
inline int priority() const { return m_priority; }
inline size_t hugePageSize() const { return m_hugePageSize * 1024U; }
inline uint32_t limit() const { return m_limit; }
private:
constexpr static size_t kDefaultHugePageSizeKb = 2048U;
constexpr static size_t kOneGbPageSizeKb = 1048576U;
void generate();
void setAesMode(const rapidjson::Value &value);
void setHugePages(const rapidjson::Value &value);
void setMemoryPool(const rapidjson::Value &value);
inline void setPriority(int priority) { m_priority = (priority >= -1 && priority <= 5) ? priority : -1; }
@@ -99,13 +98,13 @@ private:
Assembly m_assembly;
bool m_astrobwtAVX2 = false;
bool m_enabled = true;
bool m_hugePages = true;
bool m_hugePagesJit = false;
bool m_shouldSave = false;
bool m_yield = true;
int m_astrobwtMaxSize = 550;
int m_memoryPool = 0;
int m_priority = -1;
size_t m_hugePageSize = kDefaultHugePageSizeKb;
String m_argon2Impl;
Threads<CpuThreads> m_threads;
uint32_t m_limit = 100;

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,7 +1,7 @@
/* XMRig
* Copyright (c) 2018 Riku Voipio <riku.voipio@iki.fi>
* 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
@@ -87,16 +87,22 @@ static const id_part arm_part[] = {
{ 0xd03, "Cortex-A53" },
{ 0xd04, "Cortex-A35" },
{ 0xd05, "Cortex-A55" },
{ 0xd06, "Cortex-A65" },
{ 0xd07, "Cortex-A57" },
{ 0xd08, "Cortex-A72" },
{ 0xd09, "Cortex-A73" },
{ 0xd0a, "Cortex-A75" },
{ 0xd0b, "Cortex-A76" },
{ 0xd0c, "Neoverse-N1" },
{ 0xd0d, "Cortex-A77" },
{ 0xd0e, "Cortex-A76AE" },
{ 0xd13, "Cortex-R52" },
{ 0xd20, "Cortex-M23" },
{ 0xd21, "Cortex-M33" },
{ 0xd41, "Cortex-A78" },
{ 0xd42, "Cortex-A78AE" },
{ 0xd4a, "Neoverse-E1" },
{ 0xd4b, "Cortex-A78C" },
{ -1, nullptr },
};
@@ -150,6 +156,7 @@ static const id_part samsung_part[] = {
static const id_part nvidia_part[] = {
{ 0x000, "Denver" },
{ 0x003, "Denver 2" },
{ 0x004, "Carmel" },
{ -1, nullptr },
};
@@ -191,23 +198,36 @@ static const id_part intel_part[] = {
{ -1, nullptr },
};
static const struct id_part fujitsu_part[] = {
{ 0x001, "A64FX" },
{ -1, "unknown" },
};
static const id_part hisi_part[] = {
{ 0xd01, "Kunpeng-920" }, /* aka tsv110 */
{ -1, nullptr },
};
static const id_part apple_part[] = {
{ 0x022, "M1" },
{ 0x023, "M1" },
{ -1, nullptr },
};
static const hw_impl hw_implementer[] = {
{ 0x41, arm_part, "ARM" },
{ 0x42, brcm_part, "Broadcom" },
{ 0x43, cavium_part, "Cavium" },
{ 0x44, dec_part, "DEC" },
{ 0x46, fujitsu_part, "FUJITSU" },
{ 0x48, hisi_part, "HiSilicon" },
{ 0x4e, nvidia_part, "Nvidia" },
{ 0x50, apm_part, "APM" },
{ 0x51, qcom_part, "Qualcomm" },
{ 0x53, samsung_part, "Samsung" },
{ 0x56, marvell_part, "Marvell" },
{ 0x61, apple_part, "Apple" },
{ 0x66, faraday_part, "Faraday" },
{ 0x69, intel_part, "Intel" }
};

View File

@@ -1,8 +1,8 @@
/* XMRig
* Copyright 2008-2018 Advanced Micro Devices, Inc.
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2020 Patrick Bollinger <https://github.com/pjbollinger>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright (c) 2008-2018 Advanced Micro Devices, Inc.
* Copyright (c) 2020 Patrick Bollinger <https://github.com/pjbollinger>
* 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
@@ -20,10 +20,13 @@
#include "backend/opencl/wrappers/AdlLib.h"
#include "3rdparty/fmt/core.h"
#include "backend/opencl/wrappers/OclDevice.h"
#include <dirent.h>
#include <fstream>
#include <map>
#include <string>
#include <sys/stat.h>
#include <sys/types.h>
@@ -35,18 +38,27 @@ namespace xmrig {
bool AdlLib::m_initialized = false;
bool AdlLib::m_ready = false;
static const std::string kPrefix = "/sys/bus/pci/drivers/amdgpu/";
static std::map<PciTopology, std::string> hwmon_cache;
static inline bool sysfs_is_file(const std::string &path)
static inline bool sysfs_is_file(const char *path)
{
struct stat sb;
return stat(path.c_str(), &sb) == 0 && ((sb.st_mode & S_IFMT) == S_IFREG);
return stat(path, &sb) == 0 && ((sb.st_mode & S_IFMT) == S_IFREG);
}
static inline bool sysfs_is_amdgpu(const std::string &path)
static inline int dir_filter(const struct dirent *dirp)
{
return strlen(dirp->d_name) > 5 ? 1 : 0;
}
static bool sysfs_is_amdgpu(const char *path, char *buf, const char *filename)
{
strcpy(buf, filename);
if (!sysfs_is_file(path)) {
return false;
}
@@ -63,8 +75,10 @@ static inline bool sysfs_is_amdgpu(const std::string &path)
}
uint32_t sysfs_read(const std::string &path)
static uint32_t sysfs_read(const char *path, char *buf, const char *filename)
{
strcpy(buf, filename);
std::ifstream file(path);
if (!file.is_open()) {
return 0;
@@ -77,18 +91,44 @@ uint32_t sysfs_read(const std::string &path)
}
static inline std::string sysfs_prefix(const PciTopology &topology)
static size_t sysfs_prefix(char path[PATH_MAX], const PciTopology &topology)
{
const std::string path = kPrefix + "0000:" + topology.toString().data() + "/hwmon/hwmon";
const auto it = hwmon_cache.find(topology);
if (it != hwmon_cache.end()) {
strcpy(path, it->second.data());
for (uint32_t i = 1; i < 10; ++i) {
const std::string prefix = path + std::to_string(i) + "/";
if (sysfs_is_amdgpu(prefix + "name") && (sysfs_read(prefix + "temp1_input") || sysfs_read(prefix + "power1_average"))) {
return prefix;
}
return it->second.size();
}
return {};
char *base = fmt::format_to(path, "{}0000:{}/hwmon/", kPrefix, topology.toString());
*base = '\0';
char *end = nullptr;
struct dirent **namelist;
int n = scandir(path, &namelist, dir_filter, nullptr);
if (n < 0) {
return {};
}
while (n--) {
if (!end) {
char *tmp = fmt::format_to(base, "{}/", namelist[n]->d_name);
end = (sysfs_is_amdgpu(path, tmp, "name") && (sysfs_read(path, tmp, "temp1_input") || sysfs_read(path, tmp, "power1_average"))) ? tmp : nullptr;
}
free(namelist[n]);
}
free(namelist);
if (end) {
*end = '\0';
hwmon_cache.insert({ topology, path });
return end - path;
}
return 0;
}
@@ -124,20 +164,22 @@ AdlHealth xmrig::AdlLib::health(const OclDevice &device)
return {};
}
const auto prefix = sysfs_prefix(device.topology());
if (prefix.empty()) {
static char path[PATH_MAX]{};
char *buf = path + sysfs_prefix(path, device.topology());
if (buf == path) {
return {};
}
AdlHealth health;
health.clock = sysfs_read(prefix + "freq1_input") / 1000000;
health.memClock = sysfs_read(prefix + "freq2_input") / 1000000;
health.power = sysfs_read(prefix + "power1_average") / 1000000;
health.rpm = sysfs_read(prefix + "fan1_input");
health.temperature = sysfs_read(prefix + "temp2_input") / 1000;
health.clock = sysfs_read(path, buf, "freq1_input") / 1000000;
health.memClock = sysfs_read(path, buf, "freq2_input") / 1000000;
health.power = sysfs_read(path, buf, "power1_average") / 1000000;
health.rpm = sysfs_read(path, buf, "fan1_input");
health.temperature = sysfs_read(path, buf, "temp2_input") / 1000;
if (!health.temperature) {
health.temperature = sysfs_read(prefix + "temp1_input") / 1000;
health.temperature = sysfs_read(path, buf, "temp1_input") / 1000;
}
return health;

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,8 @@ public:
BenchSeedKey = 1046,
BenchHashKey = 1047,
BenchTokenKey = 1048,
DmiKey = 1049,
HugePageSizeKey = 1050,
// xmrig common
CPUPriorityKey = 1021,

View File

@@ -104,7 +104,7 @@ int64_t xmrig::DaemonClient::submit(const JobResult &result)
# ifdef XMRIG_PROXY_PROJECT
memcpy(data + 78, result.nonce, 8);
# else
Cvt::toHex(data + 78, 9, reinterpret_cast<const uint8_t *>(&result.nonce), 4);
Cvt::toHex(data + 78, 8, reinterpret_cast<const uint8_t *>(&result.nonce), 4);
# endif
using namespace rapidjson;
@@ -227,7 +227,7 @@ bool xmrig::DaemonClient::parseJob(const rapidjson::Value &params, int *code)
m_blockhashingblob = Json::getString(params, "blockhashing_blob");
if (m_apiVersion == API_DERO) {
const uint64_t offset = Json::getUint64(params, "reserved_offset");
Cvt::toHex(m_blockhashingblob.data() + offset * 2, kBlobReserveSize * 2 + 1, Cvt::randomBytes(kBlobReserveSize).data(), kBlobReserveSize);
Cvt::toHex(m_blockhashingblob.data() + offset * 2, kBlobReserveSize * 2, Cvt::randomBytes(kBlobReserveSize).data(), kBlobReserveSize);
}
if (blocktemplate.isNull() || !job.setBlob(m_blockhashingblob)) {

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

@@ -1,7 +1,7 @@
/* XMRig
* Copyright (c) 2013-2020 Frank Denis <j at pureftpd dot org>
* 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,11 +34,6 @@
namespace xmrig {
#ifndef XMRIG_SODIUM
static std::random_device randomDevice;
static std::mt19937 randomEngine(randomDevice());
static char *cvt_bin2hex(char *const hex, const size_t hex_maxlen, const unsigned char *const bin, const size_t bin_len)
{
size_t i = 0U;
@@ -46,7 +41,7 @@ static char *cvt_bin2hex(char *const hex, const size_t hex_maxlen, const unsigne
int b;
int c;
if (bin_len >= SIZE_MAX / 2 || hex_maxlen <= bin_len * 2U) {
if (bin_len >= SIZE_MAX / 2 || hex_maxlen < bin_len * 2U) {
return nullptr; /* LCOV_EXCL_LINE */
}
@@ -60,12 +55,20 @@ static char *cvt_bin2hex(char *const hex, const size_t hex_maxlen, const unsigne
hex[i * 2U + 1U] = (char) x;
i++;
}
hex[i * 2U] = 0U;
if (i * 2U < hex_maxlen) {
hex[i * 2U] = 0U;
}
return hex;
}
#ifndef XMRIG_SODIUM
static std::random_device randomDevice;
static std::mt19937 randomEngine(randomDevice());
static int cvt_hex2bin(unsigned char *const bin, const size_t bin_maxlen, const char *const hex, const size_t hex_len, const char *const ignore, size_t *const bin_len, const char **const hex_end)
{
size_t bin_pos = 0U;
@@ -137,7 +140,6 @@ static int cvt_hex2bin(unsigned char *const bin, const size_t bin_maxlen, const
return ret;
}
#define sodium_bin2hex cvt_bin2hex
#define sodium_hex2bin cvt_hex2bin
#endif
@@ -215,7 +217,7 @@ xmrig::Buffer xmrig::Cvt::fromHex(const char *in, size_t size)
bool xmrig::Cvt::toHex(char *hex, size_t hex_maxlen, const uint8_t *bin, size_t bin_len)
{
return sodium_bin2hex(hex, hex_maxlen, bin, bin_len) != nullptr;
return cvt_bin2hex(hex, hex_maxlen, bin, bin_len) != nullptr;
}
@@ -273,3 +275,17 @@ xmrig::String xmrig::Cvt::toHex(const uint8_t *in, size_t size)
return buf;
}
void xmrig::Cvt::randomBytes(void *buf, size_t size)
{
# ifndef XMRIG_SODIUM
std::uniform_int_distribution<> dis(0, 255);
for (size_t i = 0; i < size; ++i) {
static_cast<uint8_t *>(buf)[i] = static_cast<char>(dis(randomEngine));
}
# else
randombytes_buf(buf, size);
# endif
}

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,6 +52,7 @@ public:
static rapidjson::Value toHex(const std::string &data, rapidjson::Document &doc);
static rapidjson::Value toHex(const uint8_t *in, size_t size, rapidjson::Document &doc);
static String toHex(const uint8_t *in, size_t size);
static void randomBytes(void *buf, size_t size);
};

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();
}
@@ -52,9 +50,14 @@ int xmrig::Controller::init()
{
Base::init();
VirtualMemory::init(config()->cpu().memPoolSize(), config()->cpu().isHugePages());
VirtualMemory::init(config()->cpu().memPoolSize(), config()->cpu().hugePageSize());
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
}
@@ -133,9 +125,10 @@ void xmrig::ConfigTransform::transform(rapidjson::Document &doc, int key, const
BaseTransform::transform(doc, key, arg);
switch (key) {
case IConfig::AVKey: /* --av */
case IConfig::CPUPriorityKey: /* --cpu-priority */
case IConfig::ThreadsKey: /* --threads */
case IConfig::AVKey: /* --av */
case IConfig::CPUPriorityKey: /* --cpu-priority */
case IConfig::ThreadsKey: /* --threads */
case IConfig::HugePageSizeKey: /* --hugepage-size */
return transformUint64(doc, key, static_cast<uint64_t>(strtol(arg, nullptr, 10)));
case IConfig::HugePagesKey: /* --no-huge-pages */
@@ -157,8 +150,10 @@ void xmrig::ConfigTransform::transform(rapidjson::Document &doc, int key, const
case IConfig::YieldKey: /* --cpu-no-yield */
return set(doc, CpuConfig::kField, CpuConfig::kYield, false);
# ifdef XMRIG_ALGO_ARGON2
case IConfig::Argon2ImplKey: /* --argon2-impl */
return set(doc, CpuConfig::kField, CpuConfig::kArgon2Impl, arg);
# endif
# ifdef XMRIG_FEATURE_ASM
case IConfig::AssemblyKey: /* --asm */
@@ -208,47 +203,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
@@ -305,6 +307,9 @@ void xmrig::ConfigTransform::transformUint64(rapidjson::Document &doc, int key,
case IConfig::CPUPriorityKey: /* --cpu-priority */
return set(doc, CpuConfig::kField, CpuConfig::kPriority, arg);
case IConfig::HugePageSizeKey: /* --hugepage-size */
return set(doc, CpuConfig::kField, CpuConfig::kHugePages, arg);
default:
break;
}

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

@@ -71,6 +71,8 @@ static const option options[] = {
{ "nicehash", 0, nullptr, IConfig::NicehashKey },
{ "no-color", 0, nullptr, IConfig::ColorKey },
{ "no-huge-pages", 0, nullptr, IConfig::HugePagesKey },
{ "no-hugepages", 0, nullptr, IConfig::HugePagesKey },
{ "hugepage-size", 1, nullptr, IConfig::HugePageSizeKey },
{ "pass", 1, nullptr, IConfig::PasswordKey },
{ "print-time", 1, nullptr, IConfig::PrintTimeKey },
{ "retries", 1, nullptr, IConfig::RetriesKey },
@@ -155,7 +157,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

@@ -83,6 +83,9 @@ static inline const std::string &usage()
u += " --cpu-memory-pool=N number of 2 MB pages for persistent memory pool, -1 (auto), 0 (disable)\n";
u += " --cpu-no-yield prefer maximum hashrate rather than system response/stability\n";
u += " --no-huge-pages disable huge pages support\n";
# ifdef XMRIG_OS_LINUX
u += " --hugepage-size=N custom hugepage size in kB\n";
# endif
u += " --asm=ASM ASM optimizations, possible values: auto, none, intel, ryzen, bulldozer\n";
# if defined(__x86_64__) || defined(_M_AMD64)
@@ -155,7 +158,7 @@ static inline const std::string &usage()
u += " -l, --log-file=FILE log all output to a file\n";
u += " --print-time=N print hashrate report every N seconds\n";
# ifdef XMRIG_FEATURE_NVML
# if defined(XMRIG_FEATURE_NVML) || defined(XMRIG_FEATURE_ADL)
u += " --health-print-time=N print health report every N seconds\n";
# endif
u += " --no-color disable colored output\n";
@@ -190,6 +193,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

@@ -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
@@ -27,24 +21,16 @@
#include "crypto/common/VirtualMemory.h"
namespace xmrig {
constexpr size_t twoMiB = 2U * 1024U * 1024U;
constexpr size_t oneGiB = 1024U * 1024U * 1024U;
} // namespace xmrig
xmrig::HugePagesInfo::HugePagesInfo(const VirtualMemory *memory)
{
if (memory->isOneGbPages()) {
size = VirtualMemory::align(memory->size(), oneGiB);
total = size / oneGiB;
allocated = size / oneGiB;
size = VirtualMemory::align(memory->size(), VirtualMemory::kOneGiB);
total = size / VirtualMemory::kOneGiB;
allocated = size / VirtualMemory::kOneGiB;
}
else {
size = memory->size();
total = size / twoMiB;
size = VirtualMemory::alignToHugePageSize(memory->size());
total = size / VirtualMemory::hugePageSize();
allocated = memory->isHugePages() ? total : 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 (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
@@ -18,8 +18,6 @@
#include "crypto/common/LinuxMemory.h"
#include "3rdparty/fmt/core.h"
#include "backend/cpu/Cpu.h"
#include "base/io/log/Log.h"
#include "crypto/common/VirtualMemory.h"
@@ -37,33 +35,32 @@ constexpr size_t twoMiB = 2U * 1024U * 1024U;
constexpr size_t oneGiB = 1024U * 1024U * 1024U;
static inline std::string sysfs_path(uint32_t node, bool oneGbPages, bool nr)
static inline std::string sysfs_path(uint32_t node, size_t hugePageSize, bool nr)
{
return fmt::format("/sys/devices/system/node/node{}/hugepages/hugepages-{}kB/{}_hugepages", node, oneGbPages ? "1048576" : "2048", nr ? "nr" : "free");
return fmt::format("/sys/devices/system/node/node{}/hugepages/hugepages-{}kB/{}_hugepages", node, hugePageSize / 1024, nr ? "nr" : "free");
}
static inline bool write_nr_hugepages(uint32_t node, bool oneGbPages, uint64_t count) { return LinuxMemory::write(sysfs_path(node, oneGbPages, true).c_str(), count); }
static inline int64_t free_hugepages(uint32_t node, bool oneGbPages) { return LinuxMemory::read(sysfs_path(node, oneGbPages, false).c_str()); }
static inline int64_t nr_hugepages(uint32_t node, bool oneGbPages) { return LinuxMemory::read(sysfs_path(node, oneGbPages, true).c_str()); }
static inline bool write_nr_hugepages(uint32_t node, size_t hugePageSize, uint64_t count) { return LinuxMemory::write(sysfs_path(node, hugePageSize, true).c_str(), count); }
static inline int64_t free_hugepages(uint32_t node, size_t hugePageSize) { return LinuxMemory::read(sysfs_path(node, hugePageSize, false).c_str()); }
static inline int64_t nr_hugepages(uint32_t node, size_t hugePageSize) { return LinuxMemory::read(sysfs_path(node, hugePageSize, true).c_str()); }
} // namespace xmrig
bool xmrig::LinuxMemory::reserve(size_t size, uint32_t node, bool oneGbPages)
bool xmrig::LinuxMemory::reserve(size_t size, uint32_t node, size_t hugePageSize)
{
std::lock_guard<std::mutex> lock(mutex);
const size_t pageSize = oneGbPages ? oneGiB : twoMiB;
const size_t required = VirtualMemory::align(size, pageSize) / pageSize;
const size_t required = VirtualMemory::align(size, hugePageSize) / hugePageSize;
const auto available = free_hugepages(node, oneGbPages);
const auto available = free_hugepages(node, hugePageSize);
if (available < 0 || static_cast<size_t>(available) >= required) {
return false;
}
return write_nr_hugepages(node, oneGbPages, std::max<size_t>(nr_hugepages(node, oneGbPages), 0) + (required - available));
return write_nr_hugepages(node, hugePageSize, std::max<size_t>(nr_hugepages(node, hugePageSize), 0) + (required - available));
}

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
@@ -30,7 +30,7 @@ namespace xmrig {
class LinuxMemory
{
public:
static bool reserve(size_t size, uint32_t node, bool oneGbPages = false);
static bool reserve(size_t size, uint32_t node, size_t hugePageSize);
static bool write(const char *path, uint64_t value);
static int64_t read(const char *path);

View File

@@ -1,7 +1,7 @@
/* XMRig
* Copyright (c) 2018-2020 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
@@ -36,16 +36,19 @@
namespace xmrig {
static IMemoryPool *pool = nullptr;
size_t VirtualMemory::m_hugePageSize = VirtualMemory::kDefaultHugePageSize;
static IMemoryPool *pool = nullptr;
static std::mutex mutex;
} // namespace xmrig
xmrig::VirtualMemory::VirtualMemory(size_t size, bool hugePages, bool oneGbPages, bool usePool, uint32_t node, size_t alignSize) :
m_size(align(size)),
m_capacity(m_size),
m_node(node)
m_size(alignToHugePageSize(size)),
m_node(node),
m_capacity(m_size)
{
if (usePool) {
std::lock_guard<std::mutex> lock(mutex);
@@ -114,18 +117,18 @@ void xmrig::VirtualMemory::destroy()
}
void xmrig::VirtualMemory::init(size_t poolSize, bool hugePages)
void xmrig::VirtualMemory::init(size_t poolSize, size_t hugePageSize)
{
if (!pool) {
osInit(hugePages);
osInit(hugePageSize);
}
# ifdef XMRIG_FEATURE_HWLOC
if (Cpu::info()->nodes() > 1) {
pool = new NUMAMemoryPool(align(poolSize, Cpu::info()->nodes()), hugePages);
pool = new NUMAMemoryPool(align(poolSize, Cpu::info()->nodes()), hugePageSize > 0);
} else
# endif
{
pool = new MemoryPool(poolSize, hugePages);
pool = new MemoryPool(poolSize, hugePageSize > 0);
}
}

View File

@@ -1,7 +1,7 @@
/* XMRig
* Copyright (c) 2018-2020 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
@@ -39,6 +39,9 @@ class VirtualMemory
public:
XMRIG_DISABLE_COPY_MOVE_DEFAULT(VirtualMemory)
constexpr static size_t kDefaultHugePageSize = 2U * 1024U * 1024U;
constexpr static size_t kOneGiB = 1024U * 1024U * 1024U;
VirtualMemory(size_t size, bool hugePages, bool oneGbPages, bool usePool, uint32_t node = 0, size_t alignSize = 64);
~VirtualMemory();
@@ -65,9 +68,11 @@ public:
static void destroy();
static void flushInstructionCache(void *p, size_t size);
static void freeLargePagesMemory(void *p, size_t size);
static void init(size_t poolSize, bool hugePages);
static void init(size_t poolSize, size_t hugePageSize);
static inline constexpr size_t align(size_t pos, size_t align = 2097152) { return ((pos - 1) / align + 1) * align; }
static inline constexpr size_t align(size_t pos, size_t align = kDefaultHugePageSize) { return ((pos - 1) / align + 1) * align; }
static inline size_t alignToHugePageSize(size_t pos) { return align(pos, hugePageSize()); }
static inline size_t hugePageSize() { return m_hugePageSize; }
private:
enum Flags {
@@ -78,15 +83,17 @@ private:
FLAG_MAX
};
static void osInit(bool hugePages);
static void osInit(size_t hugePageSize);
bool allocateLargePagesMemory();
bool allocateOneGbPagesMemory();
void freeLargePagesMemory();
static size_t m_hugePageSize;
const size_t m_size;
size_t m_capacity;
const uint32_t m_node;
size_t m_capacity;
std::bitset<FLAG_MAX> m_flags;
uint8_t *m_scratchpad = nullptr;
};

View File

@@ -1,7 +1,7 @@
/* XMRig
* Copyright (c) 2018-2020 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
@@ -18,13 +18,14 @@
*/
#include <cstdlib>
#include <sys/mman.h>
#include "crypto/common/VirtualMemory.h"
#include "backend/cpu/Cpu.h"
#include "crypto/common/portable/mm_malloc.h"
#include "crypto/common/VirtualMemory.h"
#include <cmath>
#include <cstdlib>
#include <sys/mman.h>
#ifdef XMRIG_OS_APPLE
@@ -42,14 +43,21 @@
#endif
#if defined(XMRIG_OS_LINUX)
# if (defined(MAP_HUGE_1GB) || defined(MAP_HUGE_SHIFT))
# define XMRIG_HAS_1GB_PAGES
# endif
#ifdef XMRIG_OS_LINUX
# include "crypto/common/LinuxMemory.h"
#endif
#ifndef MAP_HUGE_SHIFT
# define MAP_HUGE_SHIFT 26
#endif
#ifndef MAP_HUGE_MASK
# define MAP_HUGE_MASK 0x3f
#endif
#ifdef XMRIG_SECURE_JIT
# define SECURE_PROT_EXEC 0
#else
@@ -57,6 +65,19 @@
#endif
namespace xmrig {
#ifdef XMRIG_OS_LINUX
static inline int hugePagesFlag(size_t size)
{
return (static_cast<int>(log2(size)) & MAP_HUGE_MASK) << MAP_HUGE_SHIFT;
}
#endif
} // namespace xmrig
bool xmrig::VirtualMemory::isHugepagesAvailable()
{
# if defined(XMRIG_OS_MACOS) && defined(XMRIG_ARM)
@@ -69,7 +90,7 @@ bool xmrig::VirtualMemory::isHugepagesAvailable()
bool xmrig::VirtualMemory::isOneGbPagesAvailable()
{
# ifdef XMRIG_HAS_1GB_PAGES
# ifdef XMRIG_OS_LINUX
return Cpu::info()->hasOneGbPages();
# else
return false;
@@ -126,18 +147,10 @@ void *xmrig::VirtualMemory::allocateExecutableMemory(size_t size, bool hugePages
# else
# if defined(MAP_HUGE_2MB)
constexpr int flag_2mb = MAP_HUGE_2MB;
# elif defined(MAP_HUGE_SHIFT)
constexpr int flag_2mb = (21 << MAP_HUGE_SHIFT);
# else
constexpr int flag_2mb = 0;
# endif
void *mem = nullptr;
if (hugePages) {
mem = mmap(0, align(size), PROT_READ | PROT_WRITE | SECURE_PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS | MAP_POPULATE | flag_2mb, -1, 0);
mem = mmap(0, align(size), PROT_READ | PROT_WRITE | SECURE_PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS | MAP_POPULATE | hugePagesFlag(hugePageSize()), -1, 0);
}
if (!mem) {
@@ -157,17 +170,7 @@ void *xmrig::VirtualMemory::allocateLargePagesMemory(size_t size)
# elif defined(__FreeBSD__)
void *mem = mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_ALIGNED_SUPER | MAP_PREFAULT_READ, -1, 0);
# else
# if defined(MAP_HUGE_2MB)
constexpr int flag_2mb = MAP_HUGE_2MB;
# elif defined(MAP_HUGE_SHIFT)
constexpr int flag_2mb = (21 << MAP_HUGE_SHIFT);
# else
constexpr int flag_2mb = 0;
# endif
void *mem = mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_POPULATE | flag_2mb, 0, 0);
void *mem = mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_POPULATE | hugePagesFlag(hugePageSize()), 0, 0);
# endif
return mem == MAP_FAILED ? nullptr : mem;
@@ -176,17 +179,9 @@ void *xmrig::VirtualMemory::allocateLargePagesMemory(size_t size)
void *xmrig::VirtualMemory::allocateOneGbPagesMemory(size_t size)
{
# ifdef XMRIG_HAS_1GB_PAGES
# ifdef XMRIG_OS_LINUX
if (isOneGbPagesAvailable()) {
# if defined(MAP_HUGE_1GB)
constexpr int flag_1gb = MAP_HUGE_1GB;
# elif defined(MAP_HUGE_SHIFT)
constexpr int flag_1gb = (30 << MAP_HUGE_SHIFT);
# else
constexpr int flag_1gb = 0;
# endif
void *mem = mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_POPULATE | flag_1gb, 0, 0);
void *mem = mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_POPULATE | hugePagesFlag(kOneGiB), 0, 0);
return mem == MAP_FAILED ? nullptr : mem;
}
@@ -212,15 +207,18 @@ void xmrig::VirtualMemory::freeLargePagesMemory(void *p, size_t size)
}
void xmrig::VirtualMemory::osInit(bool)
void xmrig::VirtualMemory::osInit(size_t hugePageSize)
{
if (hugePageSize) {
m_hugePageSize = hugePageSize;
}
}
bool xmrig::VirtualMemory::allocateLargePagesMemory()
{
# if defined(XMRIG_OS_LINUX)
LinuxMemory::reserve(m_size, m_node);
# ifdef XMRIG_OS_LINUX
LinuxMemory::reserve(m_size, m_node, hugePageSize());
# endif
m_scratchpad = static_cast<uint8_t*>(allocateLargePagesMemory(m_size));
@@ -242,8 +240,8 @@ bool xmrig::VirtualMemory::allocateLargePagesMemory()
bool xmrig::VirtualMemory::allocateOneGbPagesMemory()
{
# if defined(XMRIG_HAS_1GB_PAGES)
LinuxMemory::reserve(m_size, m_node, true);
# ifdef XMRIG_OS_LINUX
LinuxMemory::reserve(m_size, m_node, kOneGiB);
# endif
m_scratchpad = static_cast<uint8_t*>(allocateOneGbPagesMemory(m_size));

View File

@@ -1,7 +1,7 @@
/* XMRig
* Copyright (c) 2018-2020 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
@@ -24,9 +24,9 @@
#include <tchar.h>
#include "crypto/common/VirtualMemory.h"
#include "base/io/log/Log.h"
#include "crypto/common/portable/mm_malloc.h"
#include "crypto/common/VirtualMemory.h"
#ifdef XMRIG_SECURE_JIT
@@ -233,9 +233,9 @@ void xmrig::VirtualMemory::freeLargePagesMemory(void *p, size_t)
}
void xmrig::VirtualMemory::osInit(bool hugePages)
void xmrig::VirtualMemory::osInit(size_t hugePageSize)
{
if (hugePages) {
if (hugePageSize) {
hugepagesAvailable = TrySetLockPagesPrivilege();
}
}

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

@@ -171,7 +171,7 @@ void JitCompilerA64::generateProgram(Program& program, ProgramConfiguration& con
emit32(ARMV8A::EOR | 10 | (IntRegMap[config.readReg0] << 5) | (IntRegMap[config.readReg1] << 16), code, codePos);
# ifndef XMRIG_OS_APPLE
xmrig::VirtualMemory::flushInstructionCache(reinterpret_cast<char*>(code + MainLoopBegin), reinterpret_cast<char*>(code + codePos));
xmrig::VirtualMemory::flushInstructionCache(reinterpret_cast<char*>(code + MainLoopBegin), codePos - MainLoopBegin);
# endif
}
@@ -237,7 +237,7 @@ void JitCompilerA64::generateProgramLight(Program& program, ProgramConfiguration
emit32(ARMV8A::ADD_IMM_HI | 2 | (2 << 5) | (imm_hi << 10), code, codePos);
# ifndef XMRIG_OS_APPLE
xmrig::VirtualMemory::flushInstructionCache(reinterpret_cast<char*>(code + MainLoopBegin), reinterpret_cast<char*>(code + codePos));
xmrig::VirtualMemory::flushInstructionCache(reinterpret_cast<char*>(code + MainLoopBegin), codePos - MainLoopBegin);
# endif
}
@@ -364,7 +364,7 @@ void JitCompilerA64::generateSuperscalarHash(SuperscalarProgram(&programs)[N])
codePos += p2 - p1;
# ifndef XMRIG_OS_APPLE
xmrig::VirtualMemory::flushInstructionCache(reinterpret_cast<char*>(code + CodeSize), reinterpret_cast<char*>(code + codePos));
xmrig::VirtualMemory::flushInstructionCache(reinterpret_cast<char*>(code + CodeSize), codePos - MainLoopBegin);
# endif
}
@@ -401,6 +401,10 @@ void JitCompilerA64::allocate(size_t size)
code = static_cast<uint8_t*>(allocExecutableMemory(allocatedSize, hugePages));
memcpy(code, reinterpret_cast<const void *>(randomx_program_aarch64), CodeSize);
# ifndef XMRIG_OS_APPLE
xmrig::VirtualMemory::flushInstructionCache(reinterpret_cast<char*>(code), CodeSize);
# endif
}

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
@@ -113,7 +113,6 @@ private:
Mode readMode(const rapidjson::Value &value) const;
bool m_numa = true;
bool m_oneGbPages = false;
bool m_rdmsr = true;
int m_threads = -1;
@@ -123,6 +122,7 @@ private:
ScratchpadPrefetchMode m_scratchpadPrefetchMode = ScratchpadPrefetchT0;
# ifdef XMRIG_FEATURE_HWLOC
bool m_numa = true;
std::vector<uint32_t> m_nodeset;
# 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 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
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(" is 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 */

243
src/hw/dmi/DmiMemory.cpp Normal file
View File

@@ -0,0 +1,243 @@
/* 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/fmt/format.h"
#include "3rdparty/rapidjson/document.h"
#include "hw/dmi/DmiTools.h"
#include <algorithm>
#include <array>
#include <regex>
namespace xmrig {
static const char *kIdFormat = "DIMM_{}{}";
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));
}
setId(dmi_string(h, 0x10), dmi_string(h, 0x11));
m_formFactor = h->data[0x0E];
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("id", id().toJSON(doc), allocator);
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
void xmrig::DmiMemory::setId(const char *slot, const char *bank)
{
m_slot = slot;
m_bank = bank;
std::cmatch cm;
if (std::regex_match(slot, cm, std::regex("^Channel([A-Z])[-_]DIMM(\\d+)$", std::regex_constants::icase))) {
m_id = fmt::format(kIdFormat, cm.str(1), cm.str(2)).c_str();
}
else if (std::regex_search(bank, cm, std::regex("CHANNEL ([A-Z])$"))) {
std::cmatch cm2;
if (std::regex_match(slot, cm2, std::regex("^DIMM (\\d+)$"))) {
m_id = fmt::format(kIdFormat, cm.str(1), cm2.str(1)).c_str();
}
}
}

82
src/hw/dmi/DmiMemory.h Normal file
View File

@@ -0,0 +1,82 @@
/* 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 &id() const { return m_id.isNull() ? m_slot : m_id; }
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:
void setId(const char *slot, const char *bank);
String m_bank;
String m_id;
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.1"
#define APP_VERSION "6.8.1"
#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 0
#define APP_VER_MINOR 8
#define APP_VER_PATCH 1
#ifdef _MSC_VER
# if (_MSC_VER >= 1920)