xmrig/src/Mem_win.cpp

205 lines
5.5 KiB
C++
Raw Normal View History

2017-04-15 06:02:08 +00:00
/* 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>
2018-03-06 14:34:20 +00:00
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
2019-01-14 19:15:36 +00:00
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
2017-04-15 06:02:08 +00:00
*
* 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/>.
*/
2017-04-21 08:56:11 +00:00
2017-04-15 06:02:08 +00:00
2017-06-09 12:09:21 +00:00
#include <winsock2.h>
2017-04-15 06:02:08 +00:00
#include <windows.h>
#include <ntsecapi.h>
#include <tchar.h>
2017-04-15 06:02:08 +00:00
2019-03-26 18:29:37 +00:00
#include "base/io/log/Log.h"
2018-04-15 04:08:47 +00:00
#include "common/utils/mm_malloc.h"
2018-04-13 00:00:51 +00:00
#include "common/xmrig.h"
2017-06-09 21:43:23 +00:00
#include "crypto/CryptoNight.h"
2018-04-15 04:08:47 +00:00
#include "crypto/CryptoNight_constants.h"
2017-06-09 21:43:23 +00:00
#include "Mem.h"
2017-04-15 06:02:08 +00:00
/*****************************************************************
SetLockPagesPrivilege: a function to obtain or
release the privilege of locking physical pages.
Inputs:
HANDLE hProcess: Handle for the process for which the
privilege is needed
BOOL bEnable: Enable (TRUE) or disable?
Return value: TRUE indicates success, FALSE failure.
*****************************************************************/
/**
* AWE Example: https://msdn.microsoft.com/en-us/library/windows/desktop/aa366531(v=vs.85).aspx
* Creating a File Mapping Using Large Pages: https://msdn.microsoft.com/en-us/library/aa366543(VS.85).aspx
*/
2017-05-04 11:18:14 +00:00
static BOOL SetLockPagesPrivilege() {
HANDLE token;
2017-04-15 06:02:08 +00:00
2017-05-04 11:18:14 +00:00
if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token) != TRUE) {
2017-04-15 06:02:08 +00:00
return FALSE;
}
2017-05-04 11:18:14 +00:00
TOKEN_PRIVILEGES tp;
tp.PrivilegeCount = 1;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
2017-04-15 06:02:08 +00:00
2019-03-26 18:29:37 +00:00
if (LookupPrivilegeValue(nullptr, SE_LOCK_MEMORY_NAME, &(tp.Privileges[0].Luid)) != TRUE) {
2017-04-15 06:02:08 +00:00
return FALSE;
}
2019-03-26 18:29:37 +00:00
BOOL rc = AdjustTokenPrivileges(token, FALSE, (PTOKEN_PRIVILEGES) &tp, 0, nullptr, nullptr);
2017-05-04 11:18:14 +00:00
if (rc != TRUE || GetLastError() != ERROR_SUCCESS) {
2017-04-15 06:02:08 +00:00
return FALSE;
}
2017-05-04 11:18:14 +00:00
CloseHandle(token);
2017-04-15 06:02:08 +00:00
return TRUE;
}
static LSA_UNICODE_STRING StringToLsaUnicodeString(LPCTSTR string) {
LSA_UNICODE_STRING lsaString;
2017-08-14 06:30:41 +00:00
DWORD dwLen = (DWORD) wcslen(string);
lsaString.Buffer = (LPWSTR) string;
lsaString.Length = (USHORT)((dwLen) * sizeof(WCHAR));
lsaString.MaximumLength = (USHORT)((dwLen + 1) * sizeof(WCHAR));
return lsaString;
}
static BOOL ObtainLockPagesPrivilege() {
HANDLE token;
2019-03-26 18:29:37 +00:00
PTOKEN_USER user = nullptr;
if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token) == TRUE) {
DWORD size = 0;
2019-03-26 18:29:37 +00:00
GetTokenInformation(token, TokenUser, nullptr, 0, &size);
if (size) {
user = (PTOKEN_USER) LocalAlloc(LPTR, size);
}
GetTokenInformation(token, TokenUser, user, size, &size);
CloseHandle(token);
}
if (!user) {
return FALSE;
}
LSA_HANDLE handle;
LSA_OBJECT_ATTRIBUTES attributes;
ZeroMemory(&attributes, sizeof(attributes));
BOOL result = FALSE;
2019-03-26 18:29:37 +00:00
if (LsaOpenPolicy(nullptr, &attributes, POLICY_ALL_ACCESS, &handle) == 0) {
LSA_UNICODE_STRING str = StringToLsaUnicodeString(_T(SE_LOCK_MEMORY_NAME));
if (LsaAddAccountRights(handle, user->User.Sid, &str, 1) == 0) {
LOG_NOTICE("Huge pages support was successfully enabled, but reboot required to use it");
result = TRUE;
}
LsaClose(handle);
}
LocalFree(user);
return result;
}
static BOOL TrySetLockPagesPrivilege() {
if (SetLockPagesPrivilege()) {
return TRUE;
}
return ObtainLockPagesPrivilege() && SetLockPagesPrivilege();
}
2018-04-15 04:08:47 +00:00
void Mem::init(bool enabled)
2017-06-09 12:09:21 +00:00
{
2018-04-15 04:08:47 +00:00
m_enabled = enabled;
2018-04-15 04:08:47 +00:00
if (enabled && TrySetLockPagesPrivilege()) {
m_flags |= HugepagesAvailable;
}
2018-04-15 04:08:47 +00:00
}
void Mem::allocate(MemInfo &info, bool enabled)
{
info.hugePages = 0;
2017-08-16 11:21:12 +00:00
if (!enabled) {
2018-04-15 05:58:17 +00:00
info.memory = static_cast<uint8_t*>(_mm_malloc(info.size, 4096));
2017-08-16 11:21:12 +00:00
2018-04-15 04:08:47 +00:00
return;
2017-04-15 06:02:08 +00:00
}
2018-04-15 04:08:47 +00:00
info.memory = static_cast<uint8_t*>(VirtualAlloc(nullptr, info.size, MEM_COMMIT | MEM_RESERVE | MEM_LARGE_PAGES, PAGE_READWRITE));
if (info.memory) {
info.hugePages = info.pages;
return;
2017-04-15 06:02:08 +00:00
}
2018-04-15 04:08:47 +00:00
allocate(info, false);
2017-04-15 06:02:08 +00:00
}
2018-04-15 04:08:47 +00:00
void Mem::release(MemInfo &info)
2017-06-09 12:09:21 +00:00
{
2018-04-15 04:08:47 +00:00
if (info.hugePages) {
VirtualFree(info.memory, 0, MEM_RELEASE);
2017-04-15 06:02:08 +00:00
}
else {
2018-04-15 04:08:47 +00:00
_mm_free(info.memory);
2017-04-15 06:02:08 +00:00
}
}
2019-01-14 19:15:36 +00:00
void *Mem::allocateExecutableMemory(size_t size)
{
2019-03-26 18:29:37 +00:00
return VirtualAlloc(nullptr, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
}
void Mem::protectExecutableMemory(void *p, size_t size)
{
DWORD oldProtect;
VirtualProtect(p, size, PAGE_EXECUTE_READ, &oldProtect);
}
2019-01-14 19:15:36 +00:00
void Mem::flushInstructionCache(void *p, size_t size)
{
::FlushInstructionCache(GetCurrentProcess(), p, size);
}