diff --git a/src/crypto/rx/Rx_linux.cpp b/src/crypto/rx/Rx_linux.cpp index ad33b171..23d9d51f 100644 --- a/src/crypto/rx/Rx_linux.cpp +++ b/src/crypto/rx/Rx_linux.cpp @@ -48,16 +48,8 @@ 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 const char *tag = YELLOW_BG_BOLD(WHITE_BOLD_S " msr ") " "; +static MsrItems savedState; static inline int dir_filter(const struct dirent *dirp) @@ -108,6 +100,37 @@ static bool wrmsr_on_all_cpus(uint32_t reg, 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_modprobe() { if (system("/sbin/modprobe msr > /dev/null 2>&1") != 0) { @@ -120,12 +143,21 @@ static bool wrmsr_modprobe() } -static bool wrmsr(const MsrItems &preset) +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()); + if (item.isValid()) { + savedState.emplace_back(item); + } + } + } + for (const auto &i : preset) { if (!wrmsr_on_all_cpus(i.reg(), i.value())) { return false; @@ -148,46 +180,21 @@ void xmrig::Rx::msrInit(const RxConfig &config) const uint64_t ts = Chrono::steadyMSecs(); - if (wrmsr(preset)) { + 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); } - -// if (config.wrmsr() < 0) { -// return; -// } - -// 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; -// } - -// 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); } 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); + } } diff --git a/src/crypto/rx/Rx_win.cpp b/src/crypto/rx/Rx_win.cpp index ef565756..30b76ae3 100644 --- a/src/crypto/rx/Rx_win.cpp +++ b/src/crypto/rx/Rx_win.cpp @@ -211,13 +211,7 @@ static bool rdmsr(HANDLE driver, uint32_t reg, uint64_t &value) { DWORD size = 0; - if (!DeviceIoControl(driver, IOCTL_READ_MSR, ®, sizeof(reg), &value, sizeof(value), &size, nullptr)) { - LOG_WARN(CLEAR "%s" YELLOW_BOLD_S "cannot read MSR 0x%08" PRIx32, tag, reg); - - return false; - } - - return true; + return DeviceIoControl(driver, IOCTL_READ_MSR, ®, sizeof(reg), &value, sizeof(value), &size, nullptr) != 0; } @@ -225,6 +219,8 @@ 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 {}; }