Added RxMsr class.

This commit is contained in:
XMRig 2021-01-23 23:23:39 +07:00
parent b9d813c403
commit 9dae559b73
No known key found for this signature in database
GPG key ID: 446A53638BE94409
17 changed files with 435 additions and 746 deletions

View file

@ -55,6 +55,24 @@ std::shared_ptr<xmrig::Msr> xmrig::Msr::get()
}
bool xmrig::Msr::write(uint32_t reg, uint64_t value, int32_t cpu, uint64_t mask, bool verbose)
{
if (mask != MsrItem::kNoMask) {
uint64_t old_value;
if (rdmsr(reg, cpu, old_value)) {
value = MsrItem::maskedValue(old_value, value, mask);
}
}
const bool result = wrmsr(reg, value, cpu);
if (!result && verbose) {
LOG_WARN("%s " YELLOW_BOLD("cannot set MSR 0x%08" PRIx32 " to 0x%016" PRIx64), tag(), reg, value);
}
return result;
}
xmrig::MsrItem xmrig::Msr::read(uint32_t reg, int32_t cpu, bool verbose) const
{
uint64_t value = 0;

View file

@ -24,6 +24,7 @@
#include "hw/msr/MsrItem.h"
#include <functional>
#include <memory>
@ -39,17 +40,24 @@ class Msr
public:
XMRIG_DISABLE_COPY_MOVE(Msr)
using Callback = std::function<bool(int32_t cpu)>;
Msr();
~Msr();
static const char *tag();
static std::shared_ptr<Msr> get();
inline bool write(const MsrItem &item, int32_t cpu = -1, bool verbose = true) { return write(item.reg(), item.value(), cpu, item.mask(), verbose); }
bool isAvailable() const;
bool write(uint32_t reg, uint64_t value, int32_t cpu = -1, uint64_t mask = MsrItem::kNoMask, bool verbose = true);
bool write(Callback &&callback);
MsrItem read(uint32_t reg, int32_t cpu = -1, bool verbose = true) const;
private:
bool rdmsr(uint32_t reg, int32_t cpu, uint64_t &value) const;
bool wrmsr(uint32_t reg, uint64_t value, int32_t cpu);
MsrPrivate *d_ptr = nullptr;
};

View file

@ -46,6 +46,11 @@ public:
inline uint64_t value() const { return m_value; }
inline uint64_t mask() const { return m_mask; }
static inline uint64_t maskedValue(uint64_t old_value, uint64_t new_value, uint64_t mask)
{
return (new_value & mask) | (old_value & ~mask);
}
rapidjson::Value toJSON(rapidjson::Document &doc) const;
String toString() const;

View file

@ -19,6 +19,7 @@
#include "hw/msr/Msr.h"
#include "3rdparty/fmt/core.h"
#include "backend/cpu/Cpu.h"
#include "base/io/log/Log.h"
@ -31,8 +32,6 @@
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <ucontext.h>
namespace xmrig {
@ -70,6 +69,20 @@ bool xmrig::Msr::isAvailable() const
}
bool xmrig::Msr::write(Callback &&callback)
{
const auto &units = Cpu::info()->units();
for (int32_t pu : units) {
if (!callback(pu)) {
return false;
}
}
return true;
}
bool xmrig::Msr::rdmsr(uint32_t reg, int32_t cpu, uint64_t &value) const
{
const auto name = fmt::format("/dev/cpu/{}/msr", cpu < 0 ? 0 : cpu);
@ -84,3 +97,20 @@ bool xmrig::Msr::rdmsr(uint32_t reg, int32_t cpu, uint64_t &value) const
return success;
}
bool xmrig::Msr::wrmsr(uint32_t reg, uint64_t value, int32_t cpu)
{
const auto name = fmt::format("/dev/cpu/{}/msr", cpu < 0 ? 0 : cpu);
int fd = open(name.c_str(), O_WRONLY);
if (fd < 0) {
return false;
}
const bool success = pwrite(fd, &value, sizeof value, reg) == sizeof value;
close(fd);
return success;
}

View file

@ -18,10 +18,13 @@
#include "hw/msr/Msr.h"
#include "backend/cpu/Cpu.h"
#include "base/io/log/Log.h"
#include "base/kernel/Platform.h"
#include <string>
#include <thread>
#include <vector>
#include <windows.h>
@ -196,9 +199,57 @@ bool xmrig::Msr::isAvailable() const
}
bool xmrig::Msr::rdmsr(uint32_t reg, int32_t, uint64_t &value) const
bool xmrig::Msr::write(Callback &&callback)
{
const auto &units = Cpu::info()->units();
bool success = false;
std::thread thread([&callback, &units, &success]() {
for (int32_t pu : units) {
if (!Platform::setThreadAffinity(pu)) {
continue;
}
if (!callback(pu)) {
return;
}
}
success = true;
});
thread.join();
return success;
}
bool xmrig::Msr::rdmsr(uint32_t reg, int32_t cpu, uint64_t &value) const
{
assert(cpu < 0);
DWORD size = 0;
return DeviceIoControl(d_ptr->driver, IOCTL_READ_MSR, &reg, sizeof(reg), &value, sizeof(value), &size, nullptr) != 0;
}
bool xmrig::Msr::wrmsr(uint32_t reg, uint64_t value, int32_t cpu)
{
assert(cpu < 0);
struct {
uint32_t reg = 0;
uint32_t value[2]{};
} input;
static_assert(sizeof(input) == 12, "Invalid struct size for WinRing0 driver");
input.reg = reg;
*(reinterpret_cast<uint64_t*>(input.value)) = value;
DWORD output;
DWORD k;
return DeviceIoControl(d_ptr->driver, IOCTL_WRITE_MSR, &input, sizeof(input), &output, sizeof(output), &k, nullptr) != 0;
}