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

Compare commits

..

90 Commits

Author SHA1 Message Date
XMRig
d5605a29b4 v5.5.0 2019-12-29 21:42:11 +07:00
XMRig
4c28fa6009 Merge branch 'dev' 2019-12-29 21:41:40 +07:00
XMRig
ad9ae6a143 Merge branch 'dev' of github.com:xmrig/xmrig into dev 2019-12-29 15:36:39 +07:00
XMRig
a5b0bc04cc Add "cn/ultra" alias for tlo-pool.raasu.org pool. 2019-12-29 15:36:05 +07:00
xmrig
f491e99bf9 Update CHANGELOG.md 2019-12-29 03:43:10 +07:00
XMRig
402c44b547 Added "cn-pico/tlo". 2019-12-29 00:29:19 +07:00
XMRig
ac4086b273 Fix build. 2019-12-28 02:00:08 +07:00
XMRig
f00769f758 Code style cleanup. 2019-12-28 01:45:54 +07:00
xmrig
6ceb4dfc4f Merge pull request #1465 from SChernykh/dev
Fix for 1st-gen Ryzen crashes
2019-12-27 18:26:26 +07:00
SChernykh
3a2941b719 Fix for 1st-gen Ryzen crashes 2019-12-27 12:40:38 +02:00
xmrig
99826a6b51 Update CHANGELOG.md 2019-12-27 15:03:24 +07:00
XMRig
4a9a7434f6 Revert Platform::setProcessPriority 2019-12-27 03:19:03 +07:00
XMRig
dbb721cb5e Removed "rx/v" algorithm. 2019-12-26 22:34:19 +07:00
xmrig
2a93bb2cee Update CHANGELOG.md 2019-12-25 05:01:19 +07:00
XMRig
7dfb4d9dc0 v5.5.0-dev 2019-12-25 04:53:38 +07:00
XMRig
22eca8e0d5 Fixed memory allocation checks. 2019-12-25 04:39:21 +07:00
XMRig
ecb46643e2 Added support for alternative CUDA plugin API. 2019-12-25 00:35:43 +07:00
xmrig
73d959a259 Update ALGORITHMS.md 2019-12-24 03:48:39 +07:00
XMRig
a95b179a60 Merge branch 'dev' of github.com:xmrig/xmrig into dev 2019-12-24 02:05:00 +07:00
XMRig
2e4a83547d Add console title for Windows. 2019-12-24 02:04:34 +07:00
xmrig
fd30294ca0 Merge pull request #1461 from suanlian1/patch-1
Monero already changed PoW on Nov 30, 2019
2019-12-24 01:07:44 +07:00
sairog
9b16a2736a Update README.md
Monero already changed PoW on Nov 30, 2019. Also minor text corrections.
2019-12-23 23:23:16 +05:30
XMRig
ea7aa4ccef Fixed MSVC build. 2019-12-23 00:37:43 +07:00
XMRig
d81845e1ab Merge branch 'feature-env' into dev 2019-12-23 00:29:38 +07:00
XMRig
f9d07229b4 Add extra variables. 2019-12-23 00:28:57 +07:00
XMRig
2d15c10e0f Added ENV support for "loader" option. 2019-12-22 19:48:33 +07:00
XMRig
5bd6a1c028 Added ENV support for "user", "pass" and "rig-id" fields. 2019-12-22 19:09:30 +07:00
XMRig
356e666e61 Added Env class. 2019-12-22 18:09:26 +07:00
XMRig
bdf12bca0f Make Process::location static. 2019-12-22 13:26:06 +07:00
XMRig
c44ae06d54 Added --randomx-no-rdmsr command line option. 2019-12-21 23:57:25 +07:00
XMRig
c7de9e6561 v5.4.1-dev 2019-12-21 23:42:18 +07:00
XMRig
00c9f89213 Merge branch 'master' into dev 2019-12-21 23:41:44 +07:00
XMRig
8f2a92c3ec v5.4.0 2019-12-21 16:12:02 +07:00
XMRig
69e67784d3 Merge branch 'dev' 2019-12-21 16:11:25 +07:00
xmrig
cd7f73a31c Update ALGORITHMS.md 2019-12-21 13:40:42 +07:00
XMRig
98cfe7ed37 Added extra error message. 2019-12-20 23:44:32 +07:00
XMRig
449617d717 Allow use old CUDA plugin. 2019-12-20 21:10:13 +07:00
xmrig
a25042db72 Update CHANGELOG.md 2019-12-20 04:16:28 +07:00
XMRig
049caabdae Add missing algorithm name alias. 2019-12-20 04:08:47 +07:00
XMRig
81b1cccb0b Merge branch 'Spudz76-dev-rxv' into dev 2019-12-20 04:06:25 +07:00
XMRig
2911bb3a81 Fix OpenCL. 2019-12-20 04:05:09 +07:00
Tony Butler
45412a2ace Add MoneroV (rx/v) algorithm [based on MoneroOcean/master] 2019-12-18 16:17:22 -07:00
XMRig
f4cedd7b63 Fixed MsrItem serialization. 2019-12-19 03:49:32 +07:00
XMRig
3e3d34b3ce Allow number value for "wrmsr" option only for Intel. 2019-12-19 03:28:05 +07:00
XMRig
12fb27e2cf Use MsrItem::kNoMask. 2019-12-19 03:20:48 +07:00
xmrig
a1e8c1353f Merge pull request #1443 from SChernykh/dev
Fixed crash with GCC compiler
2019-12-18 23:45:36 +07:00
SChernykh
c01c035269 Fixed crash with GCC compiler 2019-12-18 17:32:57 +01:00
xmrig
eeb8bbe5bc Merge pull request #1439 from SChernykh/dev
Add vzeroupper for processors with AVX
2019-12-18 18:32:17 +07:00
SChernykh
f85aba5d21 Fixed AVX detection 2019-12-18 12:20:21 +01:00
SChernykh
f8bf8fddd9 Update jit_compiler_x86_static.S 2019-12-18 09:13:21 +01:00
SChernykh
7459677fd5 Add vzeroupper for processors with AVX
To avoid false dependencies on upper 128 bits of YMM registers.
2019-12-18 09:12:25 +01:00
xmrig
c0b0628d59 Merge pull request #1438 from SChernykh/dev
Added bit masks for MSR registers
2019-12-18 11:44:06 +07:00
SChernykh
59e8fdb9ed Added bit masks for MSR registers 2019-12-17 23:55:22 +01:00
XMRig
5142a406b0 Less error prone log interface. 2019-12-18 02:20:31 +07:00
XMRig
3cc8b19ca0 Added command line option --verbose. 2019-12-17 22:03:50 +07:00
XMRig
f8865b1498 Added "verbose" option. 2019-12-17 21:46:11 +07:00
XMRig
969821296f Merge branch 'feature-custom-msr' into dev 2019-12-17 16:53:28 +07:00
XMRig
a877b1d269 Added save/restore MSR registers on Linux. 2019-12-17 16:17:11 +07:00
XMRig
9cea70b77c Rename Rx_windows.cpp to Rx_win.cpp. 2019-12-17 15:16:37 +07:00
XMRig
d2d501c821 Added RandomX option "rdmsr" and save/restore MSR registers on Windows. 2019-12-17 14:45:01 +07:00
XMRig
a5089638ea #1421 Added limit for maximum send buffer size. 2019-12-17 03:18:25 +07:00
XMRig
17f82280d0 v5.4.0-dev 2019-12-17 02:52:47 +07:00
xmrig
c78d800392 Merge pull request #1434 from SChernykh/dev
RandomSFX (Safex Cash variant) support
2019-12-17 02:46:26 +07:00
XMRig
8bef964f68 Added support for write custom MSR. 2019-12-17 02:27:07 +07:00
SChernykh
4da37baf8c RandomSFX (Safex Cash variant) support 2019-12-16 19:36:29 +01:00
XMRig
33e7a54c29 #1421 Use dynamic size send buffer. 2019-12-16 14:09:03 +07:00
XMRig
1d4c8dda96 #1423 Implemented driver reuse. 2019-12-16 03:41:58 +07:00
XMRig
b633b593ad Strict wrmsr error handling. 2019-12-16 02:45:07 +07:00
XMRig
8dbb83f99b Revert changes. 2019-12-16 02:17:57 +07:00
xmrig
f24e4f6462 Merge pull request #1424 from SChernykh/dev
Use unique service name for WinRing0 driver
2019-12-16 01:32:32 +07:00
SChernykh
2e001677df Use unique service name for WinRing0 driver
To avoid error 1072
2019-12-15 19:28:14 +01:00
XMRig
be253808d4 v5.3.1-dev 2019-12-16 00:17:08 +07:00
XMRig
e07cbe858b Merge branch 'master' into dev 2019-12-16 00:15:49 +07:00
xmrig
271a12dcca Update CHANGELOG.md 2019-12-15 15:39:52 +07:00
xmrig
06c70a7cd9 Merge pull request #1418 from jtgrassie/buffer-size
increase stratum send buffer size
2019-12-15 15:38:27 +07:00
XMRig
dccf7f9ae7 v5.3.0 2019-12-15 15:34:27 +07:00
XMRig
aa1f0077d8 Merge branch 'dev' 2019-12-15 15:33:51 +07:00
Jethro Grassie
348916040c increase stratum send buffer size 2019-12-15 03:23:07 -05:00
xmrig
014c80f15d Update CHANGELOG.md 2019-12-15 15:02:49 +07:00
XMRig
6adba6dad4 Removed unnecessary check. 2019-12-15 12:02:45 +07:00
XMRig
b346507975 Added enable_1gb_pages.sh 2019-12-15 03:13:52 +07:00
XMRig
fb5b873524 Added missing tag. 2019-12-15 01:52:20 +07:00
XMRig
a6f381403c Added WinRing0 driver binary. 2019-12-15 01:48:48 +07:00
XMRig
5d0fd2dc8e Unified Linux/Windows MSR log messages. 2019-12-15 01:32:41 +07:00
xmrig
1ad6b5504c Merge pull request #1416 from SChernykh/dev
Fixed thread count for MSR mod
2019-12-14 22:41:00 +07:00
SChernykh
222fcfae87 Fixed thread count for MSR mod 2019-12-14 16:30:46 +01:00
XMRig
5a2c3d8396 v5.3.0-dev 2019-12-14 22:30:41 +07:00
XMRig
687617de25 Merge branch 'master' into dev 2019-12-14 22:29:57 +07:00
xmrig
a682ae3299 Merge pull request #1414 from SChernykh/dev
MSR mod for Windows
2019-12-14 22:12:08 +07:00
SChernykh
2e6523aa10 MSR mod for Windows 2019-12-14 16:04:37 +01:00
95 changed files with 7266 additions and 5895 deletions

View File

