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
, uint64_t size
)
67 if (!hax_global
.vm
|| !hax_global
.vm
->fd
) {
68 fprintf(stderr
, "Allocate memory before vm create?\n");
72 hDeviceVM
= hax_global
.vm
->fd
;
73 if (hax_global
.supports_64bit_ramblock
) {
74 struct hax_ramblock_info ramblock
= {
80 ret
= DeviceIoControl(hDeviceVM
,
81 HAX_VM_IOCTL_ADD_RAMBLOCK
,
82 &ramblock
, sizeof(ramblock
), NULL
, 0, &dSize
,
85 struct hax_alloc_ram_info info
= {
86 .size
= (uint32_t) size
,
91 ret
= DeviceIoControl(hDeviceVM
,
92 HAX_VM_IOCTL_ALLOC_RAM
,
93 &info
, sizeof(info
), NULL
, 0, &dSize
,
98 fprintf(stderr
, "Failed to register RAM block: va=0x%" PRIx64
99 ", size=0x%" PRIx64
", method=%s\n", va
, size
,
100 hax_global
.supports_64bit_ramblock
? "new" : "legacy");
107 int hax_set_ram(uint64_t start_pa
, uint32_t size
, uint64_t host_va
, int flags
)
109 struct hax_set_ram_info info
;
110 HANDLE hDeviceVM
= hax_global
.vm
->fd
;
114 info
.pa_start
= start_pa
;
117 info
.flags
= (uint8_t) flags
;
119 ret
= DeviceIoControl(hDeviceVM
, HAX_VM_IOCTL_SET_RAM
,
120 &info
, sizeof(info
), NULL
, 0, &dSize
,
121 (LPOVERLAPPED
) NULL
);
130 int hax_capability(struct hax_state
*hax
, struct hax_capabilityinfo
*cap
)
133 HANDLE hDevice
= hax
->fd
; /* handle to hax module */
137 if (hax_invalid_fd(hDevice
)) {
138 fprintf(stderr
, "Invalid fd for hax device!\n");
142 ret
= DeviceIoControl(hDevice
, HAX_IOCTL_CAPABILITY
, NULL
, 0, cap
,
143 sizeof(*cap
), &dSize
, (LPOVERLAPPED
) NULL
);
146 err
= GetLastError();
147 if (err
== ERROR_INSUFFICIENT_BUFFER
|| err
== ERROR_MORE_DATA
) {
148 fprintf(stderr
, "hax capability is too long to hold.\n");
150 fprintf(stderr
, "Failed to get Hax capability:%luu\n", err
);
157 int hax_mod_version(struct hax_state
*hax
, struct hax_module_version
*version
)
160 HANDLE hDevice
= hax
->fd
; /* handle to hax module */
164 if (hax_invalid_fd(hDevice
)) {
165 fprintf(stderr
, "Invalid fd for hax device!\n");
169 ret
= DeviceIoControl(hDevice
,
172 version
, sizeof(*version
), &dSize
,
173 (LPOVERLAPPED
) NULL
);
176 err
= GetLastError();
177 if (err
== ERROR_INSUFFICIENT_BUFFER
|| err
== ERROR_MORE_DATA
) {
178 fprintf(stderr
, "hax module verion is too long to hold.\n");
180 fprintf(stderr
, "Failed to get Hax module version:%lu\n", err
);
187 static char *hax_vm_devfs_string(int vm_id
)
191 if (vm_id
> MAX_VM_ID
) {
192 fprintf(stderr
, "Too big VM id\n");
196 #define HAX_VM_DEVFS "\\\\.\\hax_vmxx"
197 name
= g_strdup(HAX_VM_DEVFS
);
202 snprintf(name
, sizeof HAX_VM_DEVFS
, "\\\\.\\hax_vm%02d", vm_id
);
206 static char *hax_vcpu_devfs_string(int vm_id
, int vcpu_id
)
210 if (vm_id
> MAX_VM_ID
|| vcpu_id
> MAX_VCPU_ID
) {
211 fprintf(stderr
, "Too big vm id %x or vcpu id %x\n", vm_id
, vcpu_id
);
215 #define HAX_VCPU_DEVFS "\\\\.\\hax_vmxx_vcpuxx"
216 name
= g_strdup(HAX_VCPU_DEVFS
);
221 snprintf(name
, sizeof HAX_VCPU_DEVFS
, "\\\\.\\hax_vm%02d_vcpu%02d",
226 int hax_host_create_vm(struct hax_state
*hax
, int *vmid
)
232 if (hax_invalid_fd(hax
->fd
)) {
240 ret
= DeviceIoControl(hax
->fd
,
242 NULL
, 0, &vm_id
, sizeof(vm_id
), &dSize
,
243 (LPOVERLAPPED
) NULL
);
245 fprintf(stderr
, "Failed to create VM. Error code: %lu\n",
253 hax_fd
hax_host_open_vm(struct hax_state
*hax
, int vm_id
)
255 char *vm_name
= NULL
;
258 vm_name
= hax_vm_devfs_string(vm_id
);
260 fprintf(stderr
, "Failed to open VM. VM name is null\n");
261 return INVALID_HANDLE_VALUE
;
264 hDeviceVM
= CreateFile(vm_name
,
265 GENERIC_READ
| GENERIC_WRITE
,
266 0, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
267 if (hDeviceVM
== INVALID_HANDLE_VALUE
) {
268 fprintf(stderr
, "Open the vm device error:%s, ec:%lu\n",
269 vm_name
, GetLastError());
276 int hax_notify_qemu_version(hax_fd vm_fd
, struct hax_qemu_version
*qversion
)
280 if (hax_invalid_fd(vm_fd
)) {
283 ret
= DeviceIoControl(vm_fd
,
284 HAX_VM_IOCTL_NOTIFY_QEMU_VERSION
,
285 qversion
, sizeof(struct hax_qemu_version
),
286 NULL
, 0, &dSize
, (LPOVERLAPPED
) NULL
);
288 fprintf(stderr
, "Failed to notify qemu API version\n");
294 int hax_host_create_vcpu(hax_fd vm_fd
, int vcpuid
)
299 ret
= DeviceIoControl(vm_fd
,
300 HAX_VM_IOCTL_VCPU_CREATE
,
301 &vcpuid
, sizeof(vcpuid
), NULL
, 0, &dSize
,
302 (LPOVERLAPPED
) NULL
);
304 fprintf(stderr
, "Failed to create vcpu %x\n", vcpuid
);
311 hax_fd
hax_host_open_vcpu(int vmid
, int vcpuid
)
313 char *devfs_path
= NULL
;
316 devfs_path
= hax_vcpu_devfs_string(vmid
, vcpuid
);
318 fprintf(stderr
, "Failed to get the devfs\n");
319 return INVALID_HANDLE_VALUE
;
322 hDeviceVCPU
= CreateFile(devfs_path
,
323 GENERIC_READ
| GENERIC_WRITE
,
324 0, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
,
327 if (hDeviceVCPU
== INVALID_HANDLE_VALUE
) {
328 fprintf(stderr
, "Failed to open the vcpu devfs\n");
334 int hax_host_setup_vcpu_channel(struct hax_vcpu_state
*vcpu
)
336 hax_fd hDeviceVCPU
= vcpu
->fd
;
338 struct hax_tunnel_info info
;
341 ret
= DeviceIoControl(hDeviceVCPU
,
342 HAX_VCPU_IOCTL_SETUP_TUNNEL
,
343 NULL
, 0, &info
, sizeof(info
), &dSize
,
344 (LPOVERLAPPED
) NULL
);
346 fprintf(stderr
, "Failed to setup the hax tunnel\n");
350 if (!valid_hax_tunnel_size(info
.size
)) {
351 fprintf(stderr
, "Invalid hax tunnel size %x\n", info
.size
);
355 vcpu
->tunnel
= (struct hax_tunnel
*) (intptr_t) (info
.va
);
356 vcpu
->iobuf
= (unsigned char *) (intptr_t) (info
.io_va
);
360 int hax_vcpu_run(struct hax_vcpu_state
*vcpu
)
363 HANDLE hDeviceVCPU
= vcpu
->fd
;
366 ret
= DeviceIoControl(hDeviceVCPU
,
368 NULL
, 0, NULL
, 0, &dSize
, (LPOVERLAPPED
) NULL
);
376 int hax_sync_fpu(CPUArchState
*env
, struct fx_layout
*fl
, int set
)
383 fd
= hax_vcpu_get_fd(env
);
384 if (hax_invalid_fd(fd
)) {
391 ret
= DeviceIoControl(hDeviceVCPU
,
392 HAX_VCPU_IOCTL_SET_FPU
,
393 fl
, sizeof(*fl
), NULL
, 0, &dSize
,
394 (LPOVERLAPPED
) NULL
);
396 ret
= DeviceIoControl(hDeviceVCPU
,
397 HAX_VCPU_IOCTL_GET_FPU
,
398 NULL
, 0, fl
, sizeof(*fl
), &dSize
,
399 (LPOVERLAPPED
) NULL
);
408 int hax_sync_msr(CPUArchState
*env
, struct hax_msr_data
*msrs
, int set
)
415 fd
= hax_vcpu_get_fd(env
);
416 if (hax_invalid_fd(fd
)) {
422 ret
= DeviceIoControl(hDeviceVCPU
,
423 HAX_VCPU_IOCTL_SET_MSRS
,
425 msrs
, sizeof(*msrs
), &dSize
, (LPOVERLAPPED
) NULL
);
427 ret
= DeviceIoControl(hDeviceVCPU
,
428 HAX_VCPU_IOCTL_GET_MSRS
,
430 msrs
, sizeof(*msrs
), &dSize
, (LPOVERLAPPED
) NULL
);
439 int hax_sync_vcpu_state(CPUArchState
*env
, struct vcpu_state_t
*state
, int set
)
446 fd
= hax_vcpu_get_fd(env
);
447 if (hax_invalid_fd(fd
)) {
454 ret
= DeviceIoControl(hDeviceVCPU
,
456 state
, sizeof(*state
),
457 NULL
, 0, &dSize
, (LPOVERLAPPED
) NULL
);
459 ret
= DeviceIoControl(hDeviceVCPU
,
462 state
, sizeof(*state
), &dSize
,
463 (LPOVERLAPPED
) NULL
);
472 int hax_inject_interrupt(CPUArchState
*env
, int vector
)
479 fd
= hax_vcpu_get_fd(env
);
480 if (hax_invalid_fd(fd
)) {
486 ret
= DeviceIoControl(hDeviceVCPU
,
487 HAX_VCPU_IOCTL_INTERRUPT
,
488 &vector
, sizeof(vector
), NULL
, 0, &dSize
,
489 (LPOVERLAPPED
) NULL
);