diff --git a/src/base/io/log/Log.h b/src/base/io/log/Log.h index cfd3c3a3..c7e0c3f4 100644 --- a/src/base/io/log/Log.h +++ b/src/base/io/log/Log.h @@ -83,6 +83,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 +110,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 diff --git a/src/crypto/rx/Rx_linux.cpp b/src/crypto/rx/Rx_linux.cpp index 782467a7..98d343f4 100644 --- a/src/crypto/rx/Rx_linux.cpp +++ b/src/crypto/rx/Rx_linux.cpp @@ -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 #include #include #include @@ -47,6 +48,18 @@ namespace xmrig { +enum MsrMod : uint32_t { + MSR_MOD_NONE, + MSR_MOD_RYZEN, + MSR_MOD_INTEL, + MSR_MOD_MAX +}; + + +static const char *tag = YELLOW_BG_BOLD(WHITE_BOLD_S " msr ") " "; +static const std::array modNames = { nullptr, "Ryzen", "Intel" }; + + static inline int dir_filter(const struct dirent *dirp) { return isdigit(dirp->d_name[0]) ? 1 : 0; @@ -88,7 +101,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 +111,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; } @@ -116,16 +129,33 @@ void xmrig::Rx::osInit(const RxConfig &config) 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); + MsrMod mod = MSR_MOD_NONE; + if (Cpu::info()->assembly() == Assembly::RYZEN) { + mod = MSR_MOD_RYZEN; + } + else if (Cpu::info()->vendor() == ICpuInfo::VENDOR_INTEL) { + mod = MSR_MOD_INTEL; + } + if (mod == MSR_MOD_NONE) { return; } - if (Cpu::info()->vendor() == ICpuInfo::VENDOR_INTEL && wrmsr_modprobe()) { + const uint64_t ts = Chrono::steadyMSecs(); + + if (!wrmsr_modprobe()) { + return; + } + + if (mod == MSR_MOD_RYZEN) { + wrmsr_on_all_cpus(0xC0011020, 0); + wrmsr_on_all_cpus(0xC0011021, 0x40); + wrmsr_on_all_cpus(0xC0011022, 0x510000); + wrmsr_on_all_cpus(0xC001102b, 0x1808cc16); + } + else if (mod == MSR_MOD_INTEL) { wrmsr_on_all_cpus(0x1a4, config.wrmsr()); } + + LOG_NOTICE(CLEAR "%s" GREEN_BOLD_S "register values for %s has been set successfully" BLACK_BOLD(" (%" PRIu64 " ms)"), tag, modNames[mod], Chrono::steadyMSecs() - ts); } diff --git a/src/crypto/rx/Rx_windows.cpp b/src/crypto/rx/Rx_windows.cpp index a98a4334..f592cd03 100644 --- a/src/crypto/rx/Rx_windows.cpp +++ b/src/crypto/rx/Rx_windows.cpp @@ -7,9 +7,10 @@ * Copyright 2017-2019 XMR-Stak , * Copyright 2018 Lee Clagett * Copyright 2018-2019 tevador - * Copyright 2018-2019 SChernykh * Copyright 2000 Transmeta Corporation * Copyright 2004-2008 H. Peter Anvin + * Copyright 2007-2009 hiyohiyo , + * Copyright 2018-2019 SChernykh * Copyright 2016-2019 XMRig , * * This program is free software: you can redistribute it and/or modify @@ -28,61 +29,96 @@ #include "crypto/rx/Rx.h" -#include "backend/common/Tags.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 +#include #include #include + #define SERVICE_NAME L"WinRing0_1_2_0" + +namespace xmrig { + + +enum MsrMod : uint32_t { + MSR_MOD_NONE, + MSR_MOD_RYZEN, + MSR_MOD_INTEL, + MSR_MOD_MAX +}; + + +static const char *tag = YELLOW_BG_BOLD(WHITE_BOLD_S " msr ") " "; +static const std::array modNames = { nullptr, "Ryzen", "Intel" }; + + static SC_HANDLE hManager; static SC_HANDLE hService; -static bool uninstall_driver() + +static bool wrmsr_uninstall_driver() { + if (!hService) { + return true; + } + bool result = true; - DWORD err; SERVICE_STATUS serviceStatus; + if (!ControlService(hService, SERVICE_CONTROL_STOP, &serviceStatus)) { - err = GetLastError(); - LOG_ERR("Failed to stop WinRing0 driver, error %u", err); + LOG_ERR(CLEAR "%s" RED_S "failed to stop WinRing0 driver, error %u", tag, GetLastError()); result = false; } + if (!DeleteService(hService)) { - err = GetLastError(); - LOG_ERR("Failed to remove WinRing0 driver, error %u", err); + 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 install_driver() + +static HANDLE wrmsr_install_driver() { DWORD err = 0; hManager = OpenSCManager(nullptr, nullptr, SC_MANAGER_ALL_ACCESS); if (!hManager) { err = GetLastError(); - LOG_ERR("Failed to open service control manager, error %u", err); - return 0; + + 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 dir; dir.resize(MAX_PATH); do { dir.resize(dir.size() * 2); - DWORD len = GetModuleFileNameW(NULL, dir.data(), dir.size()); + GetModuleFileNameW(nullptr, dir.data(), dir.size()); err = GetLastError(); } while (err == ERROR_INSUFFICIENT_BUFFER); if (err != ERROR_SUCCESS) { - LOG_ERR("Failed to get path to driver, error %u", err); - return 0; + LOG_ERR(CLEAR "%s" RED_S "failed to get path to driver, error %u", err); + return nullptr; } for (auto it = dir.end(); it != dir.begin(); --it) { @@ -97,39 +133,41 @@ static HANDLE install_driver() driverPath += L"WinRing0x64.sys"; hService = OpenServiceW(hManager, SERVICE_NAME, SERVICE_ALL_ACCESS); - if (hService) { - if (!uninstall_driver()) { - return 0; - } - CloseServiceHandle(hService); - hService = 0; + if (hService && !wrmsr_uninstall_driver()) { + return nullptr; } - else { - err = GetLastError(); - if (err != ERROR_SERVICE_DOES_NOT_EXIST) { - LOG_ERR("Failed to open WinRing0 driver, error %u", err); - return 0; - } + + err = GetLastError(); + if (err != ERROR_SERVICE_DOES_NOT_EXIST) { + LOG_ERR(CLEAR "%s" RED_S "failed to open WinRing0 driver, error %u", tag, err); + + return nullptr; } 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("Failed to install WinRing0 driver, error %u", err); + 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) { - LOG_ERR("Failed to start WinRing0 driver, error %u", err); - return 0; + LOG_ERR(CLEAR "%s" RED_S "failed to start WinRing0 driver, error %u", tag, err); + + CloseServiceHandle(hService); + hService = nullptr; + + return nullptr; } } HANDLE hDriver = CreateFileW(L"\\\\.\\" SERVICE_NAME, GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); if (!hDriver) { - err = GetLastError(); - LOG_ERR("Failed to connect to WinRing0 driver, error %u", err); - return 0; + LOG_ERR(CLEAR "%s" RED_S "failed to connect to WinRing0 driver, error %u", tag, GetLastError()); + + return nullptr; } return hDriver; @@ -138,11 +176,13 @@ static HANDLE install_driver() #define IOCTL_WRITE_MSR CTL_CODE(40000, 0x822, METHOD_BUFFERED, FILE_ANY_ACCESS) + static bool wrmsr(HANDLE hDriver, uint32_t reg, uint64_t value) { struct { - uint32_t reg; - uint32_t value[2]; + uint32_t reg = 0; + uint32_t value[2]{}; } input; + static_assert(sizeof(input) == 12, "Invalid struct size for WinRing0 driver"); input.reg = reg; @@ -150,9 +190,10 @@ static bool wrmsr(HANDLE hDriver, uint32_t reg, uint64_t value) { DWORD output; DWORD k; + if (!DeviceIoControl(hDriver, IOCTL_WRITE_MSR, &input, sizeof(input), &output, sizeof(output), &k, nullptr)) { - const DWORD err = GetLastError(); - LOG_WARN(CLEAR "%s" YELLOW_BOLD_S "cannot set MSR 0x%08" PRIx32 " to 0x%08" PRIx64, xmrig::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 false; } @@ -160,57 +201,62 @@ static bool wrmsr(HANDLE hDriver, uint32_t reg, uint64_t value) { } +} // namespace xmrig + + void xmrig::Rx::osInit(const RxConfig &config) { if ((config.wrmsr() < 0) || !ICpuInfo::isX64()) { return; } - const char* msr_mod_variant = (Cpu::info()->assembly() == Assembly::RYZEN) ? "Ryzen" : - ((Cpu::info()->vendor() == ICpuInfo::VENDOR_INTEL) ? "Intel" : nullptr); + MsrMod mod = MSR_MOD_NONE; + if (Cpu::info()->assembly() == Assembly::RYZEN) { + mod = MSR_MOD_RYZEN; + } + else if (Cpu::info()->vendor() == ICpuInfo::VENDOR_INTEL) { + mod = MSR_MOD_INTEL; + } - if (!msr_mod_variant) { + if (mod == MSR_MOD_NONE) { return; } - LOG_INFO(CLEAR "%s" GREEN_BOLD_S "MSR mod: loading WinRing0 driver", xmrig::rx_tag()); + const uint64_t ts = Chrono::steadyMSecs(); - HANDLE hDriver = install_driver(); + HANDLE hDriver = wrmsr_install_driver(); if (!hDriver) { - if (hService) { - uninstall_driver(); - CloseServiceHandle(hService); - } + wrmsr_uninstall_driver(); + if (hManager) { CloseServiceHandle(hManager); } + return; } - LOG_INFO(CLEAR "%s" GREEN_BOLD_S "MSR mod: setting MSR register values for %s", xmrig::rx_tag(), msr_mod_variant); - - std::thread wrmsr_thread([hDriver, &config]() { + std::thread wrmsr_thread([hDriver, mod, &config]() { for (uint32_t i = 0, n = Cpu::info()->threads(); i < n; ++i) { Platform::setThreadAffinity(i); - if (Cpu::info()->assembly() == Assembly::RYZEN) { + + if (mod == MSR_MOD_RYZEN) { wrmsr(hDriver, 0xC0011020, 0); wrmsr(hDriver, 0xC0011021, 0x40); wrmsr(hDriver, 0xC0011022, 0x510000); wrmsr(hDriver, 0xC001102b, 0x1808cc16); } - else if (Cpu::info()->vendor() == ICpuInfo::VENDOR_INTEL) { + else if (mod == MSR_MOD_INTEL) { wrmsr(hDriver, 0x1a4, config.wrmsr()); } } }); + wrmsr_thread.join(); CloseHandle(hDriver); - uninstall_driver(); - - CloseServiceHandle(hService); + wrmsr_uninstall_driver(); CloseServiceHandle(hManager); - LOG_INFO(CLEAR "%s" GREEN_BOLD_S "MSR mod: all done, WinRing0 driver unloaded", xmrig::rx_tag()); + LOG_NOTICE(CLEAR "%s" GREEN_BOLD_S "register values for %s has been set successfully" BLACK_BOLD(" (%" PRIu64 " ms)"), tag, modNames[mod], Chrono::steadyMSecs() - ts); }