@@ -1,3 +1,28 @@
# v5.5.0
- [#179](https://github.com/xmrig/xmrig/issues/179) Added support for [environment variables](https://xmrig.com/docs/miner/environment-variables) in config file.
- [#1445](https://github.com/xmrig/xmrig/pull/1445) Removed `rx/v` algorithm.
- [#1453](https://github.com/xmrig/xmrig/issues/1453) Fixed crash on 32bit systems.
- [#1459](https://github.com/xmrig/xmrig/issues/1459) Fixed crash on very low memory systems.
- [#1465](https://github.com/xmrig/xmrig/pull/1465) Added fix for 1st-gen Ryzen crashes.
- [#1466](https://github.com/xmrig/xmrig/pull/1466) Added `cn-pico/tlo` algorithm.
- Added `--randomx-no-rdmsr` command line option.
- Added console title for Windows with miner name and version.
- On Windows `priority` option now also change base priority.
# v5.4.0
- [#1434](https://github.com/xmrig/xmrig/pull/1434) Added RandomSFX (`rx/sfx`) algorithm for Safex Cash.
- [#1445](https://github.com/xmrig/xmrig/pull/1445) Added RandomV (`rx/v`) algorithm for *new* MoneroV.
- [#1419](https://github.com/xmrig/xmrig/issues/1419) Added reverting MSR changes on miner exit, use `"rdmsr": false,` in `"randomx"` object to disable this feature.
- [#1423](https://github.com/xmrig/xmrig/issues/1423) Fixed conflicts with exists WinRing0 driver service.
- [#1425](https://github.com/xmrig/xmrig/issues/1425) Fixed crash on first generation Zen CPUs (MSR mod accidentally enable Opcache), additionally now you can disable Opcache and enable MSR mod via config `"wrmsr": ["0xc0011020:0x0", "0xc0011021:0x60", "0xc0011022:0x510000", "0xc001102b:0x1808cc16"],`.
- Added advanced usage for `wrmsr` option, for example: `"wrmsr": ["0x1a4:0x6"],` (Intel) and `"wrmsr": ["0xc0011020:0x0", "0xc0011021:0x40:0xffffffffffffffdf", "0xc0011022:0x510000", "0xc001102b:0x1808cc16"],` (Ryzen).
- Added new config option `"verbose"` and command line option `--verbose`.
# v5.3.0
- [#1414](https://github.com/xmrig/xmrig/pull/1414) Added native MSR support for Windows, by using signed **WinRing0 driver** (© 2007-2009 OpenLibSys.org).
- Added new [MSR documentation](https://xmrig.com/docs/miner/randomx-optimization-guide/msr).
- [#1418](https://github.com/xmrig/xmrig/pull/1418) Increased stratum send buffer size.
# v5.2.1
- [#1408](https://github.com/xmrig/xmrig/pull/1408) Added RandomX boost script for Linux (if you don't like run miner with root privileges).
- Added support for [AMD Ryzen MSR registers](https://www.reddit.com/r/MoneroMining/comments/e962fu/9526_hs_on_ryzen_7_3700x_xmrig_520_1gb_pages_msr/) (Linux only).

View File

@@ -13,6 +13,7 @@ option(WITH_HTTP "Enable HTTP protocol support (client/server)" ON)
option(WITH_DEBUG_LOG "Enable debug log output" OFF)
option(WITH_TLS "Enable OpenSSL support" ON)
option(WITH_ASM "Enable ASM PoW implementations" ON)
option(WITH_MSR "Enable MSR mod & 1st-gen Ryzen fix" ON)
option(WITH_EMBEDDED_CONFIG "Enable internal embedded JSON config" OFF)
option(WITH_OPENCL "Enable OpenCL backend" ON)
option(WITH_CUDA "Enable CUDA backend" ON)
@@ -209,3 +210,8 @@ endif()
add_executable(${CMAKE_PROJECT_NAME} ${HEADERS} ${SOURCES} ${SOURCES_OS} ${SOURCES_CPUID} ${HEADERS_CRYPTO} ${SOURCES_CRYPTO} ${SOURCES_SYSLOG} ${TLS_SOURCES} ${XMRIG_ASM_SOURCES} ${CN_GPU_SOURCES})
target_link_libraries(${CMAKE_PROJECT_NAME} ${XMRIG_ASM_LIBRARY} ${OPENSSL_LIBRARIES} ${UV_LIBRARIES} ${EXTRA_LIBS} ${CPUID_LIB} ${ARGON2_LIBRARY})
if (WIN32)
add_custom_command(TARGET ${CMAKE_PROJECT_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_SOURCE_DIR}/bin/WinRing0/WinRing0x64.sys" $<TARGET_FILE_DIR:${CMAKE_PROJECT_NAME}>)
endif()

View File

@@ -1,6 +1,6 @@
# XMRig
**:warning: [Monero will change PoW algorithm to RandomX on November 30.](https://github.com/xmrig/xmrig/issues/1204)**
**:warning: [Monero changed PoW algorithm to RandomX on November 30.](https://github.com/xmrig/xmrig/issues/1204)**
[![Github All Releases](https://img.shields.io/github/downloads/xmrig/xmrig/total.svg)](https://github.com/xmrig/xmrig/releases)
[![GitHub release](https://img.shields.io/github/release/xmrig/xmrig/all.svg)](https://github.com/xmrig/xmrig/releases)
@@ -38,7 +38,7 @@ Network:
-u, --user=USERNAME username for mining server
-p, --pass=PASSWORD password for mining server
-O, --userpass=U:P username:password pair for mining server
-k, --keepalive send keepalived packet for prevent timeout (needs pool support)
-k, --keepalive send keepalive packet for prevent timeout (needs pool support)
--nicehash enable nicehash.com support
--rig-id=ID rig identifier for pool-side statistics (needs pool support)
--tls enable SSL/TLS support (needs pool support)
@@ -62,11 +62,12 @@ CPU backend:
--cpu-no-yield prefer maximum hashrate rather than system response/stability
--no-huge-pages disable huge pages support
--asm=ASM ASM optimizations, possible values: auto, none, intel, ryzen, bulldozer
--randomx-init=N threads count to initialize RandomX dataset
--randomx-init=N thread count to initialize RandomX dataset
--randomx-no-numa disable NUMA support for RandomX
--randomx-mode=MODE RandomX mode: auto, fast, light
--randomx-1gb-pages use 1GB hugepages for dataset (Linux only)
--randomx-wrmsr=N write value (0-15) to Intel MSR register 0x1a4 or do nothing (-1) (Linux only)
--randomx-wrmsr=N write custom value (0-15) to Intel MSR register 0x1a4 or disable MSR mod (-1)
--randomx-no-rdmsr disable reverting initial MSR values on exit
API:
--api-worker-id=ID custom worker-id for API
@@ -98,6 +99,7 @@ Logging:
--print-time=N print hashrate report every N seconds
--health-print-time=N print health report every N seconds
--no-color disable colored output
--verbose verbose output
Misc:
-c, --config=FILE load a JSON-format configuration file

21
bin/WinRing0/LICENSE Normal file
View File

@@ -0,0 +1,21 @@
Copyright (c) 2007-2009 OpenLibSys.org. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Binary file not shown.

View File

@@ -79,8 +79,23 @@ if (WITH_RANDOMX)
)
endif()
if (XMRIG_OS_LINUX AND NOT XMRIG_ARM)
list(APPEND SOURCES_CRYPTO src/crypto/rx/Rx_linux.cpp)
if (WITH_MSR AND NOT XMRIG_ARM AND CMAKE_SIZEOF_VOID_P EQUAL 8 AND (XMRIG_OS_WIN OR XMRIG_OS_LINUX))
add_definitions(/DXMRIG_FEATURE_MSR)
add_definitions(/DXMRIG_FIX_RYZEN)
message("-- WITH_MSR=ON")
if (XMRIG_OS_WIN)
list(APPEND SOURCES_CRYPTO src/crypto/rx/Rx_win.cpp)
elseif (XMRIG_OS_LINUX)
list(APPEND SOURCES_CRYPTO src/crypto/rx/Rx_linux.cpp)
endif()
list(APPEND HEADERS_CRYPTO src/crypto/rx/msr/MsrItem.h)
list(APPEND SOURCES_CRYPTO src/crypto/rx/msr/MsrItem.cpp)
else()
remove_definitions(/DXMRIG_FEATURE_MSR)
remove_definitions(/DXMRIG_FIX_RYZEN)
message("-- WITH_MSR=OFF")
endif()
else()
remove_definitions(/DXMRIG_ALGO_RANDOMX)

View File

@@ -12,6 +12,8 @@ Option `coin` useful for pools without algorithm negotiation support or daemon t
| Name | Memory | Version | Notes |
|------|--------|---------|-------|
| `rx/sfx` | 2 MB | 5.4.0+ | RandomSFX (RandomX variant for Safex). |
| `rx/v` | 2 MB | 5.4.0+ | RandomV (RandomX variant for new MoneroV). |
| `rx/arq` | 256 KB | 4.3.0+ | RandomARQ (RandomX variant for ArQmA). |
| `rx/0` | 2 MB | 3.2.0+ | RandomX (Monero). |
| `argon2/chukwa` | 512 KB | 3.1.0+ | Argon2id (Chukwa). |
@@ -23,7 +25,6 @@ Option `coin` useful for pools without algorithm negotiation support or daemon t
| `cn/zls` | 2 MB | 2.14.0+ | CryptoNight variant 2 with 3/4 iterations. |
| `cn/double` | 2 MB | 2.14.0+ | CryptoNight variant 2 with double iterations. |
| `cn/r` | 2 MB | 2.13.0+ | CryptoNightR (Monero's variant 4). |
| `cn/wow` | 2 MB | 2.12.0+ | CryptoNightR (Wownero). |
| `cn/gpu` | 2 MB | 2.11.0+ | CryptoNight-GPU. |
| `cn-pico` | 256 KB | 2.10.0+ | CryptoNight-Pico. |
| `cn/half` | 2 MB | 2.9.0+ | CryptoNight variant 2 with half iterations. |

12
scripts/enable_1gb_pages.sh Executable file
View File

@@ -0,0 +1,12 @@
#!/bin/bash -e
# https://xmrig.com/docs/miner/hugepages#onegb-huge-pages
sysctl -w vm.nr_hugepages=$(nproc)
for i in $(find /sys/devices/system/node/node* -maxdepth 0 -type d);
do
echo 3 > "$i/hugepages/hugepages-1048576kB/nr_hugepages";
done
echo "1GB pages successfully enabled"

View File

@@ -159,7 +159,7 @@ static void print_threads(Config *config)
static void print_commands(Config *)
{
if (Log::colors) {
if (Log::isColors()) {
Log::print(GREEN_BOLD(" * ") WHITE_BOLD("COMMANDS ") MAGENTA_BG(WHITE_BOLD_S "h") WHITE_BOLD("ashrate, ")
MAGENTA_BG(WHITE_BOLD_S "p") WHITE_BOLD("ause, ")
MAGENTA_BG(WHITE_BOLD_S "r") WHITE_BOLD("esume"));

View File

@@ -45,6 +45,7 @@ class IRxStorage
public:
virtual ~IRxStorage() = default;
virtual bool isAllocated() const = 0;
virtual HugePagesInfo hugePages() const = 0;
virtual RxDataset *dataset(const Job &job, uint32_t nodeId) const = 0;
virtual void init(const RxSeed &seed, uint32_t threads, bool hugePages, bool oneGbPages, RxConfig::Mode mode, int priority) = 0;

View File

@@ -154,7 +154,8 @@ bool xmrig::CpuWorker<N>::selfTest()
# ifdef XMRIG_ALGO_CN_PICO
if (m_algorithm.family() == Algorithm::CN_PICO) {
return verify(Algorithm::CN_PICO_0, test_output_pico_trtl);
return verify(Algorithm::CN_PICO_0, test_output_pico_trtl) &&
verify(Algorithm::CN_PICO_TLO, test_output_pico_tlo);
}
# endif

View File

@@ -37,12 +37,20 @@ namespace xmrig {
class ICpuInfo
{
public:
enum Vendor {
enum Vendor : uint32_t {
VENDOR_UNKNOWN,
VENDOR_INTEL,
VENDOR_AMD
};
enum MsrMod : uint32_t {
MSR_MOD_NONE,
MSR_MOD_RYZEN,
MSR_MOD_INTEL,
MSR_MOD_CUSTOM,
MSR_MOD_MAX
};
virtual ~ICpuInfo() = default;
# if defined(__x86_64__) || defined(_M_AMD64) || defined (__arm64__) || defined (__aarch64__)
@@ -58,6 +66,7 @@ public:
virtual const char *backend() const = 0;
virtual const char *brand() const = 0;
virtual CpuThreads threads(const Algorithm &algorithm, uint32_t limit) const = 0;
virtual MsrMod msrMod() const = 0;
virtual size_t cores() const = 0;
virtual size_t L2() const = 0;
virtual size_t L3() const = 0;

View File

@@ -139,7 +139,13 @@ xmrig::AdvancedCpuInfo::AdvancedCpuInfo() :
m_aes = true;
if (m_vendor == VENDOR_AMD) {
m_assembly = (data.ext_family >= 23) ? Assembly::RYZEN : Assembly::BULLDOZER;
if (data.ext_family >= 23) {
m_assembly = Assembly::RYZEN;
m_msrMod = MSR_MOD_RYZEN;
}
else {
m_assembly = Assembly::BULLDOZER;
}
}
else if (m_vendor == VENDOR_INTEL) {
m_assembly = Assembly::INTEL;

View File

@@ -46,6 +46,7 @@ protected:
inline bool hasOneGbPages() const override { return m_pdpe1gb; }
inline const char *backend() const override { return m_backend; }
inline const char *brand() const override { return m_brand; }
inline MsrMod msrMod() const override { return m_msrMod; }
inline size_t cores() const override { return m_cores; }
inline size_t L2() const override { return m_L2; }
inline size_t L3() const override { return m_L3; }
@@ -62,6 +63,7 @@ private:
char m_backend[32]{};
char m_brand[64 + 5]{};
const bool m_pdpe1gb = false;
MsrMod m_msrMod = MSR_MOD_NONE;
size_t m_cores = 0;
size_t m_L2 = 0;
size_t m_L3 = 0;

View File

@@ -175,11 +175,18 @@ xmrig::BasicCpuInfo::BasicCpuInfo() :
cpuid(PROCESSOR_INFO, data);
const int32_t family = get_masked(data[EAX_Reg], 12, 8) + get_masked(data[EAX_Reg], 28, 20);
m_assembly = family >= 23 ? Assembly::RYZEN : Assembly::BULLDOZER;
if (family >= 23) {
m_assembly = Assembly::RYZEN;
m_msrMod = MSR_MOD_RYZEN;
}
else {
m_assembly = Assembly::BULLDOZER;
}
}
else if (memcmp(vendor, "GenuineIntel", 12) == 0) {
m_vendor = VENDOR_INTEL;
m_assembly = Assembly::INTEL;
m_msrMod = MSR_MOD_INTEL;
}
}
# endif

View File

@@ -46,6 +46,7 @@ protected:
inline bool hasAVX2() const override { return m_avx2; }
inline bool hasOneGbPages() const override { return m_pdpe1gb; }
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; }
@@ -63,6 +64,7 @@ private:
bool m_aes = false;
const bool m_avx2 = false;
const bool m_pdpe1gb = false;
MsrMod m_msrMod = MSR_MOD_NONE;
Vendor m_vendor = VENDOR_UNKNOWN;
};

View File

@@ -78,9 +78,15 @@ xmrig::CudaWorker::CudaWorker(size_t id, const CudaLaunchData &data) :
break;
}
if (!m_runner || !m_runner->init()) {
if (!m_runner) {
return;
}
if (!m_runner->init()) {
delete m_runner;
m_runner = nullptr;
}
}

View File

@@ -47,7 +47,7 @@ xmrig::CudaBaseRunner::~CudaBaseRunner()
bool xmrig::CudaBaseRunner::init()
{
m_ctx = CudaLib::alloc(m_data.thread.index(), m_data.thread.bfactor(), m_data.thread.bsleep());
if (CudaLib::deviceInfo(m_ctx, m_data.thread.blocks(), m_data.thread.threads(), m_data.algorithm, m_data.thread.datasetHost()) != 0) {
if (!callWrapper(CudaLib::deviceInfo(m_ctx, m_data.thread.blocks(), m_data.thread.threads(), m_data.algorithm, m_data.thread.datasetHost()))) {
return false;
}

View File

@@ -31,8 +31,9 @@
#include "crypto/rx/RxDataset.h"
xmrig::CudaRxRunner::CudaRxRunner(size_t index, const CudaLaunchData &data) : CudaBaseRunner(index, data),
m_datasetHost(data.thread.datasetHost() > 0)
xmrig::CudaRxRunner::CudaRxRunner(size_t index, const CudaLaunchData &data) :
CudaBaseRunner(index, data),
m_datasetHost(data.thread.datasetHost() > 0)
{
m_intensity = m_data.thread.threads() * m_data.thread.blocks();
const size_t scratchpads_size = m_intensity * m_data.algorithm.l3();

View File

@@ -41,7 +41,7 @@ xmrig::CudaDevice::CudaDevice(uint32_t index, int32_t bfactor, int32_t bsleep) :
m_index(index)
{
auto ctx = CudaLib::alloc(index, bfactor, bsleep);
if (CudaLib::deviceInfo(ctx, 0, 0, Algorithm::INVALID) != 0) {
if (!CudaLib::deviceInfo(ctx, 0, 0, Algorithm::INVALID)) {
CudaLib::release(ctx);
return;
@@ -107,7 +107,7 @@ uint32_t xmrig::CudaDevice::smx() const
void xmrig::CudaDevice::generate(const Algorithm &algorithm, CudaThreads &threads) const
{
if (CudaLib::deviceInfo(m_ctx, -1, -1, algorithm) != 0) {
if (!CudaLib::deviceInfo(m_ctx, -1, -1, algorithm)) {
return;
}

View File

@@ -28,6 +28,8 @@
#include "backend/cuda/wrappers/CudaLib.h"
#include "base/kernel/Env.h"
#include "crypto/rx/RxAlgo.h"
namespace xmrig {
@@ -48,6 +50,7 @@ static const char *kAlloc = "alloc";
static const char *kCnHash = "cnHash";
static const char *kDeviceCount = "deviceCount";
static const char *kDeviceInfo = "deviceInfo";
static const char *kDeviceInfo_v2 = "deviceInfo_v2";
static const char *kDeviceInit = "deviceInit";
static const char *kDeviceInt = "deviceInt";
static const char *kDeviceName = "deviceName";
@@ -60,6 +63,7 @@ static const char *kRelease = "release";
static const char *kRxHash = "rxHash";
static const char *kRxPrepare = "rxPrepare";
static const char *kSetJob = "setJob";
static const char *kSetJob_v2 = "setJob_v2";
static const char *kSymbolNotFound = "symbol not found";
static const char *kVersion = "version";
@@ -68,6 +72,7 @@ using alloc_t = nvid_ctx * (*)(uint32_
using cnHash_t = bool (*)(nvid_ctx *, uint32_t, uint64_t, uint64_t, uint32_t *, uint32_t *);
using deviceCount_t = uint32_t (*)();
using deviceInfo_t = int32_t (*)(nvid_ctx *, int32_t, int32_t, int32_t, int32_t);
using deviceInfo_v2_t = bool (*)(nvid_ctx *, int32_t, int32_t, const char *, int32_t);
using deviceInit_t = bool (*)(nvid_ctx *);
using deviceInt_t = int32_t (*)(nvid_ctx *, CudaLib::DeviceProperty);
using deviceName_t = const char * (*)(nvid_ctx *);
@@ -80,6 +85,7 @@ using release_t = void (*)(nvid_ctx *);
using rxHash_t = bool (*)(nvid_ctx *, uint32_t, uint64_t, uint32_t *, uint32_t *);
using rxPrepare_t = bool (*)(nvid_ctx *, const void *, size_t, bool, uint32_t);
using setJob_t = bool (*)(nvid_ctx *, const void *, size_t, int32_t);
using setJob_v2_t = bool (*)(nvid_ctx *, const void *, size_t, const char *);
using version_t = uint32_t (*)(Version);
@@ -87,6 +93,7 @@ static alloc_t pAlloc = nullptr;
static cnHash_t pCnHash = nullptr;
static deviceCount_t pDeviceCount = nullptr;
static deviceInfo_t pDeviceInfo = nullptr;
static deviceInfo_v2_t pDeviceInfo_v2 = nullptr;
static deviceInit_t pDeviceInit = nullptr;
static deviceInt_t pDeviceInt = nullptr;
static deviceName_t pDeviceName = nullptr;
@@ -99,6 +106,7 @@ static release_t pRelease = nullptr;
static rxHash_t pRxHash = nullptr;
static rxPrepare_t pRxPrepare = nullptr;
static setJob_t pSetJob = nullptr;
static setJob_v2_t pSetJob_v2 = nullptr;
static version_t pVersion = nullptr;
@@ -116,7 +124,7 @@ String CudaLib::m_loader;
bool xmrig::CudaLib::init(const char *fileName)
{
if (!m_initialized) {
m_loader = fileName == nullptr ? defaultLoader() : fileName;
m_loader = fileName == nullptr ? defaultLoader() : Env::expand(fileName);
m_ready = uv_dlopen(m_loader, &cudaLib) == 0 && load();
m_initialized = true;
}
@@ -143,6 +151,18 @@ bool xmrig::CudaLib::cnHash(nvid_ctx *ctx, uint32_t startNonce, uint64_t height,
}
bool xmrig::CudaLib::deviceInfo(nvid_ctx *ctx, int32_t blocks, int32_t threads, const Algorithm &algorithm, int32_t dataset_host) noexcept
{
const Algorithm algo = RxAlgo::id(algorithm);
if (pDeviceInfo_v2) {
return pDeviceInfo_v2(ctx, blocks, threads, algo.isValid() ? algo.shortName() : nullptr, dataset_host);
}
return pDeviceInfo(ctx, blocks, threads, algo, dataset_host) == 0;
}
bool xmrig::CudaLib::deviceInit(nvid_ctx *ctx) noexcept
{
return pDeviceInit(ctx);
@@ -163,7 +183,12 @@ bool xmrig::CudaLib::rxPrepare(nvid_ctx *ctx, const void *dataset, size_t datase
bool xmrig::CudaLib::setJob(nvid_ctx *ctx, const void *data, size_t size, const Algorithm &algorithm) noexcept
{
return pSetJob(ctx, data, size, algorithm);
const Algorithm algo = RxAlgo::id(algorithm);
if (pSetJob_v2) {
return pSetJob_v2(ctx, data, size, algo.shortName());
}
return pSetJob(ctx, data, size, algo);
}
@@ -185,12 +210,6 @@ const char *xmrig::CudaLib::pluginVersion() noexcept
}
int xmrig::CudaLib::deviceInfo(nvid_ctx *ctx, int32_t blocks, int32_t threads, const Algorithm &algorithm, int32_t dataset_host) noexcept
{
return pDeviceInfo(ctx, blocks, threads, algorithm, dataset_host);
}
int32_t xmrig::CudaLib::deviceInt(nvid_ctx *ctx, DeviceProperty property) noexcept
{
return pDeviceInt(ctx, property);
@@ -290,11 +309,13 @@ bool xmrig::CudaLib::load()
return false;
}
uv_dlsym(&cudaLib, kDeviceInfo_v2, reinterpret_cast<void**>(&pDeviceInfo_v2));
uv_dlsym(&cudaLib, kSetJob_v2, reinterpret_cast<void**>(&pSetJob_v2));
try {
DLSYM(Alloc);
DLSYM(CnHash);
DLSYM(DeviceCount);
DLSYM(DeviceInfo);
DLSYM(DeviceInit);
DLSYM(DeviceInt);
DLSYM(DeviceName);
@@ -306,8 +327,15 @@ bool xmrig::CudaLib::load()
DLSYM(Release);
DLSYM(RxHash);
DLSYM(RxPrepare);
DLSYM(SetJob);
DLSYM(Version);
if (!pDeviceInfo_v2) {
DLSYM(DeviceInfo);
}
if (!pSetJob_v2) {
DLSYM(SetJob);
}
} catch (std::exception &ex) {
return false;
}
@@ -318,7 +346,7 @@ bool xmrig::CudaLib::load()
}
const char *xmrig::CudaLib::defaultLoader()
xmrig::String xmrig::CudaLib::defaultLoader()
{
# if defined(__APPLE__)
return "/System/Library/Frameworks/OpenCL.framework/OpenCL"; // FIXME

View File

@@ -74,6 +74,7 @@ public:
static inline const String &loader() { return m_loader; }
static bool cnHash(nvid_ctx *ctx, uint32_t startNonce, uint64_t height, uint64_t target, uint32_t *rescount, uint32_t *resnonce);
static bool deviceInfo(nvid_ctx *ctx, int32_t blocks, int32_t threads, const Algorithm &algorithm, int32_t dataset_host = -1) noexcept;
static bool deviceInit(nvid_ctx *ctx) noexcept;
static bool rxHash(nvid_ctx *ctx, uint32_t startNonce, uint64_t target, uint32_t *rescount, uint32_t *resnonce) noexcept;
static bool rxPrepare(nvid_ctx *ctx, const void *dataset, size_t datasetSize, bool dataset_host, uint32_t batchSize) noexcept;
@@ -81,7 +82,6 @@ public:
static const char *deviceName(nvid_ctx *ctx) noexcept;
static const char *lastError(nvid_ctx *ctx) noexcept;
static const char *pluginVersion() noexcept;
static int deviceInfo(nvid_ctx *ctx, int32_t blocks, int32_t threads, const Algorithm &algorithm, int32_t dataset_host = -1) noexcept;
static int32_t deviceInt(nvid_ctx *ctx, DeviceProperty property) noexcept;
static nvid_ctx *alloc(uint32_t id, int32_t bfactor, int32_t bsleep) noexcept;
static std::string version(uint32_t version);
@@ -95,7 +95,7 @@ public:
private:
static bool load();
static const char *defaultLoader();
static String defaultLoader();
static bool m_initialized;
static bool m_ready;

View File

@@ -25,7 +25,6 @@
#include "backend/opencl/OclLaunchData.h"
#include "backend/common/Tags.h"
#include "backend/opencl/OclConfig.h"

View File

@@ -16,12 +16,14 @@
#define ALGO_CN_HEAVY_TUBE 15
#define ALGO_CN_HEAVY_XHV 16
#define ALGO_CN_PICO_0 17
#define ALGO_RX_0 18
#define ALGO_RX_WOW 19
#define ALGO_RX_LOKI 20
#define ALGO_RX_ARQMA 21
#define ALGO_AR2_CHUKWA 22
#define ALGO_AR2_WRKZ 23
#define ALGO_CN_PICO_TLO 18
#define ALGO_RX_0 19
#define ALGO_RX_WOW 20
#define ALGO_RX_LOKI 21
#define ALGO_RX_ARQMA 22
#define ALGO_RX_SFX 23
#define ALGO_AR2_CHUKWA 24
#define ALGO_AR2_WRKZ 25
#define FAMILY_UNKNOWN 0
#define FAMILY_CN 1

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -56,7 +56,7 @@ xmrig::OclRxBaseRunner::OclRxBaseRunner(size_t index, const OclLaunchData &data)
m_gcn_version = 14;
}
m_options += " -DALGO=" + std::to_string(m_algorithm.id());
m_options += " -DALGO=" + std::to_string(RxAlgo::id(m_algorithm));
m_options += " -DWORKERS_PER_HASH=" + std::to_string(m_worksize);
m_options += " -DGCN_VERSION=" + std::to_string(m_gcn_version);
}

View File

@@ -28,10 +28,12 @@
#include <uv.h>
#include "backend/opencl/wrappers/OclLib.h"
#include "backend/common/Tags.h"
#include "backend/opencl/wrappers/OclError.h"
#include "backend/opencl/wrappers/OclLib.h"
#include "base/io/log/Log.h"
#include "base/kernel/Env.h"
#if defined(OCL_DEBUG_REFERENCE_COUNT)
# define LOG_REFS(x, ...) xmrig::Log::print(xmrig::Log::WARNING, x, ##__VA_ARGS__)
@@ -188,7 +190,7 @@ static String getOclString(FUNC fn, OBJ obj, PARAM param)
bool xmrig::OclLib::init(const char *fileName)
{
if (!m_initialized) {
m_loader = fileName == nullptr ? defaultLoader() : fileName;
m_loader = fileName == nullptr ? defaultLoader() : Env::expand(fileName);
m_ready = uv_dlopen(m_loader, &oclLib) == 0 && load();
m_initialized = true;
}
@@ -257,7 +259,7 @@ bool xmrig::OclLib::load()
}
const char *xmrig::OclLib::defaultLoader()
xmrig::String xmrig::OclLib::defaultLoader()
{
# if defined(__APPLE__)
return "/System/Library/Frameworks/OpenCL.framework/OpenCL";

View File

@@ -102,7 +102,7 @@ public:
private:
static bool load();
static const char *defaultLoader();
static String defaultLoader();
static bool m_initialized;
static bool m_ready;

View File

@@ -26,17 +26,13 @@
#include <uv.h>
#ifndef _WIN32
# include <unistd.h>
#endif
#include "base/api/Api.h"
#include "3rdparty/http-parser/http_parser.h"
#include "base/api/interfaces/IApiListener.h"
#include "base/api/requests/HttpApiRequest.h"
#include "base/io/json/Json.h"
#include "base/kernel/Base.h"
#include "base/kernel/Env.h"
#include "base/tools/Buffer.h"
#include "base/tools/Chrono.h"
#include "core/config/Config.h"
@@ -158,7 +154,7 @@ void xmrig::Api::exec(IApiRequest &request)
auto &reply = request.reply();
reply.AddMember("id", StringRef(m_id), allocator);
reply.AddMember("worker_id", StringRef(m_workerId), allocator);
reply.AddMember("worker_id", m_workerId.toJSON(), allocator);
reply.AddMember("uptime", (Chrono::currentMSecsSinceEpoch() - m_timestamp) / 1000, allocator);
reply.AddMember("restricted", request.isRestricted(), allocator);
reply.AddMember("resources", getResources(request.doc()), allocator);
@@ -245,12 +241,8 @@ void xmrig::Api::genId(const String &id)
void xmrig::Api::genWorkerId(const String &id)
{
memset(m_workerId, 0, sizeof(m_workerId));
if (id.size() > 0) {
strncpy(m_workerId, id.data(), sizeof(m_workerId) - 1);
}
else {
gethostname(m_workerId, sizeof(m_workerId) - 1);
m_workerId = Env::expand(id);
if (m_workerId.isEmpty()) {
m_workerId = Env::hostname();
}
}

View File

@@ -32,6 +32,7 @@
#include "base/kernel/interfaces/IBaseListener.h"
#include "base/tools/Object.h"
#include "base/tools/String.h"
namespace xmrig {
@@ -71,7 +72,7 @@ private:
Base *m_base;
char m_id[32]{};
char m_workerId[128]{};
String m_workerId;
const uint64_t m_timestamp;
Httpd *m_httpd = nullptr;
std::vector<IApiListener *> m_listeners;

View File

@@ -12,6 +12,7 @@ set(HEADERS_BASE
src/base/kernel/config/BaseConfig.h
src/base/kernel/config/BaseTransform.h
src/base/kernel/Entry.h
src/base/kernel/Env.h
src/base/kernel/interfaces/IBaseListener.h
src/base/kernel/interfaces/IClient.h
src/base/kernel/interfaces/IClientListener.h
@@ -66,6 +67,7 @@ set(SOURCES_BASE
src/base/kernel/config/BaseConfig.cpp
src/base/kernel/config/BaseTransform.cpp
src/base/kernel/Entry.cpp
src/base/kernel/Env.cpp
src/base/kernel/Platform.cpp
src/base/kernel/Process.cpp
src/base/kernel/Signals.cpp

View File

@@ -92,7 +92,7 @@ public:
std::lock_guard<std::mutex> lock(m_mutex);
if (Log::background && m_backends.empty()) {
if (Log::isBackground() && m_backends.empty()) {
return;
}
@@ -195,9 +195,10 @@ private:
};
bool Log::background = false;
bool Log::colors = true;
LogPrivate *Log::d = new LogPrivate();
bool Log::m_background = false;
bool Log::m_colors = true;
LogPrivate *Log::d = new LogPrivate();
uint32_t Log::m_verbose = 0;
} /* namespace xmrig */

View File

@@ -27,6 +27,9 @@
#define XMRIG_LOG_H
#include <cstdint>
namespace xmrig {
@@ -54,10 +57,19 @@ public:
static void print(const char *fmt, ...);
static void print(Level level, const char *fmt, ...);
static bool background;
static bool colors;
static inline bool isBackground() { return m_background; }
static inline bool isColors() { return m_colors; }
static inline bool isVerbose() { return m_verbose > 0; }
static inline uint32_t verbose() { return m_verbose; }
static inline void setBackground(bool background) { m_background = background; }
static inline void setColors(bool colors) { m_colors = colors; }
static inline void setVerbose(uint32_t verbose) { m_verbose = verbose; }
private:
static bool m_background;
static bool m_colors;
static uint32_t m_verbose;
static LogPrivate *d;
};
@@ -83,6 +95,7 @@ private:
#define WHITE_BOLD_S CSI "1;37m" // actually white
#define GREEN_BG_BOLD_S CSI "42;1m"
#define YELLOW_BG_BOLD_S CSI "43;1m"
#define BLUE_BG_S CSI "44m"
#define BLUE_BG_BOLD_S CSI "44;1m"
#define MAGENTA_BG_S CSI "45m"
@@ -109,6 +122,7 @@ private:
#define WHITE_BOLD(x) WHITE_BOLD_S x CLEAR
#define GREEN_BG_BOLD(x) GREEN_BG_BOLD_S x CLEAR
#define YELLOW_BG_BOLD(x) YELLOW_BG_BOLD_S x CLEAR
#define BLUE_BG(x) BLUE_BG_S x CLEAR
#define BLUE_BG_BOLD(x) BLUE_BG_BOLD_S x CLEAR
#define MAGENTA_BG(x) MAGENTA_BG_S x CLEAR
@@ -117,13 +131,14 @@ private:
#define CYAN_BG_BOLD(x) CYAN_BG_BOLD_S x CLEAR
#define LOG_EMERG(x, ...) xmrig::Log::print(xmrig::Log::EMERG, x, ##__VA_ARGS__)
#define LOG_ALERT(x, ...) xmrig::Log::print(xmrig::Log::ALERT, x, ##__VA_ARGS__)
#define LOG_CRIT(x, ...) xmrig::Log::print(xmrig::Log::CRIT, x, ##__VA_ARGS__)
#define LOG_ERR(x, ...) xmrig::Log::print(xmrig::Log::ERR, x, ##__VA_ARGS__)
#define LOG_WARN(x, ...) xmrig::Log::print(xmrig::Log::WARNING, x, ##__VA_ARGS__)
#define LOG_NOTICE(x, ...) xmrig::Log::print(xmrig::Log::NOTICE, x, ##__VA_ARGS__)
#define LOG_INFO(x, ...) xmrig::Log::print(xmrig::Log::INFO, x, ##__VA_ARGS__)
#define LOG_EMERG(x, ...) xmrig::Log::print(xmrig::Log::EMERG, x, ##__VA_ARGS__)
#define LOG_ALERT(x, ...) xmrig::Log::print(xmrig::Log::ALERT, x, ##__VA_ARGS__)
#define LOG_CRIT(x, ...) xmrig::Log::print(xmrig::Log::CRIT, x, ##__VA_ARGS__)
#define LOG_ERR(x, ...) xmrig::Log::print(xmrig::Log::ERR, x, ##__VA_ARGS__)
#define LOG_WARN(x, ...) xmrig::Log::print(xmrig::Log::WARNING, x, ##__VA_ARGS__)
#define LOG_NOTICE(x, ...) xmrig::Log::print(xmrig::Log::NOTICE, x, ##__VA_ARGS__)
#define LOG_INFO(x, ...) xmrig::Log::print(xmrig::Log::INFO, x, ##__VA_ARGS__)
#define LOG_VERBOSE(x, ...) if (xmrig::Log::isVerbose()) { xmrig::Log::print(xmrig::Log::INFO, x, ##__VA_ARGS__); }
#ifdef APP_DEBUG
# define LOG_DEBUG(x, ...) xmrig::Log::print(xmrig::Log::DEBUG, x, ##__VA_ARGS__)

View File

@@ -27,28 +27,29 @@
#include <cstdio>
#include "base/tools/Handle.h"
#include "base/io/log/backends/ConsoleLog.h"
#include "base/tools/Handle.h"
#include "base/io/log/Log.h"
#include "version.h"
xmrig::ConsoleLog::ConsoleLog()
{
if (!isSupported()) {
Log::colors = false;
Log::setColors(false);
return;
}
m_tty = new uv_tty_t;
if (uv_tty_init(uv_default_loop(), m_tty, 1, 0) < 0) {
Log::colors = false;
Log::setColors(false);
return;
}
uv_tty_set_mode(m_tty, UV_TTY_MODE_NORMAL);
# ifdef WIN32
# ifdef XMRIG_OS_WIN
m_stream = reinterpret_cast<uv_stream_t*>(m_tty);
HANDLE handle = GetStdHandle(STD_INPUT_HANDLE);
@@ -59,6 +60,8 @@ xmrig::ConsoleLog::ConsoleLog()
SetConsoleMode(handle, mode | ENABLE_EXTENDED_FLAGS);
}
}
SetConsoleTitleA(APP_NAME " " APP_VERSION);
# endif
}
@@ -71,11 +74,11 @@ xmrig::ConsoleLog::~ConsoleLog()
void xmrig::ConsoleLog::print(int, const char *line, size_t, size_t size, bool colors)
{
if (!m_tty || Log::colors != colors) {
if (!m_tty || Log::isColors() != colors) {
return;
}
# ifdef _WIN32
# ifdef XMRIG_OS_WIN
uv_buf_t buf = uv_buf_init(const_cast<char *>(line), static_cast<unsigned int>(size));
if (!isWritable()) {
@@ -99,7 +102,7 @@ bool xmrig::ConsoleLog::isSupported() const
}
#ifdef WIN32
#ifdef XMRIG_OS_WIN
bool xmrig::ConsoleLog::isWritable() const
{
if (!m_stream || uv_is_writable(m_stream) != 1) {

View File

@@ -54,7 +54,7 @@ private:
uv_tty_t *m_tty = nullptr;
# ifdef _WIN32
# ifdef XMRIG_OS_WIN
bool isWritable() const;
uv_stream_t *m_stream = nullptr;

View File

@@ -25,6 +25,7 @@
#include "base/io/log/backends/FileLog.h"
#include "base/kernel/Env.h"
#include <cassert>
@@ -35,7 +36,7 @@
xmrig::FileLog::FileLog(const char *fileName)
{
uv_fs_t req;
m_file = uv_fs_open(uv_default_loop(), &req, fileName, O_CREAT | O_APPEND | O_WRONLY, 0644, nullptr);
m_file = uv_fs_open(uv_default_loop(), &req, Env::expand(fileName), O_CREAT | O_APPEND | O_WRONLY, 0644, nullptr);
uv_fs_req_cleanup(&req);
}

View File

@@ -127,7 +127,7 @@ private:
return config.release();
}
chain.addFile(process->location(Process::ExeLocation, "config.json"));
chain.addFile(Process::location(Process::ExeLocation, "config.json"));
if (read(chain, config)) {
return config.release();
@@ -177,7 +177,7 @@ int xmrig::Base::init()
Platform::init(config()->userAgent());
if (isBackground()) {
Log::background = true;
Log::setBackground(true);
}
else {
Log::add(new ConsoleLog());

View File

@@ -101,9 +101,9 @@ static int showVersion()
#ifdef XMRIG_FEATURE_HWLOC
static int exportTopology(const Process &process)
static int exportTopology(const Process &)
{
const String path = process.location(Process::ExeLocation, "topology.xml");
const String path = Process::location(Process::ExeLocation, "topology.xml");
hwloc_topology_t topology;
hwloc_topology_init(&topology);

139
src/base/kernel/Env.cpp Normal file
View File

@@ -0,0 +1,139 @@
/* 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>
*
* 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 "base/kernel/Env.h"
#include "base/kernel/Process.h"
#include "version.h"
#include <regex>
#include <uv.h>
#include <map>
#ifndef _WIN32
# include <unistd.h>
#endif
#ifndef UV_MAXHOSTNAMESIZE
# ifdef MAXHOSTNAMELEN
# define UV_MAXHOSTNAMESIZE (MAXHOSTNAMELEN + 1)
# else
# define UV_MAXHOSTNAMESIZE 256
# endif
#endif
namespace xmrig {
static std::map<String, String> variables;
static void createVariables()
{
variables.insert({ "XMRIG_VERSION", APP_VERSION });
variables.insert({ "XMRIG_EXE_DIR", Process::location(Process::ExeLocation, "") });
variables.insert({ "XMRIG_CWD", Process::location(Process::CwdLocation, "") });
}
} // namespace xmrig
xmrig::String xmrig::Env::expand(const char *in)
{
if (in == nullptr) {
return {};
}
std::string text(in);
if (text.size() < 4) {
return text.c_str();
}
static const std::regex env_re{R"--(\$\{([^}]+)\})--"};
std::map<std::string, String> vars;
for (std::sregex_iterator i = std::sregex_iterator(text.begin(), text.end(), env_re); i != std::sregex_iterator(); ++i) {
std::smatch m = *i;
const auto var = m.str();
if (vars.count(var)) {
continue;
}
vars.insert({ var, get(m[1].str().c_str()) });
}
for (const auto &kv : vars) {
if (kv.second.isNull()) {
continue;
}
size_t pos = 0;
while ((pos = text.find(kv.first, pos)) != std::string::npos) {
text.replace(pos, kv.first.size(), kv.second);
pos += kv.second.size();
}
}
return text.c_str();
}
xmrig::String xmrig::Env::get(const String &name)
{
if (variables.empty()) {
createVariables();
}
if (variables.count(name)) {
return variables.at(name);
}
return static_cast<const char *>(getenv(name));
}
xmrig::String xmrig::Env::hostname()
{
char buf[UV_MAXHOSTNAMESIZE]{};
size_t size = sizeof(buf);
# if UV_VERSION_HEX >= 0x010c00
if (uv_os_gethostname(buf, &size) == 0) {
return static_cast<const char *>(buf);
}
# else
if (gethostname(buf, size) == 0) {
return static_cast<const char *>(buf);
}
# endif
return {};
}

47
src/base/kernel/Env.h Normal file
View File

@@ -0,0 +1,47 @@
/* 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>
*
* 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_ENV_H
#define XMRIG_ENV_H
#include "base/tools/String.h"
namespace xmrig {
class Env
{
public:
static String expand(const char *in);
static String get(const String &name);
static String hostname();
};
} /* namespace xmrig */
#endif /* XMRIG_ENV_H */

View File

@@ -51,6 +51,7 @@ public:
static uint32_t setTimerResolution(uint32_t resolution);
static void init(const char *userAgent);
static void restoreTimerResolution();
static void setProcessPriority(int priority);
static void setThreadPriority(int priority);
static inline const char *userAgent() { return m_userAgent; }

View File

@@ -83,6 +83,11 @@ void xmrig::Platform::restoreTimerResolution()
}
void xmrig::Platform::setProcessPriority(int)
{
}
void xmrig::Platform::setThreadPriority(int priority)
{
if (priority == -1) {

View File

@@ -111,6 +111,11 @@ void xmrig::Platform::restoreTimerResolution()
}
void xmrig::Platform::setProcessPriority(int)
{
}
void xmrig::Platform::setThreadPriority(int priority)
{
if (priority == -1) {

View File

@@ -131,6 +131,43 @@ void xmrig::Platform::restoreTimerResolution()
}
void xmrig::Platform::setProcessPriority(int priority)
{
if (priority == -1) {
return;
}
DWORD prio = IDLE_PRIORITY_CLASS;
switch (priority)
{
case 1:
prio = BELOW_NORMAL_PRIORITY_CLASS;
break;
case 2:
prio = NORMAL_PRIORITY_CLASS;
break;
case 3:
prio = ABOVE_NORMAL_PRIORITY_CLASS;
break;
case 4:
prio = HIGH_PRIORITY_CLASS;
break;
case 5:
prio = REALTIME_PRIORITY_CLASS;
break;
default:
break;
}
SetPriorityClass(GetCurrentProcess(), prio);
}
void xmrig::Platform::setThreadPriority(int priority)
{
if (priority == -1) {

View File

@@ -31,7 +31,10 @@
#include "base/tools/Chrono.h"
static size_t location(xmrig::Process::Location location, char *buf, size_t max)
namespace xmrig {
static size_t getLocation(Process::Location location, char *buf, size_t max)
{
using namespace xmrig;
@@ -48,6 +51,9 @@ static size_t location(xmrig::Process::Location location, char *buf, size_t max)
}
} // namespace xmrig
xmrig::Process::Process(int argc, char **argv) :
m_arguments(argc, argv)
{
@@ -55,12 +61,12 @@ xmrig::Process::Process(int argc, char **argv) :
}
xmrig::String xmrig::Process::location(Location location, const char *fileName) const
xmrig::String xmrig::Process::location(Location location, const char *fileName)
{
constexpr const size_t max = 520;
char *buf = new char[max]();
size_t size = ::location(location, buf, max);
size_t size = getLocation(location, buf, max);
if (size == 0) {
delete [] buf;

View File

@@ -48,7 +48,7 @@ public:
Process(int argc, char **argv);
String location(Location location, const char *fileName = nullptr) const;
static String location(Location location, const char *fileName = nullptr);
inline const Arguments &arguments() const { return m_arguments; }

View File

@@ -23,10 +23,18 @@
*/
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "base/kernel/config/BaseConfig.h"
#include "base/io/json/Json.h"
#include "base/io/log/Log.h"
#include "base/kernel/interfaces/IJsonReader.h"
#include "rapidjson/document.h"
#include "version.h"
#include <cassert>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <uv.h>
@@ -38,80 +46,6 @@
# include "backend/cpu/Cpu.h"
#endif
#ifdef XMRIG_AMD_PROJECT
# if defined(__APPLE__)
# include <OpenCL/cl.h>
# else
# include "3rdparty/CL/cl.h"
# endif
#endif
#ifdef XMRIG_NVIDIA_PROJECT
# include "nvidia/cryptonight.h"
#endif
#include "base/io/json/Json.h"
#include "base/io/log/Log.h"
#include "base/kernel/config/BaseConfig.h"
#include "base/kernel/interfaces/IJsonReader.h"
#include "donate.h"
#include "rapidjson/document.h"
#include "rapidjson/filewritestream.h"
#include "rapidjson/prettywriter.h"
#include "version.h"
void xmrig::BaseConfig::printVersions()
{
char buf[256] = { 0 };
# if defined(__clang__)
snprintf(buf, sizeof buf, "clang/%d.%d.%d", __clang_major__, __clang_minor__, __clang_patchlevel__);
# elif defined(__GNUC__)
snprintf(buf, sizeof buf, "gcc/%d.%d.%d", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__);
# elif defined(_MSC_VER)
snprintf(buf, sizeof buf, "MSVC/%d", MSVC_VERSION);
# endif
Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN_BOLD("%s/%s") WHITE_BOLD(" %s"), "ABOUT", APP_NAME, APP_VERSION, buf);
# if defined(XMRIG_AMD_PROJECT)
# if CL_VERSION_2_0
const char *ocl = "2.0";
# elif CL_VERSION_1_2
const char *ocl = "1.2";
# elif CL_VERSION_1_1
const char *ocl = "1.1";
# elif CL_VERSION_1_0
const char *ocl = "1.0";
# else
const char *ocl = "0.0";
# endif
int length = snprintf(buf, sizeof buf, "OpenCL/%s ", ocl);
# elif defined(XMRIG_NVIDIA_PROJECT)
const int cudaVersion = cuda_get_runtime_version();
int length = snprintf(buf, sizeof buf, "CUDA/%d.%d ", cudaVersion / 1000, cudaVersion % 100);
# endif
std::string libs;
# if defined(XMRIG_FEATURE_TLS) && defined(OPENSSL_VERSION_TEXT)
{
constexpr const char *v = OPENSSL_VERSION_TEXT + 8;
snprintf(buf, sizeof buf, "OpenSSL/%.*s ", static_cast<int>(strchr(v, ' ') - v), v);
libs += buf;
}
# endif
# if defined(XMRIG_FEATURE_HWLOC)
libs += Cpu::info()->backend();
# endif
Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13slibuv/%s %s"), "LIBS", uv_version_string(), libs.c_str());
}
bool xmrig::BaseConfig::read(const IJsonReader &reader, const char *fileName)
{
@@ -126,12 +60,13 @@ bool xmrig::BaseConfig::read(const IJsonReader &reader, const char *fileName)
m_dryRun = reader.getBool("dry-run", m_dryRun);
m_syslog = reader.getBool("syslog", m_syslog);
m_watch = reader.getBool("watch", m_watch);
Log::colors = reader.getBool("colors", Log::colors);
m_logFile = reader.getString("log-file");
m_userAgent = reader.getString("user-agent");
m_version = reader.getUint("version");
Log::setColors(reader.getBool("colors", Log::isColors()));
setPrintTime(reader.getUint("print-time", 60));
setVerbose(reader.getValue("verbose"));
const rapidjson::Value &api = reader.getObject("api");
if (api.IsObject()) {
@@ -162,3 +97,46 @@ bool xmrig::BaseConfig::save()
return false;
}
void xmrig::BaseConfig::printVersions()
{
char buf[256] = { 0 };
# if defined(__clang__)
snprintf(buf, sizeof buf, "clang/%d.%d.%d", __clang_major__, __clang_minor__, __clang_patchlevel__);
# elif defined(__GNUC__)
snprintf(buf, sizeof buf, "gcc/%d.%d.%d", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__);
# elif defined(_MSC_VER)
snprintf(buf, sizeof buf, "MSVC/%d", MSVC_VERSION);
# endif
Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN_BOLD("%s/%s") WHITE_BOLD(" %s"), "ABOUT", APP_NAME, APP_VERSION, buf);
std::string libs;
# if defined(XMRIG_FEATURE_TLS) && defined(OPENSSL_VERSION_TEXT)
{
constexpr const char *v = OPENSSL_VERSION_TEXT + 8;
snprintf(buf, sizeof buf, "OpenSSL/%.*s ", static_cast<int>(strchr(v, ' ') - v), v);
libs += buf;
}
# endif
# if defined(XMRIG_FEATURE_HWLOC)
libs += Cpu::info()->backend();
# endif
Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13slibuv/%s %s"), "LIBS", uv_version_string(), libs.c_str());
}
void xmrig::BaseConfig::setVerbose(const rapidjson::Value &value)
{
if (value.IsBool()) {
Log::setVerbose(value.GetBool() ? 1 : 0);
}
else if (value.IsUint()) {
Log::setVerbose(value.GetUint());
}
}

View File

@@ -82,6 +82,8 @@ protected:
private:
inline void setPrintTime(uint32_t printTime) { if (printTime <= 3600) { m_printTime = printTime; } }
void setVerbose(const rapidjson::Value &value);
};

View File

@@ -222,6 +222,7 @@ void xmrig::BaseTransform::transform(rapidjson::Document &doc, int key, const ch
case IConfig::DryRunKey: /* --dry-run */
case IConfig::HttpEnabledKey: /* --http-enabled */
case IConfig::DaemonKey: /* --daemon */
case IConfig::VerboseKey: /* --verbose */
return transformBoolean(doc, key, true);
case IConfig::ColorKey: /* --no-color */
@@ -273,6 +274,9 @@ void xmrig::BaseTransform::transformBoolean(rapidjson::Document &doc, int key, b
case IConfig::DryRunKey: /* --dry-run */
return set(doc, "dry-run", enable);
case IConfig::VerboseKey: /* --verbose */
return set(doc, "verbose", enable);
default:
break;
}

View File

@@ -92,6 +92,7 @@ public:
RandomXModeKey = 1029,
RandomX1GbPagesKey = 1031,
RandomXWrmsrKey = 1032,
RandomXRdmsrKey = 1033,
CPUMaxThreadsKey = 1026,
MemoryPoolKey = 1027,
YieldKey = 1030,

View File

@@ -23,16 +23,19 @@
*/
#include "base/kernel/interfaces/IClientListener.h"
#include "base/net/stratum/BaseClient.h"
#include "base/kernel/Env.h"
#include "base/kernel/interfaces/IClientListener.h"
#include "base/net/stratum/SubmitResult.h"
#include "rapidjson/document.h"
namespace xmrig {
int64_t BaseClient::m_sequence = 1;
} /* namespace xmrig */
@@ -43,6 +46,19 @@ xmrig::BaseClient::BaseClient(int id, IClientListener *listener) :
}
void xmrig::BaseClient::setPool(const Pool &pool)
{
if (!pool.isValid()) {
return;
}
m_pool = pool;
m_user = Env::expand(pool.user());
m_password = Env::expand(pool.password());
m_rigId = Env::expand(pool.rigId());
}
bool xmrig::BaseClient::handleResponse(int64_t id, const rapidjson::Value &result, const rapidjson::Value &error)
{
if (id == 1) {

View File

@@ -56,11 +56,12 @@ protected:
inline int64_t sequence() const override { return m_sequence; }
inline void setAlgo(const Algorithm &algo) override { m_pool.setAlgo(algo); }
inline void setEnabled(bool enabled) override { m_enabled = enabled; }
inline void setPool(const Pool &pool) override { if (pool.isValid()) { m_pool = pool; } }
inline void setQuiet(bool quiet) override { m_quiet = quiet; }
inline void setRetries(int retries) override { m_retries = retries; }
inline void setRetryPause(uint64_t ms) override { m_retryPause = ms; }
void setPool(const Pool &pool) override;
protected:
enum SocketState {
UnconnectedState,
@@ -95,6 +96,9 @@ protected:
std::map<int64_t, SendResult> m_callbacks;
std::map<int64_t, SubmitResult> m_results;
String m_ip;
String m_password;
String m_rigId;
String m_user;
uint64_t m_retryPause = 5000;
static int64_t m_sequence;

View File

@@ -79,7 +79,8 @@ static const char *states[] = {
xmrig::Client::Client(int id, const char *agent, IClientListener *listener) :
BaseClient(id, listener),
m_agent(agent)
m_agent(agent),
m_sendBuf(1024)
{
m_key = m_storage.add(this);
m_dns = new Dns(this);
@@ -158,13 +159,18 @@ int64_t xmrig::Client::send(const rapidjson::Value &obj)
obj.Accept(writer);
const size_t size = buffer.GetSize();
if (size > (sizeof(m_sendBuf) - 2)) {
LOG_ERR("[%s] send failed: \"send buffer overflow: %zu > %zu\"", url(), size, (sizeof(m_sendBuf) - 2));
if (size > kMaxSendBufferSize) {
LOG_ERR("[%s] send failed: \"max send buffer size exceeded: %zu\"", url(), size);
close();
return -1;
}
memcpy(m_sendBuf, buffer.GetString(), size);
if (size > (m_sendBuf.size() - 2)) {
m_sendBuf.resize(((size + 1) / 1024 + 1) * 1024);
}
memcpy(m_sendBuf.data(), buffer.GetString(), size);
m_sendBuf[size] = '\n';
m_sendBuf[size + 1] = '\0';
@@ -186,8 +192,8 @@ int64_t xmrig::Client::submit(const JobResult &result)
const char *nonce = result.nonce;
const char *data = result.result;
# else
char *nonce = m_sendBuf;
char *data = m_sendBuf + 16;
char *nonce = m_sendBuf.data();
char *data = m_sendBuf.data() + 16;
Buffer::toHex(reinterpret_cast<const char*>(&result.nonce), 4, nonce);
nonce[8] = '\0';
@@ -460,11 +466,7 @@ bool xmrig::Client::send(BIO *bio)
bool result = false;
if (state() == ConnectedState && uv_is_writable(m_stream)) {
result = uv_try_write(m_stream, &buf, 1) > 0;
if (!result) {
close();
}
result = write(buf);
}
else {
LOG_DEBUG_ERR("[%s] send failed, invalid state: %d", url(), m_state);
@@ -505,6 +507,23 @@ bool xmrig::Client::verifyAlgorithm(const Algorithm &algorithm, const char *algo
}
bool xmrig::Client::write(const uv_buf_t &buf)
{
const int rc = uv_try_write(m_stream, &buf, 1);
if (static_cast<size_t>(rc) == buf.len) {
return true;
}
if (!isQuiet()) {
LOG_ERR("[%s] write error: \"%s\"", url(), uv_strerror(rc));
}
close();
return false;
}
int xmrig::Client::resolve(const String &host)
{
setState(HostLookupState);
@@ -529,11 +548,11 @@ int xmrig::Client::resolve(const String &host)
int64_t xmrig::Client::send(size_t size)
{
LOG_DEBUG("[%s] send (%d bytes): \"%.*s\"", url(), size, static_cast<int>(size) - 1, m_sendBuf);
LOG_DEBUG("[%s] send (%d bytes): \"%.*s\"", url(), size, static_cast<int>(size) - 1, m_sendBuf.data());
# ifdef XMRIG_FEATURE_TLS
if (isTLS()) {
if (!m_tls->send(m_sendBuf, size)) {
if (!m_tls->send(m_sendBuf.data(), size)) {
return -1;
}
}
@@ -545,10 +564,9 @@ int64_t xmrig::Client::send(size_t size)
return -1;
}
uv_buf_t buf = uv_buf_init(m_sendBuf, (unsigned int) size);
uv_buf_t buf = uv_buf_init(m_sendBuf.data(), (unsigned int) size);
if (uv_try_write(m_stream, &buf, 1) < 0) {
close();
if (!write(buf)) {
return -1;
}
}
@@ -606,12 +624,12 @@ void xmrig::Client::login()
auto &allocator = doc.GetAllocator();
Value params(kObjectType);
params.AddMember("login", m_pool.user().toJSON(), allocator);
params.AddMember("pass", m_pool.password().toJSON(), allocator);
params.AddMember("login", m_user.toJSON(), allocator);
params.AddMember("pass", m_password.toJSON(), allocator);
params.AddMember("agent", StringRef(m_agent), allocator);
if (!m_pool.rigId().isNull()) {
params.AddMember("rigid", m_pool.rigId().toJSON(), allocator);
if (!m_rigId.isNull()) {
params.AddMember("rigid", m_rigId.toJSON(), allocator);
}
m_listener->onLogin(this, doc, params);
@@ -795,7 +813,7 @@ void xmrig::Client::parseResponse(int64_t id, const rapidjson::Value &result, co
void xmrig::Client::ping()
{
send(snprintf(m_sendBuf, sizeof(m_sendBuf), "{\"id\":%" PRId64 ",\"jsonrpc\":\"2.0\",\"method\":\"keepalived\",\"params\":{\"id\":\"%s\"}}\n", m_sequence, m_rpcId.data()));
send(snprintf(m_sendBuf.data(), m_sendBuf.size(), "{\"id\":%" PRId64 ",\"jsonrpc\":\"2.0\",\"method\":\"keepalived\",\"params\":{\"id\":\"%s\"}}\n", m_sequence, m_rpcId.data()));
m_keepAlive = 0;
}

View File

@@ -60,14 +60,10 @@ class Client : public BaseClient, public IDnsListener, public ILineListener
public:
XMRIG_DISABLE_COPY_MOVE_DEFAULT(Client)
constexpr static uint64_t kConnectTimeout = 20 * 1000;
constexpr static uint64_t kResponseTimeout = 20 * 1000;
# ifdef XMRIG_FEATURE_TLS
constexpr static size_t kInputBufferSize = 1024 * 16;
# else
constexpr static size_t kInputBufferSize = 1024 * 2;
# endif
constexpr static uint64_t kConnectTimeout = 20 * 1000;
constexpr static uint64_t kResponseTimeout = 20 * 1000;
constexpr static size_t kInputBufferSize = 1024 * 16;
constexpr static size_t kMaxSendBufferSize = 1024 * 16;
Client(int id, const char *agent, IClientListener *listener);
~Client() override;
@@ -100,6 +96,7 @@ private:
bool parseLogin(const rapidjson::Value &result, int *code);
bool send(BIO *bio);
bool verifyAlgorithm(const Algorithm &algorithm, const char *algo) const;
bool write(const uv_buf_t &buf);
int resolve(const String &host);
int64_t send(size_t size);
void connect(sockaddr *addr);
@@ -128,11 +125,11 @@ private:
static inline Client *getClient(void *data) { return m_storage.get(data); }
char m_sendBuf[2048] = { 0 };
const char *m_agent;
Dns *m_dns;
RecvBuf<kInputBufferSize> m_recvBuf;
std::bitset<EXT_MAX> m_extensions;
std::vector<char> m_sendBuf;
String m_rpcId;
Tls *m_tls = nullptr;
uint64_t m_expire = 0;

View File

@@ -284,8 +284,8 @@ int64_t xmrig::DaemonClient::getBlockTemplate()
auto &allocator = doc.GetAllocator();
Value params(kObjectType);
params.AddMember("wallet_address", m_pool.user().toJSON(), allocator);
params.AddMember("reserve_size", 8, allocator);
params.AddMember("wallet_address", m_user.toJSON(), allocator);
params.AddMember("reserve_size", 8, allocator);
JsonRequest::create(doc, m_sequence, "getblocktemplate", params);

View File

@@ -17,6 +17,7 @@
"init": -1,
"mode": "auto",
"1gb-pages": false,
"rdmsr": true,
"wrmsr": true,
"numa": true
},
@@ -74,5 +75,6 @@
"retry-pause": 5,
"syslog": false,
"user-agent": null,
"verbose": 0,
"watch": true
}

View File

@@ -262,6 +262,7 @@ xmrig::Miner::Miner(Controller *controller)
{
const int priority = controller->config()->cpu().priority();
if (priority >= 0) {
Platform::setProcessPriority(priority);
Platform::setThreadPriority(std::min(priority + 1, 5));
}

View File

@@ -218,7 +218,7 @@ void xmrig::Config::getJSON(rapidjson::Document &doc) const
doc.AddMember("http", m_http.toJSON(doc), allocator);
doc.AddMember("autosave", isAutoSave(), allocator);
doc.AddMember("background", isBackground(), allocator);
doc.AddMember("colors", Log::colors, allocator);
doc.AddMember("colors", Log::isColors(), allocator);
# ifdef XMRIG_ALGO_RANDOMX
doc.AddMember(StringRef(kRandomX), rx().toJSON(doc), allocator);
@@ -246,5 +246,6 @@ void xmrig::Config::getJSON(rapidjson::Document &doc) const
doc.AddMember("retry-pause", m_pools.retryPause(), allocator);
doc.AddMember("syslog", isSyslog(), allocator);
doc.AddMember("user-agent", m_userAgent.toJSON(), allocator);
doc.AddMember("verbose", Log::verbose(), allocator);
doc.AddMember("watch", m_watch, allocator);
}

View File

@@ -175,6 +175,9 @@ void xmrig::ConfigTransform::transform(rapidjson::Document &doc, int key, const
}
return set(doc, kRandomX, "wrmsr", static_cast<int64_t>(strtol(arg, nullptr, 10)));
case IConfig::RandomXRdmsrKey: /* --randomx-no-rdmsr */
return set(doc, kRandomX, "rdmsr", false);
# endif
# ifdef XMRIG_FEATURE_OPENCL

View File

@@ -87,6 +87,7 @@ static const option options[] = {
{ "cpu-max-threads-hint", 1, nullptr, IConfig::CPUMaxThreadsKey },
{ "cpu-memory-pool", 1, nullptr, IConfig::MemoryPoolKey },
{ "cpu-no-yield", 0, nullptr, IConfig::YieldKey },
{ "verbose", 0, nullptr, IConfig::VerboseKey },
# ifdef XMRIG_FEATURE_TLS
{ "tls", 0, nullptr, IConfig::TlsKey },
{ "tls-fingerprint", 1, nullptr, IConfig::FingerprintKey },
@@ -101,6 +102,9 @@ static const option options[] = {
{ "randomx-1gb-pages", 0, nullptr, IConfig::RandomX1GbPagesKey },
{ "1gb-pages", 0, nullptr, IConfig::RandomX1GbPagesKey },
{ "randomx-wrmsr", 2, nullptr, IConfig::RandomXWrmsrKey },
{ "wrmsr", 2, nullptr, IConfig::RandomXWrmsrKey },
{ "randomx-no-rdmsr", 0, nullptr, IConfig::RandomXRdmsrKey },
{ "no-rdmsr", 0, nullptr, IConfig::RandomXRdmsrKey },
# endif
# ifdef XMRIG_FEATURE_OPENCL
{ "opencl", 0, nullptr, IConfig::OclKey },

View File

@@ -89,7 +89,8 @@ static inline const std::string &usage()
u += " --randomx-no-numa disable NUMA support for RandomX\n";
u += " --randomx-mode=MODE RandomX mode: auto, fast, light\n";
u += " --randomx-1gb-pages use 1GB hugepages for dataset (Linux only)\n";
u += " --randomx-wrmsr=N write value (0-15) to Intel MSR register 0x1a4 or do nothing (-1) (Linux only)\n";
u += " --randomx-wrmsr=N write custom value (0-15) to Intel MSR register 0x1a4 or disable MSR mod (-1)\n";
u += " --randomx-no-rdmsr disable reverting initial MSR values on exit\n";
# endif
# ifdef XMRIG_FEATURE_HTTP
@@ -136,6 +137,7 @@ static inline const std::string &usage()
u += " --health-print-time=N print health report every N seconds\n";
# endif
u += " --no-color disable colored output\n";
u += " --verbose verbose output\n";
u += "\nMisc:\n";

View File

@@ -111,6 +111,7 @@ public:
# ifdef XMRIG_ALGO_CN_PICO
case Algorithm::CN_PICO_0:
case Algorithm::CN_PICO_TLO:
return CN_ITER / 8;
# endif
@@ -171,6 +172,7 @@ public:
case Algorithm::CN_DOUBLE:
# ifdef XMRIG_ALGO_CN_PICO
case Algorithm::CN_PICO_0:
case Algorithm::CN_PICO_TLO:
# endif
return Algorithm::CN_2;
@@ -217,6 +219,7 @@ template<> constexpr inline uint32_t CnAlgo<Algorithm::CN_RWZ>::iterations() con
template<> constexpr inline uint32_t CnAlgo<Algorithm::CN_ZLS>::iterations() const { return 0x60000; }
template<> constexpr inline uint32_t CnAlgo<Algorithm::CN_GPU>::iterations() const { return 0xC000; }
template<> constexpr inline uint32_t CnAlgo<Algorithm::CN_PICO_0>::iterations() const { return CN_ITER / 8; }
template<> constexpr inline uint32_t CnAlgo<Algorithm::CN_PICO_TLO>::iterations() const { return CN_ITER / 8; }
template<> constexpr inline size_t CnAlgo<Algorithm::CN_LITE_0>::memory() const { return CN_MEMORY / 2; }
@@ -225,6 +228,7 @@ template<> constexpr inline size_t CnAlgo<Algorithm::CN_HEAVY_0>::memory() const
template<> constexpr inline size_t CnAlgo<Algorithm::CN_HEAVY_TUBE>::memory() const { return CN_MEMORY * 2; }
template<> constexpr inline size_t CnAlgo<Algorithm::CN_HEAVY_XHV>::memory() const { return CN_MEMORY * 2; }
template<> constexpr inline size_t CnAlgo<Algorithm::CN_PICO_0>::memory() const { return CN_MEMORY / 8; }
template<> constexpr inline size_t CnAlgo<Algorithm::CN_PICO_TLO>::memory() const { return CN_MEMORY / 8; }
template<> constexpr inline uint32_t CnAlgo<Algorithm::CN_GPU>::mask() const { return 0x1FFFC0; }

View File

@@ -79,6 +79,11 @@ cn_mainloop_fun cn_trtl_mainloop_ryzen_asm = nullptr;
cn_mainloop_fun cn_trtl_mainloop_bulldozer_asm = nullptr;
cn_mainloop_fun cn_trtl_double_mainloop_sandybridge_asm = nullptr;
cn_mainloop_fun cn_tlo_mainloop_ivybridge_asm = nullptr;
cn_mainloop_fun cn_tlo_mainloop_ryzen_asm = nullptr;
cn_mainloop_fun cn_tlo_mainloop_bulldozer_asm = nullptr;
cn_mainloop_fun cn_tlo_double_mainloop_sandybridge_asm = nullptr;
cn_mainloop_fun cn_zls_mainloop_ivybridge_asm = nullptr;
cn_mainloop_fun cn_zls_mainloop_ryzen_asm = nullptr;
cn_mainloop_fun cn_zls_mainloop_bulldozer_asm = nullptr;
@@ -128,7 +133,7 @@ static void patchCode(T dst, U src, const uint32_t iterations, const uint32_t ma
static void patchAsmVariants()
{
const int allocation_size = 65536;
const int allocation_size = 81920;
auto base = static_cast<uint8_t *>(VirtualMemory::allocateExecutableMemory(allocation_size));
cn_half_mainloop_ivybridge_asm = reinterpret_cast<cn_mainloop_fun> (base + 0x0000);
@@ -153,6 +158,13 @@ static void patchAsmVariants()
cn_double_mainloop_bulldozer_asm = reinterpret_cast<cn_mainloop_fun> (base + 0xE000);
cn_double_double_mainloop_sandybridge_asm = reinterpret_cast<cn_mainloop_fun> (base + 0xF000);
# ifdef XMRIG_ALGO_CN_PICO
cn_tlo_mainloop_ivybridge_asm = reinterpret_cast<cn_mainloop_fun> (base + 0x10000);
cn_tlo_mainloop_ryzen_asm = reinterpret_cast<cn_mainloop_fun> (base + 0x11000);
cn_tlo_mainloop_bulldozer_asm = reinterpret_cast<cn_mainloop_fun> (base + 0x12000);
cn_tlo_double_mainloop_sandybridge_asm = reinterpret_cast<cn_mainloop_fun> (base + 0x13000);
# endif
{
constexpr uint32_t ITER = CnAlgo<Algorithm::CN_HALF>().iterations();
@@ -172,6 +184,16 @@ static void patchAsmVariants()
patchCode(cn_trtl_mainloop_bulldozer_asm, cnv2_mainloop_bulldozer_asm, ITER, MASK);
patchCode(cn_trtl_double_mainloop_sandybridge_asm, cnv2_double_mainloop_sandybridge_asm, ITER, MASK);
}
{
constexpr uint32_t ITER = CnAlgo<Algorithm::CN_PICO_TLO>().iterations();
constexpr uint32_t MASK = CnAlgo<Algorithm::CN_PICO_TLO>().mask();
patchCode(cn_tlo_mainloop_ivybridge_asm, cnv2_mainloop_ivybridge_asm, ITER, MASK);
patchCode(cn_tlo_mainloop_ryzen_asm, cnv2_mainloop_ryzen_asm, ITER, MASK);
patchCode(cn_tlo_mainloop_bulldozer_asm, cnv2_mainloop_bulldozer_asm, ITER, MASK);
patchCode(cn_tlo_double_mainloop_sandybridge_asm, cnv2_double_mainloop_sandybridge_asm, ITER, MASK);
}
# endif
{
@@ -244,6 +266,8 @@ xmrig::CnHash::CnHash()
# ifdef XMRIG_ALGO_CN_PICO
ADD_FN(Algorithm::CN_PICO_0);
ADD_FN_ASM(Algorithm::CN_PICO_0);
ADD_FN(Algorithm::CN_PICO_TLO);
ADD_FN_ASM(Algorithm::CN_PICO_TLO);
# endif
# ifdef XMRIG_ALGO_ARGON2

View File

@@ -338,6 +338,21 @@ const static uint8_t test_output_pico_trtl[160] = {
0xA1, 0xE7, 0x53, 0x85, 0xFB, 0x72, 0xDD, 0x75, 0x90, 0x39, 0xB2, 0x3D, 0xC3, 0x08, 0x2C, 0xD5,
0x01, 0x08, 0x27, 0x75, 0x86, 0xB9, 0xBB, 0x9B, 0xDF, 0xEA, 0x49, 0xDE, 0x46, 0xCB, 0x83, 0x45
};
// "cn-pico/tlo"
const static uint8_t test_output_pico_tlo[160] = {
0x99, 0x75, 0xF2, 0xC1, 0xB3, 0xB4, 0x54, 0x34, 0xA4, 0x93, 0x86, 0x21, 0x30, 0x97, 0xF3, 0x1B,
0xB4, 0xB9, 0xA6, 0x58, 0x6A, 0x7E, 0x81, 0xF4, 0x42, 0x9F, 0x6D, 0x5F, 0x65, 0xC3, 0x8D, 0x1A,
0xFC, 0x67, 0xDF, 0xCC, 0xB5, 0xFC, 0x90, 0xD7, 0x85, 0x5A, 0xE9, 0x03, 0x36, 0x1E, 0xAB, 0xD7,
0x6F, 0x1E, 0x40, 0xA2, 0x2A, 0x72, 0xAD, 0x3E, 0xF2, 0xD6, 0xAD, 0x27, 0xB5, 0xA6, 0x0C, 0xE5,
0x1C, 0xB1, 0x53, 0xE9, 0x70, 0x7D, 0x69, 0xF1, 0xE1, 0x55, 0x28, 0x45, 0xF5, 0x76, 0x56, 0xE5,
0x10, 0x0D, 0xEA, 0xFD, 0xD9, 0xD6, 0xAF, 0x0F, 0x47, 0x0C, 0x0D, 0xA2, 0x10, 0x16, 0x43, 0xEE,
0x25, 0x2C, 0x07, 0x3A, 0x64, 0x29, 0x16, 0xFF, 0xF5, 0xA5, 0x0B, 0xA2, 0xE0, 0xBD, 0xDC, 0xCE,
0x93, 0x3F, 0xEF, 0x6B, 0x08, 0xF4, 0x4D, 0x6A, 0x6E, 0x14, 0x13, 0x10, 0x98, 0x11, 0xE1, 0x13,
0xF6, 0x9D, 0x3D, 0x31, 0xC4, 0x3A, 0xA9, 0x44, 0x4C, 0x38, 0xAB, 0xB5, 0x4B, 0xD9, 0xFB, 0xE6,
0x98, 0xB9, 0x46, 0xE2, 0x00, 0xEB, 0x56, 0x33, 0x1E, 0xBC, 0xEB, 0xF1, 0xF6, 0x88, 0xD3, 0xF0
};
#endif

View File

@@ -794,6 +794,11 @@ extern cn_mainloop_fun cn_trtl_mainloop_ryzen_asm;
extern cn_mainloop_fun cn_trtl_mainloop_bulldozer_asm;
extern cn_mainloop_fun cn_trtl_double_mainloop_sandybridge_asm;
extern cn_mainloop_fun cn_tlo_mainloop_ivybridge_asm;
extern cn_mainloop_fun cn_tlo_mainloop_ryzen_asm;
extern cn_mainloop_fun cn_tlo_mainloop_bulldozer_asm;
extern cn_mainloop_fun cn_tlo_double_mainloop_sandybridge_asm;
extern cn_mainloop_fun cn_zls_mainloop_ivybridge_asm;
extern cn_mainloop_fun cn_zls_mainloop_ryzen_asm;
extern cn_mainloop_fun cn_zls_mainloop_bulldozer_asm;
@@ -879,6 +884,17 @@ inline void cryptonight_single_hash_asm(const uint8_t *__restrict__ input, size_
cn_trtl_mainloop_bulldozer_asm(ctx);
}
}
else if (ALGO == Algorithm::CN_PICO_TLO) {
if (ASM == Assembly::INTEL) {
cn_tlo_mainloop_ivybridge_asm(ctx);
}
else if (ASM == Assembly::RYZEN) {
cn_tlo_mainloop_ryzen_asm(ctx);
}
else {
cn_tlo_mainloop_bulldozer_asm(ctx);
}
}
# endif
else if (ALGO == Algorithm::CN_RWZ) {
cnv2_rwz_mainloop_asm(ctx);
@@ -944,6 +960,9 @@ inline void cryptonight_double_hash_asm(const uint8_t *__restrict__ input, size_
else if (ALGO == Algorithm::CN_PICO_0) {
cn_trtl_double_mainloop_sandybridge_asm(ctx);
}
else if (ALGO == Algorithm::CN_PICO_TLO) {
cn_tlo_double_mainloop_sandybridge_asm(ctx);
}
# endif
else if (ALGO == Algorithm::CN_RWZ) {
cnv2_rwz_double_mainloop_asm(ctx);

View File

@@ -101,6 +101,10 @@ static AlgoName const algorithm_names[] = {
{ "cryptonight-turtle", "cn-trtl", Algorithm::CN_PICO_0 },
{ "cryptonight-ultralite", "cn-ultralite", Algorithm::CN_PICO_0 },
{ "cryptonight_turtle", "cn_turtle", Algorithm::CN_PICO_0 },
{ "cryptonight-pico/tlo", "cn-pico/tlo", Algorithm::CN_PICO_TLO },
{ "cryptonight/ultra", "cn/ultra", Algorithm::CN_PICO_TLO },
{ "cryptonight-talleo", "cn-talleo", Algorithm::CN_PICO_TLO },
{ "cryptonight_talleo", "cn_talleo", Algorithm::CN_PICO_TLO },
# endif
# ifdef XMRIG_ALGO_RANDOMX
{ "randomx/0", "rx/0", Algorithm::RX_0 },
@@ -112,6 +116,8 @@ static AlgoName const algorithm_names[] = {
{ "RandomXL", nullptr, Algorithm::RX_LOKI },
{ "randomx/arq", "rx/arq", Algorithm::RX_ARQ },
{ "RandomARQ", nullptr, Algorithm::RX_ARQ },
{ "randomx/sfx", "rx/sfx", Algorithm::RX_SFX },
{ "RandomSFX", nullptr, Algorithm::RX_SFX },
# endif
# ifdef XMRIG_ALGO_ARGON2
{ "argon2/chukwa", nullptr, Algorithm::AR2_CHUKWA },
@@ -138,6 +144,7 @@ size_t xmrig::Algorithm::l2() const
switch (m_id) {
case RX_0:
case RX_LOKI:
case RX_SFX:
return 0x40000;
case RX_WOW:
@@ -173,6 +180,7 @@ size_t xmrig::Algorithm::l3() const
switch (m_id) {
case RX_0:
case RX_LOKI:
case RX_SFX:
return oneMiB * 2;
case RX_WOW:
@@ -264,6 +272,7 @@ xmrig::Algorithm::Family xmrig::Algorithm::family(Id id)
# ifdef XMRIG_ALGO_CN_PICO
case CN_PICO_0:
case CN_PICO_TLO:
return CN_PICO;
# endif
@@ -272,6 +281,7 @@ xmrig::Algorithm::Family xmrig::Algorithm::family(Id id)
case RX_WOW:
case RX_LOKI:
case RX_ARQ:
case RX_SFX:
return RANDOM_X;
# endif

View File

@@ -62,11 +62,13 @@ public:
CN_HEAVY_0, // "cn-heavy/0" CryptoNight-Heavy (4 MB).
CN_HEAVY_TUBE, // "cn-heavy/tube" CryptoNight-Heavy (modified, TUBE only).
CN_HEAVY_XHV, // "cn-heavy/xhv" CryptoNight-Heavy (modified, Haven Protocol only).
CN_PICO_0, // "cn-pico" CryptoNight Turtle (TRTL)
CN_PICO_0, // "cn-pico" CryptoNight-Pico
CN_PICO_TLO, // "cn-pico/tlo" CryptoNight-Pico (TLO)
RX_0, // "rx/0" RandomX (reference configuration).
RX_WOW, // "rx/wow" RandomWOW (Wownero).
RX_LOKI, // "rx/loki" RandomXL (Loki).
RX_ARQ, // "rx/arq" RandomARQ (Arqma).
RX_SFX, // "rx/sfx" RandomSFX (Safex Cash).
AR2_CHUKWA, // "argon2/chukwa" Argon2id (Chukwa).
AR2_WRKZ, // "argon2/wrkz" Argon2id (WRKZ)
MAX

View File

@@ -1,4 +1,5 @@
;# save VM register values
add rsp, 24
pop rcx
mov qword ptr [rcx+0], r8
mov qword ptr [rcx+8], r9

View File

@@ -1,5 +1,5 @@
lea rcx, [rsi+rax]
push rcx
mov [rsp+8], rcx
xor r8, qword ptr [rcx+0]
xor r9, qword ptr [rcx+8]
xor r10, qword ptr [rcx+16]
@@ -9,7 +9,7 @@
xor r14, qword ptr [rcx+48]
xor r15, qword ptr [rcx+56]
lea rcx, [rsi+rdx]
push rcx
mov [rsp+16], rcx
cvtdq2pd xmm0, qword ptr [rcx+0]
cvtdq2pd xmm1, qword ptr [rcx+8]
cvtdq2pd xmm2, qword ptr [rcx+16]

View File

@@ -1,4 +1,4 @@
pop rcx
mov rcx, [rsp+16]
mov qword ptr [rcx+0], r8
mov qword ptr [rcx+8], r9
mov qword ptr [rcx+16], r10
@@ -7,7 +7,7 @@
mov qword ptr [rcx+40], r13
mov qword ptr [rcx+48], r14
mov qword ptr [rcx+56], r15
pop rcx
mov rcx, [rsp+8]
xorpd xmm0, xmm4
xorpd xmm1, xmm5
xorpd xmm2, xmm6

View File

@@ -36,6 +36,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "crypto/randomx/program.hpp"
#include "crypto/randomx/reciprocal.h"
#include "crypto/randomx/virtual_memory.hpp"
#include "crypto/rx/Rx.h"
#ifdef _MSC_VER
# include <intrin.h>
@@ -168,8 +169,8 @@ namespace randomx {
static const uint8_t REX_MAXPD[] = { 0x66, 0x41, 0x0f, 0x5f };
static const uint8_t REX_DIVPD[] = { 0x66, 0x41, 0x0f, 0x5e };
static const uint8_t SQRTPD[] = { 0x66, 0x0f, 0x51 };
static const uint8_t AND_OR_MOV_LDMXCSR[] = { 0x25, 0x00, 0x60, 0x00, 0x00, 0x0D, 0xC0, 0x9F, 0x00, 0x00, 0x89, 0x44, 0x24, 0xFC, 0x0F, 0xAE, 0x54, 0x24, 0xFC };
static const uint8_t AND_OR_MOV_LDMXCSR_RYZEN[] = { 0x25, 0x00, 0x60, 0x00, 0x00, 0x0D, 0xC0, 0x9F, 0x00, 0x00, 0x3B, 0x44, 0x24, 0xFC, 0x74, 0x09, 0x89, 0x44, 0x24, 0xFC, 0x0F, 0xAE, 0x54, 0x24, 0xFC };
static const uint8_t AND_OR_MOV_LDMXCSR[] = { 0x25, 0x00, 0x60, 0x00, 0x00, 0x0D, 0xC0, 0x9F, 0x00, 0x00, 0x89, 0x04, 0x24, 0x0F, 0xAE, 0x14, 0x24 };
static const uint8_t AND_OR_MOV_LDMXCSR_RYZEN[] = { 0x25, 0x00, 0x60, 0x00, 0x00, 0x0D, 0xC0, 0x9F, 0x00, 0x00, 0x3B, 0x04, 0x24, 0x74, 0x07, 0x89, 0x04, 0x24, 0x0F, 0xAE, 0x14, 0x24 };
static const uint8_t ROL_RAX[] = { 0x48, 0xc1, 0xc0 };
static const uint8_t XOR_ECX_ECX[] = { 0x33, 0xC9 };
static const uint8_t REX_CMP_R32I[] = { 0x41, 0x81 };
@@ -289,6 +290,11 @@ namespace randomx {
JitCompilerX86::JitCompilerX86() {
applyTweaks();
int32_t info[4];
cpuid(1, info);
hasAVX = ((info[2] & (1 << 27)) != 0) && ((info[2] & (1 << 28)) != 0);
allocatedCode = (uint8_t*)allocExecutableMemory(CodeSize * 2);
// Shift code base address to improve caching - all threads will use different L2/L3 cache sets
code = allocatedCode + (codeOffset.fetch_add(59 * 64) % CodeSize);
@@ -374,6 +380,14 @@ namespace randomx {
code[codePos + 5] = 0xc0 + pcfg.readReg1;
*(uint32_t*)(code + codePos + 10) = RandomX_CurrentConfig.ScratchpadL3Mask64_Calculated;
*(uint32_t*)(code + codePos + 20) = RandomX_CurrentConfig.ScratchpadL3Mask64_Calculated;
if (hasAVX) {
uint32_t* p = (uint32_t*)(code + codePos + 32);
*p = (*p & 0xFF000000U) | 0x0077F8C5U;
}
# ifdef XMRIG_FIX_RYZEN
xmrig::Rx::setMainLoopBounds(code + prologueSize, code + epilogueOffset);
# endif
codePos = prologueSize;
memcpy(code + codePos - 48, &pcfg.eMask, sizeof(pcfg.eMask));

View File

@@ -73,6 +73,7 @@ namespace randomx {
uint32_t vm_flags;
static bool BranchesWithin32B;
bool hasAVX;
static void applyTweaks();
void generateProgramPrologue(Program&, ProgramConfiguration&);

View File

@@ -93,7 +93,11 @@ DECL(randomx_program_prologue_first_load):
and eax, RANDOMX_SCRATCHPAD_MASK
ror rdx, 32
and edx, RANDOMX_SCRATCHPAD_MASK
stmxcsr dword ptr [rsp-20]
sub rsp, 24
stmxcsr dword ptr [rsp]
nop
nop
nop
jmp DECL(randomx_program_loop_begin)
.balign 64

View File

@@ -81,7 +81,11 @@ randomx_program_prologue_first_load PROC
and eax, RANDOMX_SCRATCHPAD_MASK
ror rdx, 32
and edx, RANDOMX_SCRATCHPAD_MASK
stmxcsr dword ptr [rsp-20]
sub rsp, 24
stmxcsr dword ptr [rsp]
nop
nop
nop
jmp randomx_program_loop_begin
randomx_program_prologue_first_load ENDP

View File

@@ -92,6 +92,11 @@ RandomX_ConfigurationArqma::RandomX_ConfigurationArqma()
ScratchpadL3_Size = 262144;
}
RandomX_ConfigurationSafex::RandomX_ConfigurationSafex()
{
ArgonSalt = "RandomSFX\x01";
}
RandomX_ConfigurationBase::RandomX_ConfigurationBase()
: ArgonMemory(262144)
, ArgonIterations(3)
@@ -267,12 +272,17 @@ RandomX_ConfigurationMonero RandomX_MoneroConfig;
RandomX_ConfigurationWownero RandomX_WowneroConfig;
RandomX_ConfigurationLoki RandomX_LokiConfig;
RandomX_ConfigurationArqma RandomX_ArqmaConfig;
RandomX_ConfigurationSafex RandomX_SafexConfig;
RandomX_ConfigurationBase RandomX_CurrentConfig;
extern "C" {
randomx_cache *randomx_create_cache(randomx_flags flags, uint8_t *memory) {
if (!memory) {
return nullptr;
}
randomx_cache *cache = nullptr;
try {
@@ -317,6 +327,10 @@ extern "C" {
}
randomx_dataset *randomx_create_dataset(uint8_t *memory) {
if (!memory) {
return nullptr;
}
auto dataset = new randomx_dataset();
dataset->memory = memory;

View File

@@ -182,11 +182,13 @@ struct RandomX_ConfigurationMonero : public RandomX_ConfigurationBase {};
struct RandomX_ConfigurationWownero : public RandomX_ConfigurationBase { RandomX_ConfigurationWownero(); };
struct RandomX_ConfigurationLoki : public RandomX_ConfigurationBase { RandomX_ConfigurationLoki(); };
struct RandomX_ConfigurationArqma : public RandomX_ConfigurationBase { RandomX_ConfigurationArqma(); };
struct RandomX_ConfigurationSafex : public RandomX_ConfigurationBase { RandomX_ConfigurationSafex(); };
extern RandomX_ConfigurationMonero RandomX_MoneroConfig;
extern RandomX_ConfigurationWownero RandomX_WowneroConfig;
extern RandomX_ConfigurationLoki RandomX_LokiConfig;
extern RandomX_ConfigurationArqma RandomX_ArqmaConfig;
extern RandomX_ConfigurationSafex RandomX_SafexConfig;
extern RandomX_ConfigurationBase RandomX_CurrentConfig;

View File

@@ -73,7 +73,8 @@ bool xmrig::Rx::init(const Job &job, const RxConfig &config, const CpuConfig &cp
}
if (!osInitialized) {
osInit(config);
msrInit(config);
setupMainLoopExceptionFrame();
osInitialized = true;
}
@@ -103,6 +104,10 @@ xmrig::RxDataset *xmrig::Rx::dataset(const Job &job, uint32_t nodeId)
void xmrig::Rx::destroy()
{
if (osInitialized) {
msrDestroy();
}
delete d_ptr;
d_ptr = nullptr;
@@ -115,8 +120,20 @@ void xmrig::Rx::init(IRxListener *listener)
}
#if !defined(XMRIG_OS_LINUX) || defined(XMRIG_ARM)
void xmrig::Rx::osInit(const RxConfig &)
#ifndef XMRIG_FEATURE_MSR
void xmrig::Rx::msrInit(const RxConfig &)
{
}
void xmrig::Rx::msrDestroy()
{
}
#endif
#ifndef XMRIG_FIX_RYZEN
void xmrig::Rx::setupMainLoopExceptionFrame()
{
}
#endif

View File

@@ -57,8 +57,19 @@ public:
static void destroy();
static void init(IRxListener *listener);
# ifdef XMRIG_FIX_RYZEN
static inline const std::pair<const void*, const void*> &mainLoopBounds() { return m_mainLoopBounds; }
static inline void setMainLoopBounds(const void* loopBegin, const void* loopEnd) { m_mainLoopBounds.first = loopBegin; m_mainLoopBounds.second = loopEnd; }
# endif
private:
static void osInit(const RxConfig &config);
static void msrInit(const RxConfig &config);
static void msrDestroy();
static void setupMainLoopExceptionFrame();
# ifdef XMRIG_FIX_RYZEN
static thread_local std::pair<const void*, const void*> m_mainLoopBounds;
# endif
};

View File

@@ -49,6 +49,9 @@ const RandomX_ConfigurationBase *xmrig::RxAlgo::base(Algorithm::Id algorithm)
case Algorithm::RX_ARQ:
return &RandomX_ArqmaConfig;
case Algorithm::RX_SFX:
return &RandomX_SafexConfig;
default:
break;
}

View File

@@ -51,6 +51,15 @@ public:
static uint32_t programIterations(Algorithm::Id algorithm);
static uint32_t programSize(Algorithm::Id algorithm);
static uint32_t version(Algorithm::Id algorithm);
static inline Algorithm::Id id(Algorithm::Id algorithm)
{
if (algorithm == Algorithm::RX_SFX) {
return Algorithm::RX_0;
}
return algorithm;
}
};

View File

@@ -48,13 +48,11 @@ public:
XMRIG_DISABLE_COPY_MOVE(RxBasicStoragePrivate)
inline RxBasicStoragePrivate() = default;
inline ~RxBasicStoragePrivate()
{
delete m_dataset;
}
inline ~RxBasicStoragePrivate() { deleteDataset(); }
inline bool isReady(const Job &job) const { return m_ready && m_seed == job; }
inline RxDataset *dataset() const { return m_dataset; }
inline void deleteDataset() { delete m_dataset; m_dataset = nullptr; }
inline void setSeed(const RxSeed &seed)
@@ -69,12 +67,22 @@ public:
}
inline void createDataset(bool hugePages, bool oneGbPages, RxConfig::Mode mode)
inline bool createDataset(bool hugePages, bool oneGbPages, RxConfig::Mode mode)
{
const uint64_t ts = Chrono::steadyMSecs();
m_dataset = new RxDataset(hugePages, oneGbPages, true, mode, 0);
if (!m_dataset->cache()->get()) {
deleteDataset();
LOG_INFO("%s" RED_BOLD("failed to allocate RandomX memory") BLACK_BOLD(" (%" PRIu64 " ms)"), rx_tag(), Chrono::steadyMSecs() - ts);
return false;
}
printAllocStatus(ts);
return true;
}
@@ -82,11 +90,11 @@ public:
{
const uint64_t ts = Chrono::steadyMSecs();
m_dataset->init(m_seed.data(), threads, priority);
m_ready = m_dataset->init(m_seed.data(), threads, priority);
LOG_INFO("%s" GREEN_BOLD("dataset ready") BLACK_BOLD(" (%" PRIu64 " ms)"), rx_tag(), Chrono::steadyMSecs() - ts);
m_ready = true;
if (m_ready) {
LOG_INFO("%s" GREEN_BOLD("dataset ready") BLACK_BOLD(" (%" PRIu64 " ms)"), rx_tag(), Chrono::steadyMSecs() - ts);
}
}
@@ -136,6 +144,12 @@ xmrig::RxBasicStorage::~RxBasicStorage()
}
bool xmrig::RxBasicStorage::isAllocated() const
{
return d_ptr->dataset() && d_ptr->dataset()->cache() && d_ptr->dataset()->cache()->get();
}
xmrig::HugePagesInfo xmrig::RxBasicStorage::hugePages() const
{
if (!d_ptr->dataset()) {
@@ -160,8 +174,8 @@ void xmrig::RxBasicStorage::init(const RxSeed &seed, uint32_t threads, bool huge
{
d_ptr->setSeed(seed);
if (!d_ptr->dataset()) {
d_ptr->createDataset(hugePages, oneGbPages, mode);
if (!d_ptr->dataset() && !d_ptr->createDataset(hugePages, oneGbPages, mode)) {
return;
}
d_ptr->initDataset(threads, priority);

View File

@@ -48,6 +48,7 @@ public:
~RxBasicStorage() override;
protected:
bool isAllocated() const override;
HugePagesInfo hugePages() const override;
RxDataset *dataset(const Job &job, uint32_t nodeId) const override;
void init(const RxSeed &seed, uint32_t threads, bool hugePages, bool oneGbPages, RxConfig::Mode mode, int priority) override;

View File

@@ -30,9 +30,7 @@
#include "crypto/randomx/randomx.h"
static_assert(RANDOMX_FLAG_JIT == 8, "RANDOMX_FLAG_JIT flag mismatch");
static_assert(RANDOMX_FLAG_LARGE_PAGES == 1, "RANDOMX_FLAG_LARGE_PAGES flag mismatch");
static_assert(RANDOMX_FLAG_JIT == 8, "RANDOMX_FLAG_JIT flag mismatch");
xmrig::RxCache::RxCache(bool hugePages, uint32_t nodeId)
@@ -64,9 +62,14 @@ bool xmrig::RxCache::init(const Buffer &seed)
}
m_seed = seed;
randomx_init_cache(m_cache, m_seed.data(), m_seed.size());
return true;
if (m_cache) {
randomx_init_cache(m_cache, m_seed.data(), m_seed.size());
return true;
}
return false;
}
@@ -78,6 +81,10 @@ xmrig::HugePagesInfo xmrig::RxCache::hugePages() const
void xmrig::RxCache::create(uint8_t *memory)
{
if (!memory) {
return;
}
m_cache = randomx_create_cache(RANDOMX_FLAG_JIT, memory);
if (!m_cache) {

View File

@@ -49,6 +49,7 @@ namespace xmrig {
static const char *kInit = "init";
static const char *kMode = "mode";
static const char *kOneGbPages = "1gb-pages";
static const char *kRdmsr = "rdmsr";
static const char *kWrmsr = "wrmsr";
#ifdef XMRIG_FEATURE_HWLOC
@@ -57,6 +58,23 @@ static const char *kNUMA = "numa";
static const std::array<const char *, RxConfig::ModeMax> modeNames = { "auto", "fast", "light" };
#ifdef XMRIG_FEATURE_MSR
constexpr size_t kMsrArraySize = 4;
static const std::array<MsrItems, kMsrArraySize> msrPresets = {
MsrItems(),
MsrItems{{ 0xC0011020, 0x0 }, { 0xC0011021, 0x40, ~0x20ULL }, { 0xC0011022, 0x510000 }, { 0xC001102b, 0x1808cc16 }},
MsrItems{{ 0x1a4, 0x6 }},
MsrItems()
};
static const std::array<const char *, kMsrArraySize> modNames = { "none", "ryzen", "intel", "custom" };
static_assert (kMsrArraySize == ICpuInfo::MSR_MOD_MAX, "kMsrArraySize and MSR_MOD_MAX mismatch");
#endif
}
@@ -65,7 +83,11 @@ bool xmrig::RxConfig::read(const rapidjson::Value &value)
if (value.IsObject()) {
m_threads = Json::getInt(value, kInit, m_threads);
m_mode = readMode(Json::getValue(value, kMode));
m_wrmsr = readMSR(Json::getValue(value, kWrmsr));
m_rdmsr = Json::getBool(value, kRdmsr, m_rdmsr);
# ifdef XMRIG_FEATURE_MSR
readMSR(Json::getValue(value, kWrmsr));
# endif
# ifdef XMRIG_OS_LINUX
m_oneGbPages = Json::getBool(value, kOneGbPages, m_oneGbPages);
@@ -109,13 +131,25 @@ rapidjson::Value xmrig::RxConfig::toJSON(rapidjson::Document &doc) const
obj.AddMember(StringRef(kInit), m_threads, allocator);
obj.AddMember(StringRef(kMode), StringRef(modeName()), allocator);
obj.AddMember(StringRef(kOneGbPages), m_oneGbPages, allocator);
obj.AddMember(StringRef(kRdmsr), m_rdmsr, allocator);
if (m_wrmsr < 0 || m_wrmsr == 6) {
obj.AddMember(StringRef(kWrmsr), m_wrmsr == 6, allocator);
# ifdef XMRIG_FEATURE_MSR
if (!m_msrPreset.empty()) {
Value wrmsr(kArrayType);
wrmsr.Reserve(m_msrPreset.size(), allocator);
for (const auto &i : m_msrPreset) {
wrmsr.PushBack(i.toJSON(doc), allocator);
}
obj.AddMember(StringRef(kWrmsr), wrmsr, allocator);
}
else {
obj.AddMember(StringRef(kWrmsr), m_wrmsr, allocator);
}
# else
obj.AddMember(StringRef(kWrmsr), false, allocator);
# endif
# ifdef XMRIG_FEATURE_HWLOC
if (!m_nodeset.empty()) {
@@ -168,20 +202,71 @@ uint32_t xmrig::RxConfig::threads(uint32_t limit) const
}
int xmrig::RxConfig::readMSR(const rapidjson::Value &value) const
#ifdef XMRIG_FEATURE_MSR
const char *xmrig::RxConfig::msrPresetName() const
{
if (value.IsInt()) {
return std::min(value.GetInt(), 15);
}
if (value.IsBool() && !value.GetBool()) {
return -1;
}
return m_wrmsr;
return modNames[msrMod()];
}
const xmrig::MsrItems &xmrig::RxConfig::msrPreset() const
{
const auto mod = msrMod();
if (mod == ICpuInfo::MSR_MOD_CUSTOM) {
return m_msrPreset;
}
return msrPresets[mod];
}
uint32_t xmrig::RxConfig::msrMod() const
{
if (!wrmsr()) {
return ICpuInfo::MSR_MOD_NONE;
}
if (!m_msrPreset.empty()) {
return ICpuInfo::MSR_MOD_CUSTOM;
}
return Cpu::info()->msrMod();
}
void xmrig::RxConfig::readMSR(const rapidjson::Value &value)
{
if (value.IsBool()) {
m_wrmsr = value.GetBool();
return;
}
if (value.IsInt() && Cpu::info()->vendor() == ICpuInfo::VENDOR_INTEL) {
const int i = std::min(value.GetInt(), 15);
if (i >= 0) {
m_msrPreset.emplace_back(0x1a4, i);
}
else {
m_wrmsr = false;
}
}
if (value.IsArray()) {
for (const auto &i : value.GetArray()) {
MsrItem item(i);
if (item.isValid()) {
m_msrPreset.emplace_back(item);
}
}
m_wrmsr = !m_msrPreset.empty();
}
}
#endif
xmrig::RxConfig::Mode xmrig::RxConfig::readMode(const rapidjson::Value &value) const
{
if (value.IsUint()) {

View File

@@ -29,6 +29,11 @@
#include "rapidjson/fwd.h"
#ifdef XMRIG_FEATURE_MSR
# include "crypto/rx/msr/MsrItem.h"
#endif
#include <vector>
@@ -58,17 +63,32 @@ public:
uint32_t threads(uint32_t limit = 100) const;
inline bool isOneGbPages() const { return m_oneGbPages; }
inline int wrmsr() const { return m_wrmsr; }
inline bool rdmsr() const { return m_rdmsr; }
inline bool wrmsr() const { return m_wrmsr; }
inline Mode mode() const { return m_mode; }
# ifdef XMRIG_FEATURE_MSR
const char *msrPresetName() const;
const MsrItems &msrPreset() const;
# endif
private:
int readMSR(const rapidjson::Value &value) const;
# ifdef XMRIG_FEATURE_MSR
uint32_t msrMod() const;
void readMSR(const rapidjson::Value &value);
bool m_wrmsr = true;
MsrItems m_msrPreset;
# else
bool m_wrmsr = false;
# endif
Mode readMode(const rapidjson::Value &value) const;
bool m_numa = true;
bool m_oneGbPages = false;
bool m_rdmsr = true;
int m_threads = -1;
int m_wrmsr = 6;
Mode m_mode = AutoMode;
# ifdef XMRIG_FEATURE_HWLOC

View File

@@ -88,7 +88,7 @@ xmrig::RxDataset::~RxDataset()
bool xmrig::RxDataset::init(const Buffer &seed, uint32_t numThreads, int priority)
{
if (!m_cache) {
if (!m_cache || !m_cache->get()) {
return false;
}

View File

@@ -120,7 +120,7 @@ public:
}
inline void createDatasets(bool hugePages, bool oneGbPages)
inline bool createDatasets(bool hugePages, bool oneGbPages)
{
const uint64_t ts = Chrono::steadyMSecs();
@@ -133,6 +133,10 @@ public:
if (isCacheRequired()) {
std::thread thread(allocateCache, this, m_nodeset.front(), hugePages);
thread.join();
if (!m_cache) {
return false;
}
}
if (m_datasets.empty()) {
@@ -149,6 +153,8 @@ public:
}
m_allocated = true;
return true;
}
@@ -237,6 +243,13 @@ private:
bindToNUMANode(nodeId);
auto cache = new RxCache(hugePages, nodeId);
if (!cache->get()) {
delete cache;
LOG_INFO("%s" RED_BOLD("failed to allocate RandomX memory") BLACK_BOLD(" (%" PRIu64 " ms)"), rx_tag(), Chrono::steadyMSecs() - ts);
return;
}
std::lock_guard<std::mutex> lock(mutex);
d_ptr->m_cache = cache;
@@ -336,6 +349,12 @@ xmrig::RxNUMAStorage::~RxNUMAStorage()
}
bool xmrig::RxNUMAStorage::isAllocated() const
{
return d_ptr->isAllocated();
}
xmrig::HugePagesInfo xmrig::RxNUMAStorage::hugePages() const
{
if (!d_ptr->isAllocated()) {
@@ -360,8 +379,8 @@ void xmrig::RxNUMAStorage::init(const RxSeed &seed, uint32_t threads, bool hugeP
{
d_ptr->setSeed(seed);
if (!d_ptr->isAllocated()) {
d_ptr->createDatasets(hugePages, oneGbPages);
if (!d_ptr->isAllocated() && !d_ptr->createDatasets(hugePages, oneGbPages)) {
return;
}
d_ptr->initDatasets(threads, priority);

View File

@@ -51,6 +51,7 @@ public:
~RxNUMAStorage() override;
protected:
bool isAllocated() const override;
HugePagesInfo hugePages() const override;
RxDataset *dataset(const Job &job, uint32_t nodeId) const override;
void init(const RxSeed &seed, uint32_t threads, bool hugePages, bool oneGbPages, RxConfig::Mode mode, int priority) override;

View File

@@ -126,7 +126,7 @@ void xmrig::RxQueue::enqueue(const RxSeed &seed, const std::vector<uint32_t> &no
bool xmrig::RxQueue::isReadyUnsafe(const Job &job) const
{
return m_storage != nullptr && m_state == STATE_IDLE && m_seed == job;
return m_storage != nullptr && m_storage->isAllocated() && m_state == STATE_IDLE && m_seed == job;
}

View File

@@ -28,12 +28,13 @@
#include "crypto/rx/Rx.h"
#include "backend/common/Tags.h"
#include "backend/cpu/Cpu.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>
@@ -42,21 +43,66 @@
#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;
}
static bool wrmsr_on_cpu(uint32_t reg, uint32_t cpu, uint64_t value)
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 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 = (value & mask) | (old_value & ~mask);
}
}
char msr_file_name[64]{};
sprintf(msr_file_name, "/dev/cpu/%d/msr", cpu);
int fd = open(msr_file_name, O_WRONLY);
if (fd < 0) {
@@ -71,14 +117,14 @@ static bool wrmsr_on_cpu(uint32_t reg, uint32_t cpu, uint64_t value)
}
static bool wrmsr_on_all_cpus(uint32_t reg, uint64_t value)
static bool wrmsr_on_all_cpus(uint32_t reg, uint64_t value, uint64_t mask)
{
struct dirent **namelist;
int dir_entries = scandir("/dev/cpu", &namelist, dir_filter, 0);
int errors = 0;
while (dir_entries--) {
if (!wrmsr_on_cpu(reg, strtoul(namelist[dir_entries]->d_name, nullptr, 10), value)) {
if (!wrmsr_on_cpu(reg, strtoul(namelist[dir_entries]->d_name, nullptr, 10), value, mask)) {
++errors;
}
@@ -88,7 +134,7 @@ static bool wrmsr_on_all_cpus(uint32_t reg, uint64_t value)
free(namelist);
if (errors) {
LOG_WARN(CLEAR "%s" YELLOW_BOLD_S "cannot set MSR 0x%08" PRIx32 " to 0x%08" PRIx64, rx_tag(), reg, value);
LOG_WARN(CLEAR "%s" YELLOW_BOLD_S "cannot set MSR 0x%08" PRIx32 " to 0x%08" PRIx64, tag, reg, value);
}
return errors == 0;
@@ -98,7 +144,7 @@ static bool wrmsr_on_all_cpus(uint32_t reg, uint64_t value)
static bool wrmsr_modprobe()
{
if (system("/sbin/modprobe msr > /dev/null 2>&1") != 0) {
LOG_WARN(CLEAR "%s" YELLOW_BOLD_S "msr kernel module is not available", rx_tag());
LOG_WARN(CLEAR "%s" YELLOW_BOLD_S "msr kernel module is not available", tag);
return false;
}
@@ -107,25 +153,91 @@ static bool wrmsr_modprobe()
}
static bool wrmsr(const MsrItems &preset, 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(), i.value());
if (item.isValid()) {
savedState.emplace_back(item);
}
}
}
for (const auto &i : preset) {
if (!wrmsr_on_all_cpus(i.reg(), i.value(), i.mask())) {
return false;
}
}
return true;
}
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 = Rx::mainLoopBounds();
if ((loopBounds.first <= p) && (p < loopBounds.second)) {
ucp->uc_mcontext.gregs[REG_RIP] = reinterpret_cast<size_t>(loopBounds.second);
}
else {
abort();
}
}
thread_local std::pair<const void*, const void*> Rx::m_mainLoopBounds = { nullptr, nullptr };
} // namespace xmrig
void xmrig::Rx::osInit(const RxConfig &config)
void xmrig::Rx::msrInit(const RxConfig &config)
{
if (config.wrmsr() < 0) {
const auto &preset = config.msrPreset();
if (preset.empty()) {
return;
}
if (Cpu::info()->assembly() == Assembly::RYZEN && wrmsr_modprobe()) {
wrmsr_on_all_cpus(0xC0011022, 0x510000);
wrmsr_on_all_cpus(0xC001102b, 0x1808cc16);
wrmsr_on_all_cpus(0xC0011020, 0);
wrmsr_on_all_cpus(0xC0011021, 0x40);
const uint64_t ts = Chrono::steadyMSecs();
return;
}
if (Cpu::info()->vendor() == ICpuInfo::VENDOR_INTEL && wrmsr_modprobe()) {
wrmsr_on_all_cpus(0x1a4, config.wrmsr());
if (wrmsr(preset, 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);
}
}
void xmrig::Rx::msrDestroy()
{
if (savedState.empty()) {
return;
}
const uint64_t ts = Chrono::steadyMSecs();
if (!wrmsr(savedState, 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()
{
struct sigaction act = {};
act.sa_sigaction = MainLoopHandler;
act.sa_flags = SA_RESTART | SA_SIGINFO;
sigaction(SIGSEGV, &act, nullptr);
sigaction(SIGILL, &act, nullptr);
}

372
src/crypto/rx/Rx_win.cpp Normal file
View File

@@ -0,0 +1,372 @@
/* 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 2000 Transmeta Corporation <https://github.com/intel/msr-tools>
* Copyright 2004-2008 H. Peter Anvin <https://github.com/intel/msr-tools>
* Copyright 2007-2009 hiyohiyo <https://openlibsys.org>, <hiyohiyo@crystalmark.info>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 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 "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(); 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 && Log::isVerbose()) {
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 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 = (value & mask) | (old_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, 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(), i.value());
if (item.isValid()) {
savedState.emplace_back(item);
}
}
}
std::thread wrmsr_thread([driver, &preset, &success]() {
for (uint32_t i = 0, n = Cpu::info()->threads(); i < n; ++i) {
if (!Platform::setThreadAffinity(i)) {
continue;
}
for (const auto &i : preset) {
success = wrmsr(driver, i.reg(), i.value(), i.mask());
}
if (!success) {
break;
}
}
});
wrmsr_thread.join();
CloseHandle(driver);
wrmsr_uninstall_driver();
CloseServiceHandle(hManager);
return success;
}
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 = Rx::mainLoopBounds();
if ((loopBounds.first <= p) && (p < loopBounds.second)) {
ExceptionInfo->ContextRecord->Rip = reinterpret_cast<DWORD64>(loopBounds.second);
return EXCEPTION_CONTINUE_EXECUTION;
}
return EXCEPTION_CONTINUE_SEARCH;
}
thread_local std::pair<const void*, const void*> Rx::m_mainLoopBounds = { nullptr, nullptr };
} // namespace xmrig
void xmrig::Rx::msrInit(const RxConfig &config)
{
const auto &preset = config.msrPreset();
if (preset.empty()) {
return;
}
const uint64_t ts = Chrono::steadyMSecs();
if (wrmsr(preset, 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);
}
}
void xmrig::Rx::msrDestroy()
{
if (savedState.empty()) {
return;
}
const uint64_t ts = Chrono::steadyMSecs();
if (!wrmsr(savedState, 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()
{
AddVectoredExceptionHandler(1, MainLoopHandler);
}

View File

@@ -0,0 +1,72 @@
/* 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-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 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/msr/MsrItem.h"
#include "rapidjson/document.h"
#include <cstdio>
xmrig::MsrItem::MsrItem(const rapidjson::Value &value)
{
if (!value.IsString()) {
return;
}
auto kv = String(value.GetString()).split(':');
if (kv.size() < 2) {
return;
}
m_reg = strtoul(kv[0], nullptr, 0);
m_value = strtoull(kv[1], nullptr, 0);
m_mask = (kv.size() > 2) ? strtoull(kv[2], nullptr, 0) : kNoMask;
}
rapidjson::Value xmrig::MsrItem::toJSON(rapidjson::Document &doc) const
{
return toString().toJSON(doc);
}
xmrig::String xmrig::MsrItem::toString() const
{
constexpr size_t size = 48;
auto buf = new char[size]();
if (m_mask != kNoMask) {
snprintf(buf, size, "0x%" PRIx32 ":0x%" PRIx64 ":0x%" PRIx64, m_reg, m_value, m_mask);
}
else {
snprintf(buf, size, "0x%" PRIx32 ":0x%" PRIx64, m_reg, m_value);
}
return buf;
}

View File

@@ -0,0 +1,76 @@
/* 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-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 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_MSRITEM_H
#define XMRIG_MSRITEM_H
#include "base/tools/String.h"
#include <limits>
#include <vector>
namespace xmrig
{
class RxDataset;
class MsrItem
{
public:
constexpr static uint64_t kNoMask = std::numeric_limits<uint64_t>::max();
inline MsrItem() = default;
inline MsrItem(uint32_t reg, uint64_t value, uint64_t mask = kNoMask) : m_reg(reg), m_value(value), m_mask(mask) {}
MsrItem(const rapidjson::Value &value);
inline bool isValid() const { return m_reg > 0; }
inline uint32_t reg() const { return m_reg; }
inline uint64_t value() const { return m_value; }
inline uint64_t mask() const { return m_mask; }
rapidjson::Value toJSON(rapidjson::Document &doc) const;
String toString() const;
private:
uint32_t m_reg = 0;
uint64_t m_value = 0;
uint64_t m_mask = kNoMask;
};
using MsrItems = std::vector<MsrItem>;
} /* namespace xmrig */
#endif /* XMRIG_MSRITEM_H */

View File

@@ -28,15 +28,15 @@
#define APP_ID "xmrig"
#define APP_NAME "XMRig"
#define APP_DESC "XMRig miner"
#define APP_VERSION "5.2.1"
#define APP_VERSION "5.5.0"
#define APP_DOMAIN "xmrig.com"
#define APP_SITE "www.xmrig.com"
#define APP_COPYRIGHT "Copyright (C) 2016-2019 xmrig.com"
#define APP_KIND "miner"
#define APP_VER_MAJOR 5
#define APP_VER_MINOR 2
#define APP_VER_PATCH 1
#define APP_VER_MINOR 5
#define APP_VER_PATCH 0
#ifdef _MSC_VER
# if (_MSC_VER >= 1920)