Merge "hax: fix wrong printf format for target_ulong." into features/smp
[sdk/emulator/qemu.git] / target-i386 / hax-windows.c
1 /*
2  * QEMU HAXM support
3  *
4  * Copyright (c) 2011 Intel Corporation
5  *  Written by:
6  *  Jiang Yunhong<yunhong.jiang@intel.com>
7  *
8  * This work is licensed under the terms of the GNU GPL, version 2 or later.
9  *
10  */
11
12 #include "hax-i386.h"
13
14 /*
15  * return 0 when success, -1 when driver not loaded,
16  * other negative value for other failure
17  */
18 static int hax_open_device(hax_fd *fd)
19 {
20     uint32_t errNum = 0;
21     HANDLE hDevice;
22
23     if (!fd)
24         return -2;
25
26     hDevice = CreateFile( "\\\\.\\HAX",
27       GENERIC_READ | GENERIC_WRITE,
28       0,
29       NULL,
30       CREATE_ALWAYS,
31       FILE_ATTRIBUTE_NORMAL,
32       NULL);
33
34     if (hDevice == INVALID_HANDLE_VALUE)
35     {
36         dprint("Failed to open the HAX device!\n");
37         errNum = GetLastError();
38         if (errNum == ERROR_FILE_NOT_FOUND)
39             return -1;
40         return -2;
41     }
42     *fd = hDevice;
43     dprint("device fd:%d\n", *fd);
44     return 0;
45 }
46
47 /* This need changes after more investigation on driver loading*/
48 hax_fd hax_mod_open(void)
49 {
50     int ret;
51     hax_fd fd = NULL;
52
53     ret = hax_open_device(&fd);
54     if (ret != 0)
55         dprint("Open HAX device failed\n");
56
57     return fd;
58 }
59
60 int hax_populate_ram(uint64_t va, uint32_t size)
61 {
62     int ret;
63     struct hax_alloc_ram_info info;
64     HANDLE hDeviceVM;
65     DWORD dSize = 0;
66
67     if (!hax_global.vm || !hax_global.vm->fd)
68     {
69         dprint("Allocate memory before vm create?\n");
70         return -EINVAL;
71     }
72
73     info.size = size;
74     info.va = va;
75
76     hDeviceVM = hax_global.vm->fd;
77
78     ret = DeviceIoControl(hDeviceVM,
79       HAX_VM_IOCTL_ALLOC_RAM,
80       &info, sizeof(info),
81       NULL, 0,
82       &dSize,
83       (LPOVERLAPPED) NULL);
84
85     if (!ret) {
86         dprint("Failed to allocate %x memory\n", size);
87         return ret;
88     }
89
90     return 0;
91 }
92
93
94 /*
95  * much simpler than kvm, at least in first stage because:
96  * We don't need consider the device pass-through, we don't need
97  * consider the framebuffer, and we may even remove the bios at all
98  */
99
100 int hax_set_phys_mem(MemoryRegionSection *section)
101 {
102     struct hax_set_ram_info info, *pinfo = &info;
103     MemoryRegion *mr = section->mr;
104     hwaddr start_addr = section->offset_within_address_space;
105     ram_addr_t size = int128_get64(section->size);
106     HANDLE hDeviceVM;
107     DWORD dSize = 0;
108     int ret = 0;
109
110     /* We only care for the  RAM and ROM */
111     if (!memory_region_is_ram(mr)) {
112         return 0;
113     }
114
115     if ( (start_addr & ~TARGET_PAGE_MASK) || (size & ~TARGET_PAGE_MASK)) {
116         dprint(
117           "set_phys_mem %x %lx requires page aligned addr and size\n",
118           start_addr, size);
119         return -1;
120     }
121
122     info.pa_start = start_addr;
123     info.size = size;
124     info.va = (uint64_t)(intptr_t)(memory_region_get_ram_ptr(mr) +
125                 section->offset_within_region);
126     info.flags = memory_region_is_rom(mr) ? 1 : 0;
127
128     hDeviceVM = hax_global.vm->fd;
129
130     ret = DeviceIoControl(hDeviceVM,
131       HAX_VM_IOCTL_SET_RAM,
132       pinfo, sizeof(*pinfo),
133       NULL, 0,
134       &dSize,
135       (LPOVERLAPPED) NULL);
136
137     if (!ret)
138         return -EFAULT;
139     else
140         return 0;
141 }
142
143 int hax_capability(struct hax_state *hax, struct hax_capabilityinfo *cap)
144 {
145     int ret;
146     HANDLE hDevice = hax->fd;   //handle to hax module
147     DWORD dSize = 0;
148     DWORD err = 0;
149
150     if (hax_invalid_fd(hDevice)) {
151         dprint("Invalid fd for hax device!\n");
152         return -ENODEV;
153     }
154
155     ret = DeviceIoControl(hDevice,
156       HAX_IOCTL_CAPABILITY,
157       NULL, 0,
158       cap, sizeof(*cap),
159       &dSize,
160       (LPOVERLAPPED) NULL);
161
162     if (!ret) {
163         err = GetLastError();
164         if (err == ERROR_INSUFFICIENT_BUFFER ||
165             err == ERROR_MORE_DATA)
166             dprint("hax capability is too long to hold.\n");
167         dprint("Failed to get Hax capability:%d\n", err);
168         return -EFAULT;
169     } else
170         return 0;
171
172 }
173 int hax_mod_version(struct hax_state *hax, struct hax_module_version *version)
174 {
175     int ret;
176     HANDLE hDevice = hax->fd;   //handle to hax module
177     DWORD dSize = 0;
178     DWORD err = 0;
179
180     if (hax_invalid_fd(hDevice)) {
181         dprint("Invalid fd for hax device!\n");
182         return -ENODEV;
183     }
184
185     ret = DeviceIoControl(hDevice,
186       HAX_IOCTL_VERSION,
187       NULL, 0,
188       version, sizeof(*version),
189       &dSize,
190       (LPOVERLAPPED) NULL);
191
192     if (!ret) {
193         err = GetLastError();
194         if (err == ERROR_INSUFFICIENT_BUFFER ||
195             err == ERROR_MORE_DATA)
196             dprint("hax module verion is too long to hold.\n");
197         dprint("Failed to get Hax module version:%d\n", err);
198         return -EFAULT;
199     } else
200         return 0;
201 }
202
203 static char *hax_vm_devfs_string(int vm_id)
204 {
205     char *name;
206
207     if (vm_id > MAX_VM_ID)
208     {
209         dprint("Too big VM id\n");
210         return NULL;
211     }
212
213     name = g_strdup("\\\\.\\hax_vmxx");
214     if (!name)
215         return NULL;
216     sprintf(name, "\\\\.\\hax_vm%02d", vm_id);
217
218     return name;
219 }
220
221 static char *hax_vcpu_devfs_string(int vm_id, int vcpu_id)
222 {
223     char *name;
224
225     if (vm_id > MAX_VM_ID || vcpu_id > MAX_VCPU_ID)
226     {
227         dprint("Too big vm id %x or vcpu id %x\n", vm_id, vcpu_id);
228         return NULL;
229     }
230     name = g_strdup("\\\\.\\hax_vmxx_vcpuxx");
231     if (!name)
232         return NULL;
233     sprintf(name, "\\\\.\\hax_vm%02d_vcpu%02d", vm_id, vcpu_id);
234
235     return name;
236 }
237
238 int hax_host_create_vm(struct hax_state *hax, int *vmid)
239 {
240     int ret;
241     int vm_id = 0;
242     DWORD dSize = 0;
243
244     if (hax_invalid_fd(hax->fd))
245         return -EINVAL;
246
247     if (hax->vm)
248         return 0;
249
250     ret = DeviceIoControl(hax->fd,
251       HAX_IOCTL_CREATE_VM,
252       NULL, 0,
253       &vm_id, sizeof(vm_id),
254       &dSize,
255       (LPOVERLAPPED) NULL);
256     if (!ret) {
257         dprint("error code:%d", GetLastError());
258         return -1;
259     }
260     *vmid = vm_id;
261     return 0;
262 }
263
264 hax_fd hax_host_open_vm(struct hax_state *hax, int vm_id)
265 {
266     char *vm_name = NULL;
267     hax_fd hDeviceVM;
268
269     vm_name = hax_vm_devfs_string(vm_id);
270     if (!vm_name) {
271         dprint("Incorrect name\n");
272         return INVALID_HANDLE_VALUE;
273     }
274
275     hDeviceVM = CreateFile(vm_name,
276       GENERIC_READ | GENERIC_WRITE,
277       0,
278       NULL,
279       CREATE_ALWAYS,
280       FILE_ATTRIBUTE_NORMAL,
281       NULL);
282     if (hDeviceVM == INVALID_HANDLE_VALUE)
283         dprint("Open the vm devcie error:%s, ec:%d\n", vm_name, GetLastError());
284
285     g_free(vm_name);
286     return hDeviceVM;
287 }
288
289 int hax_notify_qemu_version(hax_fd vm_fd, struct hax_qemu_version *qversion)
290 {
291     int ret;
292     DWORD dSize = 0;
293     if (hax_invalid_fd(vm_fd))
294         return -EINVAL;
295     ret = DeviceIoControl(vm_fd,
296       HAX_VM_IOCTL_NOTIFY_QEMU_VERSION,
297       qversion, sizeof(struct hax_qemu_version),
298       NULL, 0,
299       &dSize,
300       (LPOVERLAPPED) NULL);
301     if (!ret)
302     {
303         dprint("Failed to notify qemu API version\n");
304         return -1;
305     }
306     return 0;
307 }
308
309 int hax_host_create_vcpu(hax_fd vm_fd, int vcpuid)
310 {
311     int ret;
312     DWORD dSize = 0;
313
314     ret = DeviceIoControl(vm_fd,
315       HAX_VM_IOCTL_VCPU_CREATE,
316       &vcpuid, sizeof(vcpuid),
317       NULL, 0,
318       &dSize,
319       (LPOVERLAPPED) NULL);
320     if (!ret)
321     {
322         dprint("Failed to create vcpu %x\n", vcpuid);
323         return -1;
324     }
325
326     return 0;
327 }
328
329 hax_fd hax_host_open_vcpu(int vmid, int vcpuid)
330 {
331     char *devfs_path = NULL;
332     hax_fd hDeviceVCPU;
333
334     devfs_path = hax_vcpu_devfs_string(vmid, vcpuid);
335     if (!devfs_path)
336     {
337         dprint("Failed to get the devfs\n");
338         return INVALID_HANDLE_VALUE;
339     }
340
341     hDeviceVCPU = CreateFile( devfs_path,
342       GENERIC_READ | GENERIC_WRITE,
343       0,
344       NULL,
345       CREATE_ALWAYS,
346       FILE_ATTRIBUTE_NORMAL,
347       NULL);
348
349     if (hDeviceVCPU == INVALID_HANDLE_VALUE)
350         dprint("Failed to open the vcpu devfs\n");
351     g_free(devfs_path);
352     return hDeviceVCPU;
353 }
354
355 int hax_host_setup_vcpu_channel(struct hax_vcpu_state *vcpu)
356 {
357     hax_fd hDeviceVCPU = vcpu->fd;
358     int ret;
359     struct hax_tunnel_info info;
360     DWORD dSize = 0;
361
362     ret = DeviceIoControl(hDeviceVCPU,
363       HAX_VCPU_IOCTL_SETUP_TUNNEL,
364       NULL, 0,
365       &info, sizeof(info),
366       &dSize,
367       (LPOVERLAPPED) NULL);
368     if (!ret)
369     {
370         dprint("Failed to setup the hax tunnel\n");
371         return -1;
372     }
373
374     if (!valid_hax_tunnel_size(info.size))
375     {
376         dprint("Invalid hax tunnel size %x\n", info.size);
377         ret = -EINVAL;
378         return ret;
379     }
380     vcpu->tunnel = (struct hax_tunnel *)(intptr_t)(info.va);
381     vcpu->iobuf = (unsigned char *)(intptr_t)(info.io_va);
382     return 0;
383 }
384
385 int hax_vcpu_run(struct hax_vcpu_state* vcpu)
386 {
387     int ret;
388     HANDLE hDeviceVCPU = vcpu->fd;
389     DWORD dSize = 0;
390
391     ret = DeviceIoControl(hDeviceVCPU,
392       HAX_VCPU_IOCTL_RUN,
393       NULL, 0,
394       NULL, 0,
395       &dSize,
396       (LPOVERLAPPED) NULL);
397     if (!ret)
398         return -EFAULT;
399     else
400         return 0;
401 }
402
403 int hax_sync_fpu(CPUArchState *env, struct fx_layout *fl, int set)
404 {
405     int ret;
406     hax_fd fd;
407     HANDLE hDeviceVCPU;
408     DWORD dSize = 0;
409
410     fd = hax_vcpu_get_fd(env);
411     if (hax_invalid_fd(fd))
412         return -1;
413
414     hDeviceVCPU = fd;
415
416     if (set)
417         ret = DeviceIoControl(hDeviceVCPU,
418           HAX_VCPU_IOCTL_SET_FPU,
419           fl, sizeof(*fl),
420           NULL, 0,
421           &dSize,
422           (LPOVERLAPPED) NULL);
423     else
424         ret = DeviceIoControl(hDeviceVCPU,
425           HAX_VCPU_IOCTL_GET_FPU,
426           NULL, 0,
427           fl, sizeof(*fl),
428           &dSize,
429           (LPOVERLAPPED) NULL);
430     if (!ret)
431         return -EFAULT;
432     else
433         return 0;
434 }
435
436 int hax_sync_msr(CPUArchState *env, struct hax_msr_data *msrs, int set)
437 {
438     int ret;
439     hax_fd fd;
440     HANDLE hDeviceVCPU;
441     DWORD dSize = 0;
442
443     fd = hax_vcpu_get_fd(env);
444     if (hax_invalid_fd(fd))
445         return -1;
446     hDeviceVCPU = fd;
447
448     if (set)
449         ret = DeviceIoControl(hDeviceVCPU,
450           HAX_VCPU_IOCTL_SET_MSRS,
451           msrs, sizeof(*msrs),
452           msrs, sizeof(*msrs),
453           &dSize,
454           (LPOVERLAPPED) NULL);
455     else
456         ret = DeviceIoControl(hDeviceVCPU,
457           HAX_VCPU_IOCTL_GET_MSRS,
458           msrs, sizeof(*msrs),
459           msrs, sizeof(*msrs),
460           &dSize,
461           (LPOVERLAPPED) NULL);
462     if (!ret)
463         return -EFAULT;
464     else
465         return 0;
466 }
467
468 int hax_sync_vcpu_state(CPUArchState *env, struct vcpu_state_t *state, int set)
469 {
470     int ret;
471     hax_fd fd;
472     HANDLE hDeviceVCPU;
473     DWORD dSize;
474
475     fd = hax_vcpu_get_fd(env);
476     if (hax_invalid_fd(fd))
477         return -1;
478
479     hDeviceVCPU = fd;
480
481     if (set)
482         ret = DeviceIoControl(hDeviceVCPU,
483           HAX_VCPU_SET_REGS,
484           state, sizeof(*state),
485           NULL, 0,
486           &dSize,
487           (LPOVERLAPPED) NULL);
488     else
489         ret = DeviceIoControl(hDeviceVCPU,
490           HAX_VCPU_GET_REGS,
491           NULL, 0,
492           state, sizeof(*state),
493           &dSize,
494           (LPOVERLAPPED) NULL);
495     if (!ret)
496         return -EFAULT;
497     else
498         return 0;
499 }
500
501 int hax_inject_interrupt(CPUArchState *env, int vector)
502 {
503     int ret;
504     hax_fd fd;
505     HANDLE hDeviceVCPU;
506     DWORD dSize;
507
508     fd = hax_vcpu_get_fd(env);
509     if (hax_invalid_fd(fd))
510         return -1;
511
512     hDeviceVCPU = fd;
513
514     ret = DeviceIoControl(hDeviceVCPU,
515       HAX_VCPU_IOCTL_INTERRUPT,
516       &vector, sizeof(vector),
517       NULL, 0,
518       &dSize,
519       (LPOVERLAPPED) NULL);
520     if (!ret)
521         return -EFAULT;
522     else
523         return 0;
524 }