1e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima/* 2e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima** Copyright (c) 2011, Intel Corporation 3e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima** 4e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima** This software is licensed under the terms of the GNU General Public 5e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima** License version 2, as published by the Free Software Foundation, and 6e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima** may be copied, distributed, and modified under those terms. 7e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima** 8e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima** This program is distributed in the hope that it will be useful, 9e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima** but WITHOUT ANY WARRANTY; without even the implied warranty of 10e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima** GNU General Public License for more details. 12e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima*/ 13e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 14e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima#include "target-i386/hax-i386.h" 15e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 16e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima/* 17e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima * return 0 upon success, -1 when the driver is not loaded, 18e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima * other negative value for other failures 19e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima */ 20e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajimastatic int hax_open_device(hax_fd *fd) 21e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima{ 22e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima uint32_t errNum = 0; 23e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima HANDLE hDevice; 24e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 25e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima if (!fd) 26e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima return -2; 27e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 28e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima hDevice = CreateFile( "\\\\.\\HAX", 29e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima GENERIC_READ | GENERIC_WRITE, 30e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 0, 31e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima NULL, 32e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima CREATE_ALWAYS, 33e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima FILE_ATTRIBUTE_NORMAL, 34e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima NULL); 35e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 36e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima if (hDevice == INVALID_HANDLE_VALUE) 37e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima { 38e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima dprint("Failed to open the HAX device!\n"); 39e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima errNum = GetLastError(); 40e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima if (errNum == ERROR_FILE_NOT_FOUND) 41e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima return -1; 42e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima return -2; 43e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima } 44e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima *fd = hDevice; 45e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima dprint("device fd:%d\n", *fd); 46e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima return 0; 47e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima} 48e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 49e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 50e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajimahax_fd hax_mod_open(void) 51e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima{ 52e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima int ret; 53a2c14f947951612b45024095afd2210aa7368773David 'Digit' Turner hax_fd fd = INVALID_HANDLE_VALUE; 54e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 55e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima ret = hax_open_device(&fd); 56a2c14f947951612b45024095afd2210aa7368773David 'Digit' Turner if (ret != 0) { 57e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima dprint("Open HAX device failed\n"); 58a2c14f947951612b45024095afd2210aa7368773David 'Digit' Turner return INVALID_HANDLE_VALUE; 59a2c14f947951612b45024095afd2210aa7368773David 'Digit' Turner } 60e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 61e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima return fd; 62e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima} 63e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 64e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajimaint hax_populate_ram(uint64_t va, uint32_t size) 65e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima{ 66e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima int ret; 67e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima struct hax_alloc_ram_info info; 68e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima HANDLE hDeviceVM; 69e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima DWORD dSize = 0; 70e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 71e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima if (!hax_global.vm || !hax_global.vm->fd) 72e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima { 73e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima dprint("Allocate memory before vm create?\n"); 74e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima return -EINVAL; 75e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima } 76e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 77e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima info.size = size; 78e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima info.va = va; 79e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 80e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima hDeviceVM = hax_global.vm->fd; 81e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 82e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima ret = DeviceIoControl(hDeviceVM, 83e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima HAX_VM_IOCTL_ALLOC_RAM, 84e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima &info, sizeof(info), 85e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima NULL, 0, 86e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima &dSize, 87e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima (LPOVERLAPPED) NULL); 88e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 89e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima if (!ret) { 90f2de2ae9ce153cea6119b05e640dbf35db3b519aDavid 'Digit' Turner dprint("HAX: Failed to allocate %x memory (address %llx)\n", 91f2de2ae9ce153cea6119b05e640dbf35db3b519aDavid 'Digit' Turner size, (unsigned long long)va); 92f2de2ae9ce153cea6119b05e640dbf35db3b519aDavid 'Digit' Turner return -1; 93e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima } 94e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 95e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima return 0; 96e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima} 97e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 98e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 99bcde1092aca184dbd7860078af020de7d1e4e22fDavid 'Digit' Turnerint hax_set_phys_mem(hwaddr start_addr, ram_addr_t size, ram_addr_t phys_offset) 100e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima{ 101e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima struct hax_set_ram_info info, *pinfo = &info; 102e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima ram_addr_t flags = phys_offset & ~TARGET_PAGE_MASK; 103e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima HANDLE hDeviceVM; 104e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima DWORD dSize = 0; 105e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima int ret = 0; 106e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 107e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima /* We look for the RAM and ROM only */ 108e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima if (flags >= IO_MEM_UNASSIGNED) 109e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima return 0; 110e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 111e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima if ( (start_addr & ~TARGET_PAGE_MASK) || (size & ~TARGET_PAGE_MASK)) 112e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima { 113e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima dprint( 114e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima "set_phys_mem %x %lx requires page aligned addr and size\n", 115e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima start_addr, size); 116e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima return -1; 117e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima } 118e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 119e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima info.pa_start = start_addr; 120e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima info.size = size; 121a2c14f947951612b45024095afd2210aa7368773David 'Digit' Turner info.va = (uint64_t)(uintptr_t)qemu_get_ram_ptr(phys_offset); 122e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima info.flags = (flags & IO_MEM_ROM) ? 1 : 0; 123e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 124e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima hDeviceVM = hax_global.vm->fd; 125e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 126e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima ret = DeviceIoControl(hDeviceVM, 127e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima HAX_VM_IOCTL_SET_RAM, 128e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima pinfo, sizeof(*pinfo), 129e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima NULL, 0, 130e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima &dSize, 131e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima (LPOVERLAPPED) NULL); 132e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 133e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima if (!ret) 134e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima return -EFAULT; 135e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima else 136e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima return 0; 137e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima} 138e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 1394a5a0efd49f100c7d53920807c83d9c74304ecd8Jiang, Yunhongint hax_capability(struct hax_state *hax, struct hax_capabilityinfo *cap) 1404a5a0efd49f100c7d53920807c83d9c74304ecd8Jiang, Yunhong{ 1414a5a0efd49f100c7d53920807c83d9c74304ecd8Jiang, Yunhong int ret; 1424a5a0efd49f100c7d53920807c83d9c74304ecd8Jiang, Yunhong HANDLE hDevice = hax->fd; //handle to hax module 1434a5a0efd49f100c7d53920807c83d9c74304ecd8Jiang, Yunhong DWORD dSize = 0; 1444a5a0efd49f100c7d53920807c83d9c74304ecd8Jiang, Yunhong DWORD err = 0; 1454a5a0efd49f100c7d53920807c83d9c74304ecd8Jiang, Yunhong 1464a5a0efd49f100c7d53920807c83d9c74304ecd8Jiang, Yunhong if (hax_invalid_fd(hDevice)) { 1474a5a0efd49f100c7d53920807c83d9c74304ecd8Jiang, Yunhong dprint("Invalid fd for hax device!\n"); 1484a5a0efd49f100c7d53920807c83d9c74304ecd8Jiang, Yunhong return -ENODEV; 1494a5a0efd49f100c7d53920807c83d9c74304ecd8Jiang, Yunhong } 1504a5a0efd49f100c7d53920807c83d9c74304ecd8Jiang, Yunhong 1514a5a0efd49f100c7d53920807c83d9c74304ecd8Jiang, Yunhong ret = DeviceIoControl(hDevice, 1524a5a0efd49f100c7d53920807c83d9c74304ecd8Jiang, Yunhong HAX_IOCTL_CAPABILITY, 1534a5a0efd49f100c7d53920807c83d9c74304ecd8Jiang, Yunhong NULL, 0, 1544a5a0efd49f100c7d53920807c83d9c74304ecd8Jiang, Yunhong cap, sizeof(*cap), 1554a5a0efd49f100c7d53920807c83d9c74304ecd8Jiang, Yunhong &dSize, 1564a5a0efd49f100c7d53920807c83d9c74304ecd8Jiang, Yunhong (LPOVERLAPPED) NULL); 1574a5a0efd49f100c7d53920807c83d9c74304ecd8Jiang, Yunhong 1584a5a0efd49f100c7d53920807c83d9c74304ecd8Jiang, Yunhong if (!ret) { 1594a5a0efd49f100c7d53920807c83d9c74304ecd8Jiang, Yunhong err = GetLastError(); 1604a5a0efd49f100c7d53920807c83d9c74304ecd8Jiang, Yunhong if (err == ERROR_INSUFFICIENT_BUFFER || 1614a5a0efd49f100c7d53920807c83d9c74304ecd8Jiang, Yunhong err == ERROR_MORE_DATA) 1624a5a0efd49f100c7d53920807c83d9c74304ecd8Jiang, Yunhong dprint("hax capability is too long to hold.\n"); 1634a5a0efd49f100c7d53920807c83d9c74304ecd8Jiang, Yunhong dprint("Failed to get Hax capability:%d\n", err); 1644a5a0efd49f100c7d53920807c83d9c74304ecd8Jiang, Yunhong return -EFAULT; 1654a5a0efd49f100c7d53920807c83d9c74304ecd8Jiang, Yunhong } else 1664a5a0efd49f100c7d53920807c83d9c74304ecd8Jiang, Yunhong return 0; 1674a5a0efd49f100c7d53920807c83d9c74304ecd8Jiang, Yunhong} 1684a5a0efd49f100c7d53920807c83d9c74304ecd8Jiang, Yunhong 169e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajimaint hax_mod_version(struct hax_state *hax, struct hax_module_version *version) 170e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima{ 171e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima int ret; 172e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima HANDLE hDevice = hax->fd; //handle to hax module 173e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima DWORD dSize = 0; 174e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima DWORD err = 0; 175e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 176e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima if (hax_invalid_fd(hDevice)) { 177e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima dprint("Invalid fd for hax device!\n"); 178e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima return -ENODEV; 179e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima } 180e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 181e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima ret = DeviceIoControl(hDevice, 182e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima HAX_IOCTL_VERSION, 183e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima NULL, 0, 184e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima version, sizeof(*version), 185e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima &dSize, 186e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima (LPOVERLAPPED) NULL); 187e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 188e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima if (!ret) { 189e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima err = GetLastError(); 190e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima if (err == ERROR_INSUFFICIENT_BUFFER || 191e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima err == ERROR_MORE_DATA) 192e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima dprint("HAX module is too large.\n"); 193e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima dprint("Failed to get Hax module version:%d\n", err); 194e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima return -EFAULT; 195e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima } else 196e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima return 0; 197e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima} 198e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 199e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajimastatic char *hax_vm_devfs_string(int vm_id) 200e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima{ 201e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima char *name; 202e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 203e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima if (vm_id > MAX_VM_ID) 204e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima { 205e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima dprint("Too big VM id\n"); 206e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima return NULL; 207e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima } 208e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 209aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner name = g_strdup("\\\\.\\hax_vmxx"); 210e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima if (!name) 211e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima return NULL; 212e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima sprintf(name, "\\\\.\\hax_vm%02d", vm_id); 213e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 214e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima return name; 215e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima} 216e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 217e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajimastatic char *hax_vcpu_devfs_string(int vm_id, int vcpu_id) 218e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima{ 219e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima char *name; 220e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 221e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima if (vm_id > MAX_VM_ID || vcpu_id > MAX_VCPU_ID) 222e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima { 223e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima dprint("Too big vm id %x or vcpu id %x\n", vm_id, vcpu_id); 224e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima return NULL; 225e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima } 226aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner name = g_strdup("\\\\.\\hax_vmxx_vcpuxx"); 227e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima if (!name) 228e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima return NULL; 229e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima sprintf(name, "\\\\.\\hax_vm%02d_vcpu%02d", vm_id, vcpu_id); 230e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 231e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima return name; 232e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima} 233e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 2341d1280d7d347bb9467bfe9c161cba254f9e55d1cJiang, Yunhongint hax_host_create_vm(struct hax_state *hax, int *vmid) 235e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima{ 236e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima int ret; 2371d1280d7d347bb9467bfe9c161cba254f9e55d1cJiang, Yunhong int vm_id = 0; 238e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima DWORD dSize = 0; 239e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 240e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima if (hax_invalid_fd(hax->fd)) 241e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima return -EINVAL; 242e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 243e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima if (hax->vm) 244e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima return 0; 245e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 246e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima ret = DeviceIoControl(hax->fd, 247e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima HAX_IOCTL_CREATE_VM, 248e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima NULL, 0, 249e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima &vm_id, sizeof(vm_id), 250e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima &dSize, 251e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima (LPOVERLAPPED) NULL); 252e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima if (!ret) { 253e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima dprint("error code:%d", GetLastError()); 254e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima return -1; 255e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima } 2561d1280d7d347bb9467bfe9c161cba254f9e55d1cJiang, Yunhong *vmid = vm_id; 257e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima return 0; 258e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima} 259e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 260e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajimahax_fd hax_host_open_vm(struct hax_state *hax, int vm_id) 261e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima{ 262e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima char *vm_name = NULL; 263e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima hax_fd hDeviceVM; 264e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 265e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima vm_name = hax_vm_devfs_string(vm_id); 266e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima if (!vm_name) { 267e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima dprint("Incorrect name\n"); 268e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima return INVALID_HANDLE_VALUE; 269e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima } 270e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 271e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima hDeviceVM = CreateFile(vm_name, 272e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima GENERIC_READ | GENERIC_WRITE, 273e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 0, 274e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima NULL, 275e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima CREATE_ALWAYS, 276e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima FILE_ATTRIBUTE_NORMAL, 277e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima NULL); 278e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima if (hDeviceVM == INVALID_HANDLE_VALUE) 279e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima dprint("Open the vm devcie error:%s, ec:%d\n", vm_name, GetLastError()); 280e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 281aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner g_free(vm_name); 282e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima return hDeviceVM; 283e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima} 284e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 2858a539eaab40dc7a8047dbf97c081467029e6c518Jiang, Yunhongint hax_notify_qemu_version(hax_fd vm_fd, struct hax_qemu_version *qversion) 2868a539eaab40dc7a8047dbf97c081467029e6c518Jiang, Yunhong{ 2878a539eaab40dc7a8047dbf97c081467029e6c518Jiang, Yunhong int ret; 2888a539eaab40dc7a8047dbf97c081467029e6c518Jiang, Yunhong DWORD dSize = 0; 2898a539eaab40dc7a8047dbf97c081467029e6c518Jiang, Yunhong 2908a539eaab40dc7a8047dbf97c081467029e6c518Jiang, Yunhong if (hax_invalid_fd(vm_fd)) 2918a539eaab40dc7a8047dbf97c081467029e6c518Jiang, Yunhong return -EINVAL; 2928a539eaab40dc7a8047dbf97c081467029e6c518Jiang, Yunhong 2938a539eaab40dc7a8047dbf97c081467029e6c518Jiang, Yunhong ret = DeviceIoControl(vm_fd, 2948a539eaab40dc7a8047dbf97c081467029e6c518Jiang, Yunhong HAX_VM_IOCTL_NOTIFY_QEMU_VERSION, 2958a539eaab40dc7a8047dbf97c081467029e6c518Jiang, Yunhong qversion, sizeof(struct hax_qemu_version), 2968a539eaab40dc7a8047dbf97c081467029e6c518Jiang, Yunhong NULL, 0, 2978a539eaab40dc7a8047dbf97c081467029e6c518Jiang, Yunhong &dSize, 2988a539eaab40dc7a8047dbf97c081467029e6c518Jiang, Yunhong (LPOVERLAPPED) NULL); 2998a539eaab40dc7a8047dbf97c081467029e6c518Jiang, Yunhong if (!ret) 3008a539eaab40dc7a8047dbf97c081467029e6c518Jiang, Yunhong { 3018a539eaab40dc7a8047dbf97c081467029e6c518Jiang, Yunhong dprint("Failed to notify qemu API version\n"); 3028a539eaab40dc7a8047dbf97c081467029e6c518Jiang, Yunhong return -1; 3038a539eaab40dc7a8047dbf97c081467029e6c518Jiang, Yunhong } 3048a539eaab40dc7a8047dbf97c081467029e6c518Jiang, Yunhong 3058a539eaab40dc7a8047dbf97c081467029e6c518Jiang, Yunhong return 0; 3068a539eaab40dc7a8047dbf97c081467029e6c518Jiang, Yunhong} 3078a539eaab40dc7a8047dbf97c081467029e6c518Jiang, Yunhong 308e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajimaint hax_host_create_vcpu(hax_fd vm_fd, int vcpuid) 309e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima{ 310e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima int ret; 311e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima DWORD dSize = 0; 312e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 313e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima ret = DeviceIoControl(vm_fd, 314e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima HAX_VM_IOCTL_VCPU_CREATE, 315e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima &vcpuid, sizeof(vcpuid), 316e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima NULL, 0, 317e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima &dSize, 318e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima (LPOVERLAPPED) NULL); 319e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima if (!ret) 320e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima { 321e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima dprint("Failed to create vcpu %x\n", vcpuid); 322e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima return -1; 323e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima } 324e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 325e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima return 0; 326e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima} 327e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 328e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajimahax_fd hax_host_open_vcpu(int vmid, int vcpuid) 329e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima{ 330e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima char *devfs_path = NULL; 331e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima hax_fd hDeviceVCPU; 332e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 333e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima devfs_path = hax_vcpu_devfs_string(vmid, vcpuid); 334e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima if (!devfs_path) 335e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima { 336e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima dprint("Failed to get the devfs\n"); 337e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima return INVALID_HANDLE_VALUE; 338e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima } 339e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 340e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima hDeviceVCPU = CreateFile( devfs_path, 341e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima GENERIC_READ | GENERIC_WRITE, 342e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 0, 343e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima NULL, 344e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima CREATE_ALWAYS, 345e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima FILE_ATTRIBUTE_NORMAL, 346e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima NULL); 347e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 348e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima if (hDeviceVCPU == INVALID_HANDLE_VALUE) 349e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima dprint("Failed to open the vcpu devfs\n"); 350aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner g_free(devfs_path); 351e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima return hDeviceVCPU; 352e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima} 353e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 354e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajimaint hax_host_setup_vcpu_channel(struct hax_vcpu_state *vcpu) 355e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima{ 356e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima hax_fd hDeviceVCPU = vcpu->fd; 357e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima int ret; 358e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima struct hax_tunnel_info info; 359e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima DWORD dSize = 0; 360e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 361e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima ret = DeviceIoControl(hDeviceVCPU, 362e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima HAX_VCPU_IOCTL_SETUP_TUNNEL, 363e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima NULL, 0, 364e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima &info, sizeof(info), 365e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima &dSize, 366e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima (LPOVERLAPPED) NULL); 367e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima if (!ret) 368e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima { 369e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima dprint("Failed to setup the hax tunnel\n"); 370e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima return -1; 371e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima } 372e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 373e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima if (!valid_hax_tunnel_size(info.size)) 374e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima { 375e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima dprint("Invalid hax tunnel size %x\n", info.size); 376e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima ret = -EINVAL; 377e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima return ret; 378e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima } 379a2c14f947951612b45024095afd2210aa7368773David 'Digit' Turner vcpu->tunnel = (struct hax_tunnel *)(uintptr_t)(info.va); 380a2c14f947951612b45024095afd2210aa7368773David 'Digit' Turner vcpu->iobuf = (unsigned char *)(uintptr_t)(info.io_va); 381e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima return 0; 382e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima} 383e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 384e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajimaint hax_vcpu_run(struct hax_vcpu_state* vcpu) 385e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima{ 386e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima int ret; 387e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima HANDLE hDeviceVCPU = vcpu->fd; 388e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima DWORD dSize = 0; 389e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 390e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima ret = DeviceIoControl(hDeviceVCPU, 391e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima HAX_VCPU_IOCTL_RUN, 392e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima NULL, 0, 393e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima NULL, 0, 394e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima &dSize, 395e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima (LPOVERLAPPED) NULL); 396e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima if (!ret) 397e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima return -EFAULT; 398e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima else 399e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima return 0; 400e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima} 401e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 4027f38c7f905384c064b88fbdfa2eb054a92be63f3David 'Digit' Turnerint hax_sync_fpu(CPUState *cpu, struct fx_layout *fl, int set) 403e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima{ 404e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima int ret; 405e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima hax_fd fd; 406e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima HANDLE hDeviceVCPU; 407e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima DWORD dSize = 0; 408e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 4097f38c7f905384c064b88fbdfa2eb054a92be63f3David 'Digit' Turner fd = hax_vcpu_get_fd(cpu); 410e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima if (hax_invalid_fd(fd)) 411e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima return -1; 412e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 413e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima hDeviceVCPU = fd; 414e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 415e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima if (set) 416e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima ret = DeviceIoControl(hDeviceVCPU, 417e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima HAX_VCPU_IOCTL_SET_FPU, 418e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima fl, sizeof(*fl), 419e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima NULL, 0, 420e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima &dSize, 421e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima (LPOVERLAPPED) NULL); 422e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima else 423e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima ret = DeviceIoControl(hDeviceVCPU, 424e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima HAX_VCPU_IOCTL_GET_FPU, 425e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima NULL, 0, 426e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima fl, sizeof(*fl), 427e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima &dSize, 428e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima (LPOVERLAPPED) NULL); 429e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima if (!ret) 430e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima return -EFAULT; 431e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima else 432e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima return 0; 433e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima} 434e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 4357f38c7f905384c064b88fbdfa2eb054a92be63f3David 'Digit' Turnerint hax_sync_msr(CPUState *cpu, struct hax_msr_data *msrs, int set) 436e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima{ 437e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima int ret; 438e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima hax_fd fd; 439e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima HANDLE hDeviceVCPU; 440e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima DWORD dSize = 0; 441e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 4427f38c7f905384c064b88fbdfa2eb054a92be63f3David 'Digit' Turner fd = hax_vcpu_get_fd(cpu); 443e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima if (hax_invalid_fd(fd)) 444e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima return -1; 445e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima hDeviceVCPU = fd; 446e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 447e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima if (set) 448e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima ret = DeviceIoControl(hDeviceVCPU, 449e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima HAX_VCPU_IOCTL_SET_MSRS, 450e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima msrs, sizeof(*msrs), 451e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima msrs, sizeof(*msrs), 452e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima &dSize, 453e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima (LPOVERLAPPED) NULL); 454e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima else 455e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima ret = DeviceIoControl(hDeviceVCPU, 456e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima HAX_VCPU_IOCTL_GET_MSRS, 457e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima msrs, sizeof(*msrs), 458e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima msrs, sizeof(*msrs), 459e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima &dSize, 460e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima (LPOVERLAPPED) NULL); 461e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima if (!ret) 462e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima return -EFAULT; 463e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima else 464e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima return 0; 465e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima} 466e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 4677f38c7f905384c064b88fbdfa2eb054a92be63f3David 'Digit' Turnerint hax_sync_vcpu_state(CPUState *cpu, struct vcpu_state_t *state, int set) 468e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima{ 469e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima int ret; 470e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima hax_fd fd; 471e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima HANDLE hDeviceVCPU; 472e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima DWORD dSize; 473e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 4747f38c7f905384c064b88fbdfa2eb054a92be63f3David 'Digit' Turner fd = hax_vcpu_get_fd(cpu); 475e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima if (hax_invalid_fd(fd)) 476e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima return -1; 477e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 478e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima hDeviceVCPU = fd; 479e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 480e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima if (set) 481e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima ret = DeviceIoControl(hDeviceVCPU, 482e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima HAX_VCPU_SET_REGS, 483e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima state, sizeof(*state), 484e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima NULL, 0, 485e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima &dSize, 486e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima (LPOVERLAPPED) NULL); 487e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima else 488e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima ret = DeviceIoControl(hDeviceVCPU, 489e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima HAX_VCPU_GET_REGS, 490e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima NULL, 0, 491e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima state, sizeof(*state), 492e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima &dSize, 493e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima (LPOVERLAPPED) NULL); 494e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima if (!ret) 495e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima return -EFAULT; 496e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima else 497e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima return 0; 498e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima} 499e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 5007f38c7f905384c064b88fbdfa2eb054a92be63f3David 'Digit' Turnerint hax_inject_interrupt(CPUState *cpu, int vector) 501e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima{ 502e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima int ret; 503e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima hax_fd fd; 504e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima HANDLE hDeviceVCPU; 505e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima DWORD dSize; 506e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 5077f38c7f905384c064b88fbdfa2eb054a92be63f3David 'Digit' Turner fd = hax_vcpu_get_fd(cpu); 508e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima if (hax_invalid_fd(fd)) 509e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima return -1; 510e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 511e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima hDeviceVCPU = fd; 512e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima 513e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima ret = DeviceIoControl(hDeviceVCPU, 514e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima HAX_VCPU_IOCTL_INTERRUPT, 515e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima &vector, sizeof(vector), 516e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima NULL, 0, 517e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima &dSize, 518e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima (LPOVERLAPPED) NULL); 519e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima if (!ret) 520e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima return -EFAULT; 521e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima else 522e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima return 0; 523e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima} 524