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"
18 * return 0 when success, -1 when driver not loaded,
19 * other negative value for other failure
21 static int hax_open_device(hax_fd
*fd
)
30 hDevice
= CreateFile("\\\\.\\HAX",
31 GENERIC_READ
| GENERIC_WRITE
,
32 0, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
34 if (hDevice
== INVALID_HANDLE_VALUE
) {
35 fprintf(stderr
, "Failed to open the HAX device!\n");
36 errNum
= GetLastError();
37 if (errNum
== ERROR_FILE_NOT_FOUND
) {
46 /* hax_fd hax_mod_open */
47 hax_fd
hax_mod_open(void)
52 ret
= hax_open_device(&fd
);
54 fprintf(stderr
, "Open HAX device failed\n");
60 int hax_populate_ram(uint64_t va
, uint64_t size
)
66 if (!hax_global
.vm
|| !hax_global
.vm
->fd
) {
67 fprintf(stderr
, "Allocate memory before vm create?\n");
71 hDeviceVM
= hax_global
.vm
->fd
;
72 if (hax_global
.supports_64bit_ramblock
) {
73 struct hax_ramblock_info ramblock
= {
79 ret
= DeviceIoControl(hDeviceVM
,
80 HAX_VM_IOCTL_ADD_RAMBLOCK
,
81 &ramblock
, sizeof(ramblock
), NULL
, 0, &dSize
,
84 struct hax_alloc_ram_info info
= {
85 .size
= (uint32_t) size
,
90 ret
= DeviceIoControl(hDeviceVM
,
91 HAX_VM_IOCTL_ALLOC_RAM
,
92 &info
, sizeof(info
), NULL
, 0, &dSize
,
97 fprintf(stderr
, "Failed to register RAM block: va=0x%" PRIx64
98 ", size=0x%" PRIx64
", method=%s\n", va
, size
,
99 hax_global
.supports_64bit_ramblock
? "new" : "legacy");
106 int hax_set_ram(uint64_t start_pa
, uint32_t size
, uint64_t host_va
, int flags
)
108 struct hax_set_ram_info info
;
109 HANDLE hDeviceVM
= hax_global
.vm
->fd
;
113 info
.pa_start
= start_pa
;
116 info
.flags
= (uint8_t) flags
;
118 ret
= DeviceIoControl(hDeviceVM
, HAX_VM_IOCTL_SET_RAM
,
119 &info
, sizeof(info
), NULL
, 0, &dSize
,
120 (LPOVERLAPPED
) NULL
);
129 int hax_capability(struct hax_state
*hax
, struct hax_capabilityinfo
*cap
)
132 HANDLE hDevice
= hax
->fd
; /* handle to hax module */
136 if (hax_invalid_fd(hDevice
)) {
137 fprintf(stderr
, "Invalid fd for hax device!\n");
141 ret
= DeviceIoControl(hDevice
, HAX_IOCTL_CAPABILITY
, NULL
, 0, cap
,
142 sizeof(*cap
), &dSize
, (LPOVERLAPPED
) NULL
);
145 err
= GetLastError();
146 if (err
== ERROR_INSUFFICIENT_BUFFER
|| err
== ERROR_MORE_DATA
) {
147 fprintf(stderr
, "hax capability is too long to hold.\n");
149 fprintf(stderr
, "Failed to get Hax capability:%luu\n", err
);
156 int hax_mod_version(struct hax_state
*hax
, struct hax_module_version
*version
)
159 HANDLE hDevice
= hax
->fd
; /* handle to hax module */
163 if (hax_invalid_fd(hDevice
)) {
164 fprintf(stderr
, "Invalid fd for hax device!\n");
168 ret
= DeviceIoControl(hDevice
,
171 version
, sizeof(*version
), &dSize
,
172 (LPOVERLAPPED
) NULL
);
175 err
= GetLastError();
176 if (err
== ERROR_INSUFFICIENT_BUFFER
|| err
== ERROR_MORE_DATA
) {
177 fprintf(stderr
, "hax module verion is too long to hold.\n");
179 fprintf(stderr
, "Failed to get Hax module version:%lu\n", err
);
186 static char *hax_vm_devfs_string(int vm_id
)
190 if (vm_id
> MAX_VM_ID
) {
191 fprintf(stderr
, "Too big VM id\n");
195 #define HAX_VM_DEVFS "\\\\.\\hax_vmxx"
196 name
= g_strdup(HAX_VM_DEVFS
);
201 snprintf(name
, sizeof HAX_VM_DEVFS
, "\\\\.\\hax_vm%02d", vm_id
);
205 static char *hax_vcpu_devfs_string(int vm_id
, int vcpu_id
)
209 if (vm_id
> MAX_VM_ID
|| vcpu_id
> MAX_VCPU_ID
) {
210 fprintf(stderr
, "Too big vm id %x or vcpu id %x\n", vm_id
, vcpu_id
);
214 #define HAX_VCPU_DEVFS "\\\\.\\hax_vmxx_vcpuxx"
215 name
= g_strdup(HAX_VCPU_DEVFS
);
220 snprintf(name
, sizeof HAX_VCPU_DEVFS
, "\\\\.\\hax_vm%02d_vcpu%02d",
225 int hax_host_create_vm(struct hax_state
*hax
, int *vmid
)
231 if (hax_invalid_fd(hax
->fd
)) {
239 ret
= DeviceIoControl(hax
->fd
,
241 NULL
, 0, &vm_id
, sizeof(vm_id
), &dSize
,
242 (LPOVERLAPPED
) NULL
);
244 fprintf(stderr
, "Failed to create VM. Error code: %lu\n",
252 hax_fd
hax_host_open_vm(struct hax_state
*hax
, int vm_id
)
254 char *vm_name
= NULL
;
257 vm_name
= hax_vm_devfs_string(vm_id
);
259 fprintf(stderr
, "Failed to open VM. VM name is null\n");
260 return INVALID_HANDLE_VALUE
;
263 hDeviceVM
= CreateFile(vm_name
,
264 GENERIC_READ
| GENERIC_WRITE
,
265 0, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
266 if (hDeviceVM
== INVALID_HANDLE_VALUE
) {
267 fprintf(stderr
, "Open the vm device error:%s, ec:%lu\n",
268 vm_name
, GetLastError());
275 int hax_notify_qemu_version(hax_fd vm_fd
, struct hax_qemu_version
*qversion
)
279 if (hax_invalid_fd(vm_fd
)) {
282 ret
= DeviceIoControl(vm_fd
,
283 HAX_VM_IOCTL_NOTIFY_QEMU_VERSION
,
284 qversion
, sizeof(struct hax_qemu_version
),
285 NULL
, 0, &dSize
, (LPOVERLAPPED
) NULL
);
287 fprintf(stderr
, "Failed to notify qemu API version\n");
293 int hax_host_create_vcpu(hax_fd vm_fd
, int vcpuid
)
298 ret
= DeviceIoControl(vm_fd
,
299 HAX_VM_IOCTL_VCPU_CREATE
,
300 &vcpuid
, sizeof(vcpuid
), NULL
, 0, &dSize
,
301 (LPOVERLAPPED
) NULL
);
303 fprintf(stderr
, "Failed to create vcpu %x\n", vcpuid
);
310 hax_fd
hax_host_open_vcpu(int vmid
, int vcpuid
)
312 char *devfs_path
= NULL
;
315 devfs_path
= hax_vcpu_devfs_string(vmid
, vcpuid
);
317 fprintf(stderr
, "Failed to get the devfs\n");
318 return INVALID_HANDLE_VALUE
;
321 hDeviceVCPU
= CreateFile(devfs_path
,
322 GENERIC_READ
| GENERIC_WRITE
,
323 0, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
,
326 if (hDeviceVCPU
== INVALID_HANDLE_VALUE
) {
327 fprintf(stderr
, "Failed to open the vcpu devfs\n");
333 int hax_host_setup_vcpu_channel(struct hax_vcpu_state
*vcpu
)
335 hax_fd hDeviceVCPU
= vcpu
->fd
;
337 struct hax_tunnel_info info
;
340 ret
= DeviceIoControl(hDeviceVCPU
,
341 HAX_VCPU_IOCTL_SETUP_TUNNEL
,
342 NULL
, 0, &info
, sizeof(info
), &dSize
,
343 (LPOVERLAPPED
) NULL
);
345 fprintf(stderr
, "Failed to setup the hax tunnel\n");
349 if (!valid_hax_tunnel_size(info
.size
)) {
350 fprintf(stderr
, "Invalid hax tunnel size %x\n", info
.size
);
354 vcpu
->tunnel
= (struct hax_tunnel
*) (intptr_t) (info
.va
);
355 vcpu
->iobuf
= (unsigned char *) (intptr_t) (info
.io_va
);
359 int hax_vcpu_run(struct hax_vcpu_state
*vcpu
)
362 HANDLE hDeviceVCPU
= vcpu
->fd
;
365 ret
= DeviceIoControl(hDeviceVCPU
,
367 NULL
, 0, NULL
, 0, &dSize
, (LPOVERLAPPED
) NULL
);
375 int hax_sync_fpu(CPUArchState
*env
, struct fx_layout
*fl
, int set
)
382 fd
= hax_vcpu_get_fd(env
);
383 if (hax_invalid_fd(fd
)) {
390 ret
= DeviceIoControl(hDeviceVCPU
,
391 HAX_VCPU_IOCTL_SET_FPU
,
392 fl
, sizeof(*fl
), NULL
, 0, &dSize
,
393 (LPOVERLAPPED
) NULL
);
395 ret
= DeviceIoControl(hDeviceVCPU
,
396 HAX_VCPU_IOCTL_GET_FPU
,
397 NULL
, 0, fl
, sizeof(*fl
), &dSize
,
398 (LPOVERLAPPED
) NULL
);
407 int hax_sync_msr(CPUArchState
*env
, struct hax_msr_data
*msrs
, int set
)
414 fd
= hax_vcpu_get_fd(env
);
415 if (hax_invalid_fd(fd
)) {
421 ret
= DeviceIoControl(hDeviceVCPU
,
422 HAX_VCPU_IOCTL_SET_MSRS
,
424 msrs
, sizeof(*msrs
), &dSize
, (LPOVERLAPPED
) NULL
);
426 ret
= DeviceIoControl(hDeviceVCPU
,
427 HAX_VCPU_IOCTL_GET_MSRS
,
429 msrs
, sizeof(*msrs
), &dSize
, (LPOVERLAPPED
) NULL
);
438 int hax_sync_vcpu_state(CPUArchState
*env
, struct vcpu_state_t
*state
, int set
)
445 fd
= hax_vcpu_get_fd(env
);
446 if (hax_invalid_fd(fd
)) {
453 ret
= DeviceIoControl(hDeviceVCPU
,
455 state
, sizeof(*state
),
456 NULL
, 0, &dSize
, (LPOVERLAPPED
) NULL
);
458 ret
= DeviceIoControl(hDeviceVCPU
,
461 state
, sizeof(*state
), &dSize
,
462 (LPOVERLAPPED
) NULL
);
471 int hax_inject_interrupt(CPUArchState
*env
, int vector
)
478 fd
= hax_vcpu_get_fd(env
);
479 if (hax_invalid_fd(fd
)) {
485 ret
= DeviceIoControl(hDeviceVCPU
,
486 HAX_VCPU_IOCTL_INTERRUPT
,
487 &vector
, sizeof(vector
), NULL
, 0, &dSize
,
488 (LPOVERLAPPED
) NULL
);