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