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/* HAX module interface - darwin version */
15e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima#include <sys/types.h>
16e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima#include <sys/stat.h>
17e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima#include <fcntl.h>
18e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima#include <errno.h>
19e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima#include <sys/ioctl.h>
20e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima
21e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima#include "target-i386/hax-i386.h"
22e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajimahax_fd hax_mod_open(void)
23e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima{
24e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    int fd = open("/dev/HAX", O_RDWR);
25e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima
26e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    if (fd == -1)
27e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    {
28e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima        dprint("Failed to open the hax module\n");
29e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima        return -errno;
30e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    }
31e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima
32e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    return fd;
33e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima}
34e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima
35e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajimaint hax_populate_ram(uint64_t va, uint32_t size)
36e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima{
37e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    int ret;
38e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    struct hax_alloc_ram_info info;
39e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima
40e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    if (!hax_global.vm || !hax_global.vm->fd)
41e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    {
42e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima        dprint("Allocate memory before vm create?\n");
43e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima        return -EINVAL;
44e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    }
45e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima
46e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    info.size = size;
47e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    info.va = va;
48e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    ret = ioctl(hax_global.vm->fd, HAX_VM_IOCTL_ALLOC_RAM, &info);
49e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    if (ret < 0)
50e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    {
51e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima        dprint("Failed to allocate %x memory\n", size);
52e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima        return ret;
53e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    }
54e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    return 0;
55e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima}
56e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima
57e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajimaint hax_set_phys_mem(target_phys_addr_t start_addr, ram_addr_t size, ram_addr_t phys_offset)
58e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima{
59e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    struct hax_set_ram_info info, *pinfo = &info;
60e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    int ret;
61e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    ram_addr_t flags = phys_offset & ~TARGET_PAGE_MASK;
62e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima
63e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    /* We look for the  RAM and ROM only */
64e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    if (flags >= IO_MEM_UNASSIGNED)
65e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima        return 0;
66e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima
67e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    if ( (start_addr & ~TARGET_PAGE_MASK) || (size & ~TARGET_PAGE_MASK))
68e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    {
69e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima        dprint("set_phys_mem %x %lx requires page aligned addr and size\n", start_addr, size);
70e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima        exit(1);
71e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima        return -1;
72e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    }
73e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima
74e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    info.pa_start = start_addr;
75e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    info.size = size;
76e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    info.va = (uint64_t)qemu_get_ram_ptr(phys_offset);
77e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    info.flags = (flags & IO_MEM_ROM) ? 1 : 0;
78e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima
79e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    ret = ioctl(hax_global.vm->fd, HAX_VM_IOCTL_SET_RAM, pinfo);
80e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    if (ret < 0)
81e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    {
82e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima        dprint("has set phys mem failed\n");
83e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima        exit(1);
84e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    }
85e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    return ret;
86e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima}
87e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima
884a5a0efd49f100c7d53920807c83d9c74304ecd8Jiang, Yunhongint hax_capability(struct hax_state *hax, struct hax_capabilityinfo *cap)
894a5a0efd49f100c7d53920807c83d9c74304ecd8Jiang, Yunhong{
904a5a0efd49f100c7d53920807c83d9c74304ecd8Jiang, Yunhong    int ret;
914a5a0efd49f100c7d53920807c83d9c74304ecd8Jiang, Yunhong
924a5a0efd49f100c7d53920807c83d9c74304ecd8Jiang, Yunhong    ret = ioctl(hax->fd, HAX_IOCTL_CAPABILITY, cap);
934a5a0efd49f100c7d53920807c83d9c74304ecd8Jiang, Yunhong    if (ret == -1)
944a5a0efd49f100c7d53920807c83d9c74304ecd8Jiang, Yunhong    {
954a5a0efd49f100c7d53920807c83d9c74304ecd8Jiang, Yunhong        dprint("Failed to get HAX capability\n");
964a5a0efd49f100c7d53920807c83d9c74304ecd8Jiang, Yunhong        return -errno;
974a5a0efd49f100c7d53920807c83d9c74304ecd8Jiang, Yunhong    }
984a5a0efd49f100c7d53920807c83d9c74304ecd8Jiang, Yunhong
994a5a0efd49f100c7d53920807c83d9c74304ecd8Jiang, Yunhong    return 0;
100e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima}
101e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima
102e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajimaint hax_mod_version(struct hax_state *hax, struct hax_module_version *version)
103e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima{
104e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    int ret;
105e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima
106e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    ret = ioctl(hax->fd, HAX_IOCTL_VERSION, version);
107e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    if (ret == -1)
108e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    {
109e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima        dprint("Failed to get HAX version\n");
110e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima        return -errno;
111e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    }
112e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima
113e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    return 0;
114e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima}
115e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima
116e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajimastatic char *hax_vm_devfs_string(int vm_id)
117e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima{
118e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    char *name;
119e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima
120e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    if (vm_id > MAX_VM_ID)
121e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    {
122e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima        dprint("Too big VM id\n");
123e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima        return NULL;
124e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    }
125e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima
126e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    name = qemu_strdup("/dev/hax_vm/vmxx");
127e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    if (!name)
128e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima        return NULL;
129e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    sprintf(name, "/dev/hax_vm/vm%02d", vm_id);
130e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima
131e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    return name;
132e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima}
133e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima
134e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajimastatic char *hax_vcpu_devfs_string(int vm_id, int vcpu_id)
135e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima{
136e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    char *name;
137e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima
138e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    if (vm_id > MAX_VM_ID || vcpu_id > MAX_VCPU_ID)
139e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    {
140e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima        dprint("Too big vm id %x or vcpu id %x\n", vm_id, vcpu_id);
141e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima        return NULL;
142e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    }
143e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima
144e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    name = qemu_strdup("/dev/hax_vmxx/vcpuyy");
145e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    if (!name)
146e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima        return NULL;
147e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima
148e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    sprintf(name, "/dev/hax_vm%02d/vcpu%02d", vm_id, vcpu_id);
149e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima
150e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    return name;
151e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima}
152e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima
1531d1280d7d347bb9467bfe9c161cba254f9e55d1cJiang, Yunhongint hax_host_create_vm(struct hax_state *hax, int *vmid)
154e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima{
155e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    int ret;
1561d1280d7d347bb9467bfe9c161cba254f9e55d1cJiang, Yunhong    int vm_id = 0;
157e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima
158e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    if (hax_invalid_fd(hax->fd))
159e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima        return -EINVAL;
160e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima
161e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    if (hax->vm)
162e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima        return 0;
163e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima
164e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    ret = ioctl(hax->fd, HAX_IOCTL_CREATE_VM, &vm_id);
1651d1280d7d347bb9467bfe9c161cba254f9e55d1cJiang, Yunhong    *vmid = vm_id;
166e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    return ret;
167e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima}
168e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima
169e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajimahax_fd hax_host_open_vm(struct hax_state *hax, int vm_id)
170e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima{
171e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    hax_fd fd;
172e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    char *vm_name = NULL;
173e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima
174e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    vm_name = hax_vm_devfs_string(vm_id);
175e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    if (!vm_name)
176e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima        return -1;
177e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima
178e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    fd = open(vm_name, O_RDWR);
179e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    qemu_free(vm_name);
180e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima
181e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    return fd;
182e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima}
183e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima
1848a539eaab40dc7a8047dbf97c081467029e6c518Jiang, Yunhongint hax_notify_qemu_version(hax_fd vm_fd, struct hax_qemu_version *qversion)
1858a539eaab40dc7a8047dbf97c081467029e6c518Jiang, Yunhong{
1868a539eaab40dc7a8047dbf97c081467029e6c518Jiang, Yunhong    int ret;
1878a539eaab40dc7a8047dbf97c081467029e6c518Jiang, Yunhong
1888a539eaab40dc7a8047dbf97c081467029e6c518Jiang, Yunhong    if (hax_invalid_fd(vm_fd))
1898a539eaab40dc7a8047dbf97c081467029e6c518Jiang, Yunhong        return -EINVAL;
1908a539eaab40dc7a8047dbf97c081467029e6c518Jiang, Yunhong
1918a539eaab40dc7a8047dbf97c081467029e6c518Jiang, Yunhong    ret = ioctl(vm_fd, HAX_VM_IOCTL_NOTIFY_QEMU_VERSION, qversion);
1928a539eaab40dc7a8047dbf97c081467029e6c518Jiang, Yunhong    if (ret == -1)
1938a539eaab40dc7a8047dbf97c081467029e6c518Jiang, Yunhong    {
1948a539eaab40dc7a8047dbf97c081467029e6c518Jiang, Yunhong        dprint("Failed to notify qemu API version\n");
1958a539eaab40dc7a8047dbf97c081467029e6c518Jiang, Yunhong        return -errno;
1968a539eaab40dc7a8047dbf97c081467029e6c518Jiang, Yunhong    }
1978a539eaab40dc7a8047dbf97c081467029e6c518Jiang, Yunhong
1988a539eaab40dc7a8047dbf97c081467029e6c518Jiang, Yunhong    return 0;
1998a539eaab40dc7a8047dbf97c081467029e6c518Jiang, Yunhong}
2008a539eaab40dc7a8047dbf97c081467029e6c518Jiang, Yunhong
201e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima/*
202e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima * Simply assume that the size should be bigger than the hax_tunnel,
203e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima * since the hax_tunnel can be extended later with backward
204e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima * compatibility.
205e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima */
206e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajimaint hax_host_create_vcpu(hax_fd vm_fd, int vcpuid)
207e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima{
208e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    int ret;
209e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima
210e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    ret = ioctl(vm_fd, HAX_VM_IOCTL_VCPU_CREATE, &vcpuid);
211e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    if (ret < 0)
212e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima        dprint("Failed to create vcpu %x\n", vcpuid);
213e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima
214e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    return ret;
215e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima}
216e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima
217e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajimahax_fd hax_host_open_vcpu(int vmid, int vcpuid)
218e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima{
219e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    char *devfs_path = NULL;
220e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    hax_fd fd;
221e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima
222e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    devfs_path = hax_vcpu_devfs_string(vmid, vcpuid);
223e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    if (!devfs_path)
224e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    {
225e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima        dprint("Failed to get the devfs\n");
226e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima        return -EINVAL;
227e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    }
228e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima
229e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    fd = open(devfs_path, O_RDWR);
230e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    qemu_free(devfs_path);
231e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    if (fd < 0)
232e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima        dprint("Failed to open the vcpu devfs\n");
233e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    return fd;
234e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima}
235e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima
236e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajimaint hax_host_setup_vcpu_channel(struct hax_vcpu_state *vcpu)
237e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima{
238e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    int ret;
239e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    struct hax_tunnel_info info;
240e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima
241e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    ret = ioctl(vcpu->fd, HAX_VCPU_IOCTL_SETUP_TUNNEL, &info);
242e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    if (ret)
243e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    {
244e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima        dprint("Failed to setup the hax tunnel\n");
245e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima        return ret;
246e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    }
247e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima
248e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    if (!valid_hax_tunnel_size(info.size))
249e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    {
250e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima        dprint("Invalid hax tunnel size %x\n", info.size);
251e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima        ret = -EINVAL;
252e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima        return ret;
253e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    }
254e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima
255e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    vcpu->tunnel = (struct hax_tunnel *)(info.va);
256e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    vcpu->iobuf = (unsigned char *)(info.io_va);
257e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    return 0;
258e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima}
259e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima
260e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajimaint hax_vcpu_run(struct hax_vcpu_state* vcpu)
261e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima{
262e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    int ret;
263e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima
264e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    ret = ioctl(vcpu->fd, HAX_VCPU_IOCTL_RUN, NULL);
265e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    return ret;
266e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima}
267e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima
268e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajimaint hax_sync_fpu(CPUState *env, struct fx_layout *fl, int set)
269e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima{
270e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    int ret, fd;
271e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima
272e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    fd = hax_vcpu_get_fd(env);
273e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    if (fd <= 0)
274e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima        return -1;
275e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima
276e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    if (set)
277e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima        ret = ioctl(fd, HAX_VCPU_IOCTL_SET_FPU, fl);
278e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    else
279e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima        ret = ioctl(fd, HAX_VCPU_IOCTL_GET_FPU, fl);
280e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    return ret;
281e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima}
282e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima
283e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajimaint hax_sync_msr(CPUState *env, struct hax_msr_data *msrs, int set)
284e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima{
285e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    int ret, fd;
286e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima
287e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    fd = hax_vcpu_get_fd(env);
288e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    if (fd <= 0)
289e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima        return -1;
290e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    if (set)
291e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima        ret = ioctl(fd, HAX_VCPU_IOCTL_SET_MSRS, msrs);
292e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    else
293e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima        ret = ioctl(fd, HAX_VCPU_IOCTL_GET_MSRS, msrs);
294e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    return ret;
295e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima}
296e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima
297e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajimaint hax_sync_vcpu_state(CPUState *env, struct vcpu_state_t *state, int set)
298e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima{
299e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    int ret, fd;
300e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima
301e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    fd = hax_vcpu_get_fd(env);
302e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    if (fd <= 0)
303e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima        return -1;
304e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima
305e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    if (set)
306e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima        ret = ioctl(fd, HAX_VCPU_SET_REGS, state);
307e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    else
308e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima        ret = ioctl(fd, HAX_VCPU_GET_REGS, state);
309e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    return ret;
310e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima}
311e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima
312e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajimaint hax_inject_interrupt(CPUState *env, int vector)
313e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima{
314e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    int ret, fd;
315e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima
316e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    fd = hax_vcpu_get_fd(env);
317e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    if (fd <= 0)
318e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima        return -1;
319e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima
320e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    ret = ioctl(fd, HAX_VCPU_IOCTL_INTERRUPT, &vector);
321e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima    return ret;
322e4a3c7801e0075a49674c79972394ad962b338f2Jun Nakajima}
323