4 * Copyright (c) 2011 Intel Corporation
6 * Jiang Yunhong<yunhong.jiang@intel.com>
8 * This work is licensed under the terms of the GNU GPL, version 2 or later.
9 * See the COPYING file in the top-level directory.
13 #include "qemu/osdep.h"
15 #include "exec/exec-all.h"
19 * return 0 when success, -1 when driver not loaded,
20 * other negative value for other failure
22 static int hax_open_device(hax_fd
*fd
)
31 hDevice
= CreateFile("\\\\.\\HAX",
32 GENERIC_READ
| GENERIC_WRITE
,
33 0, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
35 if (hDevice
== INVALID_HANDLE_VALUE
) {
36 fprintf(stderr
, "Failed to open the HAX device!\n");
37 errNum
= GetLastError();
38 if (errNum
== ERROR_FILE_NOT_FOUND
) {
47 /* hax_fd hax_mod_open */
48 hax_fd
hax_mod_open(void)
53 ret
= hax_open_device(&fd
);
55 fprintf(stderr
, "Open HAX device failed\n");
61 int hax_populate_ram(uint64_t va
, uint32_t size
)
64 struct hax_alloc_ram_info info
;
68 if (!hax_global
.vm
|| !hax_global
.vm
->fd
) {
69 fprintf(stderr
, "Allocate memory before vm create?\n");
76 hDeviceVM
= hax_global
.vm
->fd
;
78 ret
= DeviceIoControl(hDeviceVM
,
79 HAX_VM_IOCTL_ALLOC_RAM
,
80 &info
, sizeof(info
), NULL
, 0, &dSize
,
84 fprintf(stderr
, "Failed to allocate %x memory\n", size
);
91 int hax_set_ram(uint64_t start_pa
, uint32_t size
, uint64_t host_va
, int flags
)
93 struct hax_set_ram_info info
;
94 HANDLE hDeviceVM
= hax_global
.vm
->fd
;
98 info
.pa_start
= start_pa
;
101 info
.flags
= (uint8_t) flags
;
103 ret
= DeviceIoControl(hDeviceVM
, HAX_VM_IOCTL_SET_RAM
,
104 &info
, sizeof(info
), NULL
, 0, &dSize
,
105 (LPOVERLAPPED
) NULL
);
114 int hax_capability(struct hax_state
*hax
, struct hax_capabilityinfo
*cap
)
117 HANDLE hDevice
= hax
->fd
; /* handle to hax module */
121 if (hax_invalid_fd(hDevice
)) {
122 fprintf(stderr
, "Invalid fd for hax device!\n");
126 ret
= DeviceIoControl(hDevice
, HAX_IOCTL_CAPABILITY
, NULL
, 0, cap
,
127 sizeof(*cap
), &dSize
, (LPOVERLAPPED
) NULL
);
130 err
= GetLastError();
131 if (err
== ERROR_INSUFFICIENT_BUFFER
|| err
== ERROR_MORE_DATA
) {
132 fprintf(stderr
, "hax capability is too long to hold.\n");
134 fprintf(stderr
, "Failed to get Hax capability:%luu\n", err
);
141 int hax_mod_version(struct hax_state
*hax
, struct hax_module_version
*version
)
144 HANDLE hDevice
= hax
->fd
; /* handle to hax module */
148 if (hax_invalid_fd(hDevice
)) {
149 fprintf(stderr
, "Invalid fd for hax device!\n");
153 ret
= DeviceIoControl(hDevice
,
156 version
, sizeof(*version
), &dSize
,
157 (LPOVERLAPPED
) NULL
);
160 err
= GetLastError();
161 if (err
== ERROR_INSUFFICIENT_BUFFER
|| err
== ERROR_MORE_DATA
) {
162 fprintf(stderr
, "hax module verion is too long to hold.\n");
164 fprintf(stderr
, "Failed to get Hax module version:%lu\n", err
);
171 static char *hax_vm_devfs_string(int vm_id
)
175 if (vm_id
> MAX_VM_ID
) {
176 fprintf(stderr
, "Too big VM id\n");
180 #define HAX_VM_DEVFS "\\\\.\\hax_vmxx"
181 name
= g_strdup(HAX_VM_DEVFS
);
186 snprintf(name
, sizeof HAX_VM_DEVFS
, "\\\\.\\hax_vm%02d", vm_id
);
190 static char *hax_vcpu_devfs_string(int vm_id
, int vcpu_id
)
194 if (vm_id
> MAX_VM_ID
|| vcpu_id
> MAX_VCPU_ID
) {
195 fprintf(stderr
, "Too big vm id %x or vcpu id %x\n", vm_id
, vcpu_id
);
199 #define HAX_VCPU_DEVFS "\\\\.\\hax_vmxx_vcpuxx"
200 name
= g_strdup(HAX_VCPU_DEVFS
);
205 snprintf(name
, sizeof HAX_VCPU_DEVFS
, "\\\\.\\hax_vm%02d_vcpu%02d",
210 int hax_host_create_vm(struct hax_state
*hax
, int *vmid
)
216 if (hax_invalid_fd(hax
->fd
)) {
224 ret
= DeviceIoControl(hax
->fd
,
226 NULL
, 0, &vm_id
, sizeof(vm_id
), &dSize
,
227 (LPOVERLAPPED
) NULL
);
229 fprintf(stderr
, "Failed to create VM. Error code: %lu\n",
237 hax_fd
hax_host_open_vm(struct hax_state
*hax
, int vm_id
)
239 char *vm_name
= NULL
;
242 vm_name
= hax_vm_devfs_string(vm_id
);
244 fprintf(stderr
, "Failed to open VM. VM name is null\n");
245 return INVALID_HANDLE_VALUE
;
248 hDeviceVM
= CreateFile(vm_name
,
249 GENERIC_READ
| GENERIC_WRITE
,
250 0, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
251 if (hDeviceVM
== INVALID_HANDLE_VALUE
) {
252 fprintf(stderr
, "Open the vm device error:%s, ec:%lu\n",
253 vm_name
, GetLastError());
260 int hax_notify_qemu_version(hax_fd vm_fd
, struct hax_qemu_version
*qversion
)
264 if (hax_invalid_fd(vm_fd
)) {
267 ret
= DeviceIoControl(vm_fd
,
268 HAX_VM_IOCTL_NOTIFY_QEMU_VERSION
,
269 qversion
, sizeof(struct hax_qemu_version
),
270 NULL
, 0, &dSize
, (LPOVERLAPPED
) NULL
);
272 fprintf(stderr
, "Failed to notify qemu API version\n");
278 int hax_host_create_vcpu(hax_fd vm_fd
, int vcpuid
)
283 ret
= DeviceIoControl(vm_fd
,
284 HAX_VM_IOCTL_VCPU_CREATE
,
285 &vcpuid
, sizeof(vcpuid
), NULL
, 0, &dSize
,
286 (LPOVERLAPPED
) NULL
);
288 fprintf(stderr
, "Failed to create vcpu %x\n", vcpuid
);
295 hax_fd
hax_host_open_vcpu(int vmid
, int vcpuid
)
297 char *devfs_path
= NULL
;
300 devfs_path
= hax_vcpu_devfs_string(vmid
, vcpuid
);
302 fprintf(stderr
, "Failed to get the devfs\n");
303 return INVALID_HANDLE_VALUE
;
306 hDeviceVCPU
= CreateFile(devfs_path
,
307 GENERIC_READ
| GENERIC_WRITE
,
308 0, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
,
311 if (hDeviceVCPU
== INVALID_HANDLE_VALUE
) {
312 fprintf(stderr
, "Failed to open the vcpu devfs\n");
318 int hax_host_setup_vcpu_channel(struct hax_vcpu_state
*vcpu
)
320 hax_fd hDeviceVCPU
= vcpu
->fd
;
322 struct hax_tunnel_info info
;
325 ret
= DeviceIoControl(hDeviceVCPU
,
326 HAX_VCPU_IOCTL_SETUP_TUNNEL
,
327 NULL
, 0, &info
, sizeof(info
), &dSize
,
328 (LPOVERLAPPED
) NULL
);
330 fprintf(stderr
, "Failed to setup the hax tunnel\n");
334 if (!valid_hax_tunnel_size(info
.size
)) {
335 fprintf(stderr
, "Invalid hax tunnel size %x\n", info
.size
);
339 vcpu
->tunnel
= (struct hax_tunnel
*) (intptr_t) (info
.va
);
340 vcpu
->iobuf
= (unsigned char *) (intptr_t) (info
.io_va
);
344 int hax_vcpu_run(struct hax_vcpu_state
*vcpu
)
347 HANDLE hDeviceVCPU
= vcpu
->fd
;
350 ret
= DeviceIoControl(hDeviceVCPU
,
352 NULL
, 0, NULL
, 0, &dSize
, (LPOVERLAPPED
) NULL
);
360 int hax_sync_fpu(CPUArchState
*env
, struct fx_layout
*fl
, int set
)
367 fd
= hax_vcpu_get_fd(env
);
368 if (hax_invalid_fd(fd
)) {
375 ret
= DeviceIoControl(hDeviceVCPU
,
376 HAX_VCPU_IOCTL_SET_FPU
,
377 fl
, sizeof(*fl
), NULL
, 0, &dSize
,
378 (LPOVERLAPPED
) NULL
);
380 ret
= DeviceIoControl(hDeviceVCPU
,
381 HAX_VCPU_IOCTL_GET_FPU
,
382 NULL
, 0, fl
, sizeof(*fl
), &dSize
,
383 (LPOVERLAPPED
) NULL
);
392 int hax_sync_msr(CPUArchState
*env
, struct hax_msr_data
*msrs
, int set
)
399 fd
= hax_vcpu_get_fd(env
);
400 if (hax_invalid_fd(fd
)) {
406 ret
= DeviceIoControl(hDeviceVCPU
,
407 HAX_VCPU_IOCTL_SET_MSRS
,
409 msrs
, sizeof(*msrs
), &dSize
, (LPOVERLAPPED
) NULL
);
411 ret
= DeviceIoControl(hDeviceVCPU
,
412 HAX_VCPU_IOCTL_GET_MSRS
,
414 msrs
, sizeof(*msrs
), &dSize
, (LPOVERLAPPED
) NULL
);
423 int hax_sync_vcpu_state(CPUArchState
*env
, struct vcpu_state_t
*state
, int set
)
430 fd
= hax_vcpu_get_fd(env
);
431 if (hax_invalid_fd(fd
)) {
438 ret
= DeviceIoControl(hDeviceVCPU
,
440 state
, sizeof(*state
),
441 NULL
, 0, &dSize
, (LPOVERLAPPED
) NULL
);
443 ret
= DeviceIoControl(hDeviceVCPU
,
446 state
, sizeof(*state
), &dSize
,
447 (LPOVERLAPPED
) NULL
);
456 int hax_inject_interrupt(CPUArchState
*env
, int vector
)
463 fd
= hax_vcpu_get_fd(env
);
464 if (hax_invalid_fd(fd
)) {
470 ret
= DeviceIoControl(hDeviceVCPU
,
471 HAX_VCPU_IOCTL_INTERRUPT
,
472 &vector
, sizeof(vector
), NULL
, 0, &dSize
,
473 (LPOVERLAPPED
) NULL
);