1 /*
2 ** Copyright (c) 2011, Intel Corporation
3 **
4 ** This software is licensed under the terms of the GNU General Public
5 ** License version 2, as published by the Free Software Foundation, and
6 ** may be copied, distributed, and modified under those terms.
7 **
8 ** This program is distributed in the hope that it will be useful,
9 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
10 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 ** GNU General Public License for more details.
12 */
13
14 /*
15 * HAX common code for both Windows and Darwin
16 * Some portion of code from KVM is used in this file.
17 */
18
19 #include "target-i386/hax-i386.h"
20
21 #define HAX_EMUL_ONE 0x1
22 #define HAX_EMUL_REAL 0x2
23 #define HAX_EMUL_HLT 0x4
24 #define HAX_EMUL_EXITLOOP 0x5
25
26 #define HAX_EMULATE_STATE_MMIO 0x1
27 #define HAX_EMULATE_STATE_REAL 0x2
28 #define HAX_EMULATE_STATE_NONE 0x3
29 #define HAX_EMULATE_STATE_INITIAL 0x4
30
31 struct hax_state hax_global;
32
33 int hax_support = -1;
34
35 /* Called after hax_init */
hax_enabled()36 int hax_enabled()
37 {
38 return (!hax_disabled && hax_support);
39 }
40
41 /* Currently non-PG modes are emulated by QEMU */
hax_vcpu_emulation_mode(CPUState * env)42 int hax_vcpu_emulation_mode(CPUState *env)
43 {
44 return !(env->cr[0] & CR0_PG_MASK);
45 }
46
hax_prepare_emulation(CPUState * env)47 static int hax_prepare_emulation(CPUState *env)
48 {
49 /* Flush all emulation states */
50 tlb_flush(env, 1);
51 tb_flush(env);
52 /* Sync the vcpu state from hax kernel module */
53 hax_vcpu_sync_state(env, 0);
54 return 0;
55 }
56
57 /*
58 * Check whether to break the translation block loop
59 * Break tbloop after one MMIO emulation, or after finish emulation mode
60 */
hax_stop_tbloop(CPUState * env)61 static int hax_stop_tbloop(CPUState *env)
62 {
63 switch (env->hax_vcpu->emulation_state)
64 {
65 case HAX_EMULATE_STATE_MMIO:
66 return 1;
67 case HAX_EMULATE_STATE_INITIAL:
68 case HAX_EMULATE_STATE_REAL:
69 if (!hax_vcpu_emulation_mode(env))
70 return 1;
71 break;
72 default:
73 dprint("Invalid emulation state in hax_sto_tbloop state %x\n",
74 env->hax_vcpu->emulation_state);
75 break;
76 }
77
78 return 0;
79 }
80
hax_stop_emulation(CPUState * env)81 int hax_stop_emulation(CPUState *env)
82 {
83 if (hax_stop_tbloop(env))
84 {
85 env->hax_vcpu->emulation_state = HAX_EMULATE_STATE_NONE;
86 /*
87 * QEMU emulation changes vcpu state,
88 * Sync the vcpu state to HAX kernel module
89 */
90 hax_vcpu_sync_state(env, 1);
91 return 1;
92 }
93
94 return 0;
95 }
96
hax_stop_translate(CPUState * env)97 int hax_stop_translate(CPUState *env)
98 {
99 struct hax_vcpu_state *vstate;
100
101 vstate = env->hax_vcpu;
102 assert(vstate->emulation_state);
103 if (vstate->emulation_state == HAX_EMULATE_STATE_MMIO )
104 return 1;
105
106 return 0;
107 }
108
valid_hax_tunnel_size(uint16_t size)109 int valid_hax_tunnel_size(uint16_t size)
110 {
111 return size >= sizeof(struct hax_tunnel);
112 }
113
hax_vcpu_get_fd(CPUState * env)114 hax_fd hax_vcpu_get_fd(CPUState *env)
115 {
116 struct hax_vcpu_state *vcpu = env->hax_vcpu;
117 if (!vcpu)
118 return HAX_INVALID_FD;
119 return vcpu->fd;
120 }
121
122 /* Current version */
123 uint32_t hax_cur_version = 0x2;
124 /* Least HAX kernel version */
125 uint32_t hax_lest_version = 0x1;
126
hax_get_capability(struct hax_state * hax)127 static int hax_get_capability(struct hax_state *hax)
128 {
129 int ret;
130 struct hax_capabilityinfo capinfo, *cap = &capinfo;
131
132 ret = hax_capability(hax, cap);
133 if (ret)
134 return -ENOSYS;
135
136 if ( ((cap->wstatus & HAX_CAP_WORKSTATUS_MASK) ==
137 HAX_CAP_STATUS_NOTWORKING ))
138 {
139 if (cap->winfo & HAX_CAP_FAILREASON_VT)
140 dprint("VT feature is not enabled, HAXM not working.\n");
141 else if (cap->winfo & HAX_CAP_FAILREASON_NX)
142 dprint("NX feature is not enabled, HAXM not working.\n");
143 return -ENXIO;
144 }
145
146 if (cap->wstatus & HAX_CAP_MEMQUOTA)
147 {
148 if (cap->mem_quota < hax->mem_quota)
149 {
150 dprint("The memory needed by this VM exceeds the driver limit.\n");
151 return -ENOSPC;
152 }
153 }
154
155 return 0;
156 }
157
hax_version_support(struct hax_state * hax)158 static int hax_version_support(struct hax_state *hax)
159 {
160 int ret;
161 struct hax_module_version version;
162
163 ret = hax_mod_version(hax, &version);
164 if (ret < 0)
165 return 0;
166
167 if ( (hax_lest_version > version.cur_version) ||
168 (hax_cur_version < version.compat_version) )
169 return 0;
170
171 return 1;
172 }
173
hax_vcpu_create(int id)174 int hax_vcpu_create(int id)
175 {
176 struct hax_vcpu_state *vcpu = NULL;
177 int ret;
178
179 if (!hax_global.vm)
180 {
181 dprint("vcpu %x created failed, vm is null\n", id);
182 return -1;
183 }
184
185 if (hax_global.vm->vcpus[id])
186 {
187 dprint("vcpu %x allocated already\n", id);
188 return 0;
189 }
190
191 vcpu = qemu_malloc(sizeof(struct hax_vcpu_state));
192 if (!vcpu)
193 {
194 dprint("Failed to alloc vcpu state\n");
195 return -ENOMEM;
196 }
197
198 memset(vcpu, 0, sizeof(struct hax_vcpu_state));
199
200 ret = hax_host_create_vcpu(hax_global.vm->fd, id);
201 if (ret)
202 {
203 dprint("Failed to create vcpu %x\n", id);
204 goto error;
205 }
206
207 vcpu->fd = hax_host_open_vcpu(hax_global.vm->id, id);
208 if (hax_invalid_fd(vcpu->fd))
209 {
210 dprint("Failed to open the vcpu\n");
211 ret = -ENODEV;
212 goto error;
213 }
214
215 hax_global.vm->vcpus[id] = vcpu;
216
217 ret = hax_host_setup_vcpu_channel(vcpu);
218 if (ret)
219 {
220 dprint("Invalid HAX tunnel size \n");
221 ret = -EINVAL;
222 goto error;
223 }
224 return 0;
225
226 error:
227 /* vcpu and tunnel will be closed automatically */
228 if (vcpu && !hax_invalid_fd(vcpu->fd))
229 hax_close_fd(vcpu->fd);
230
231 hax_global.vm->vcpus[id] = NULL;
232 qemu_free(vcpu);
233 return -1;
234 }
235
hax_vcpu_destroy(CPUState * env)236 int hax_vcpu_destroy(CPUState *env)
237 {
238 struct hax_vcpu_state *vcpu = env->hax_vcpu;
239
240 if (!hax_global.vm)
241 {
242 dprint("vcpu %x destroy failed, vm is null\n", vcpu->vcpu_id);
243 return -1;
244 }
245
246 if (!vcpu)
247 return 0;
248
249 /*
250 * 1. The hax_tunnel is also destroyed at vcpu_destroy
251 * 2. hax_close_fd will require the HAX kernel module to free vcpu
252 */
253 hax_close_fd(vcpu->fd);
254 hax_global.vm->vcpus[vcpu->vcpu_id] = NULL;
255 qemu_free(vcpu);
256 return 0;
257 }
258
hax_init_vcpu(CPUState * env)259 int hax_init_vcpu(CPUState *env)
260 {
261 int ret;
262
263 ret = hax_vcpu_create(env->cpu_index);
264 if (ret < 0)
265 {
266 dprint("Failed to create HAX vcpu\n");
267 exit(-1);
268 }
269
270 env->hax_vcpu = hax_global.vm->vcpus[env->cpu_index];
271 env->hax_vcpu->emulation_state = HAX_EMULATE_STATE_INITIAL;
272
273 return ret;
274 }
275
hax_vm_create(struct hax_state * hax)276 struct hax_vm *hax_vm_create(struct hax_state *hax)
277 {
278 struct hax_vm *vm;
279 int vm_id = 0, ret;
280 char *vm_name = NULL;
281
282 if (hax_invalid_fd(hax->fd))
283 return NULL;
284
285 if (hax->vm)
286 return hax->vm;
287
288 vm = qemu_malloc(sizeof(struct hax_vm));
289 if (!vm)
290 return NULL;
291 memset(vm, 0, sizeof(struct hax_vm));
292 ret = hax_host_create_vm(hax, &vm_id);
293 if (ret) {
294 dprint("Failed to create vm %x\n", ret);
295 goto error;
296 }
297 vm->id = vm_id;
298 vm->fd = hax_host_open_vm(hax, vm_id);
299 if (hax_invalid_fd(vm->fd))
300 {
301 dprint("Open vm device error:%s\n", vm_name);
302 goto error;
303 }
304
305 hax->vm = vm;
306 return vm;
307
308 error:
309 qemu_free(vm);
310 hax->vm = NULL;
311 return NULL;
312 }
313
hax_vm_destroy(struct hax_vm * vm)314 int hax_vm_destroy(struct hax_vm *vm)
315 {
316 int i;
317
318 for (i = 0; i < HAX_MAX_VCPU; i++)
319 if (vm->vcpus[i])
320 {
321 dprint("VCPU should be cleaned before vm clean\n");
322 return -1;
323 }
324 hax_close_fd(vm->fd);
325 qemu_free(vm);
326 hax_global.vm = NULL;
327 return 0;
328 }
329
hax_set_ramsize(uint64_t ramsize)330 int hax_set_ramsize(uint64_t ramsize)
331 {
332 struct hax_state *hax = &hax_global;
333
334 memset(hax, 0, sizeof(struct hax_state));
335 hax->mem_quota = ram_size;
336
337 return 0;
338 }
339
hax_init(int smp_cpus)340 int hax_init(int smp_cpus)
341 {
342 struct hax_state *hax = NULL;
343 struct hax_qemu_version qversion;
344 int ret;
345
346 hax_support = 0;
347
348 hax = &hax_global;
349
350 hax->fd = hax_mod_open();
351 if (hax_invalid_fd(hax->fd))
352 {
353 hax->fd = 0;
354 ret = -ENODEV;
355 goto error;
356 }
357
358 ret = hax_get_capability(hax);
359 /* In case HAXM have no such capability support */
360 if (ret && (ret != -ENOSYS))
361 {
362 ret = -EINVAL;
363 goto error;
364 }
365
366 if (!hax_version_support(hax))
367 {
368 dprint("Incompatible HAX version. Qemu current version %x ", hax_cur_version );
369 dprint("requires least HAX version %x\n", hax_lest_version);
370 ret = -EINVAL;
371 goto error;
372 }
373
374 hax->vm = hax_vm_create(hax);
375 if (!hax->vm)
376 {
377 dprint("Failed to create HAX VM\n");
378 ret = -EINVAL;
379 goto error;
380 }
381
382 qversion.cur_version = hax_cur_version;
383 qversion.least_version = hax_lest_version;
384 hax_notify_qemu_version(hax->vm->fd, &qversion);
385 hax_support = 1;
386 qemu_register_reset( hax_reset_vcpu_state, 0, NULL);
387
388 return 0;
389 error:
390 if (hax->vm)
391 hax_vm_destroy(hax->vm);
392 if (hax->fd)
393 hax_mod_close(hax);
394
395 return ret;
396 }
397
hax_handle_fastmmio(CPUState * env,struct hax_fastmmio * hft)398 int hax_handle_fastmmio(CPUState *env, struct hax_fastmmio *hft)
399 {
400 uint64_t buf = 0;
401
402 /*
403 * With fast MMIO, QEMU need not sync vCPU state with HAXM
404 * driver because it will only invoke MMIO handler
405 * However, some MMIO operations utilize virtual address like qemu_pipe
406 * Thus we need to sync the CR0, CR3 and CR4 so that QEMU
407 * can translate the guest virtual address to guest physical
408 * address
409 */
410 env->cr[0] = hft->_cr0;
411 env->cr[2] = hft->_cr2;
412 env->cr[3] = hft->_cr3;
413 env->cr[4] = hft->_cr4;
414
415 buf = hft->value;
416 cpu_physical_memory_rw(hft->gpa, &buf, hft->size, hft->direction);
417 if (hft->direction == 0)
418 hft->value = buf;
419
420 return 0;
421 }
422
hax_handle_io(CPUState * env,uint32_t df,uint16_t port,int direction,int size,int count,void * buffer)423 int hax_handle_io(CPUState *env, uint32_t df, uint16_t port, int direction,
424 int size, int count, void *buffer)
425 {
426 uint8_t *ptr;
427 int i;
428
429 if (!df)
430 ptr = (uint8_t *)buffer;
431 else
432 ptr = buffer + size * count - size;
433 for (i = 0; i < count; i++)
434 {
435 if (direction == HAX_EXIT_IO_IN) {
436 switch (size) {
437 case 1:
438 stb_p(ptr, cpu_inb(port));
439 break;
440 case 2:
441 stw_p(ptr, cpu_inw(port));
442 break;
443 case 4:
444 stl_p(ptr, cpu_inl(port));
445 break;
446 }
447 } else {
448 switch (size) {
449 case 1:
450 cpu_outb(port, ldub_p(ptr));
451 break;
452 case 2:
453 cpu_outw(port, lduw_p(ptr));
454 break;
455 case 4:
456 cpu_outl(port, ldl_p(ptr));
457 break;
458 }
459 }
460 if (!df)
461 ptr += size;
462 else
463 ptr -= size;
464 }
465
466 return 0;
467 }
468
hax_vcpu_interrupt(CPUState * env)469 static int hax_vcpu_interrupt(CPUState *env)
470 {
471 struct hax_vcpu_state *vcpu = env->hax_vcpu;
472 struct hax_tunnel *ht = vcpu->tunnel;
473
474 /*
475 * Try to inject an interrupt if the guest can accept it
476 * Unlike KVM, the HAX kernel module checks the eflags, instead.
477 */
478 if (ht->ready_for_interrupt_injection &&
479 (env->interrupt_request & CPU_INTERRUPT_HARD))
480 {
481 int irq;
482
483 env->interrupt_request &= ~CPU_INTERRUPT_HARD;
484 irq = cpu_get_pic_interrupt(env);
485 if (irq >= 0) {
486 hax_inject_interrupt(env, irq);
487 }
488 }
489
490 /*
491 * If we have an interrupt pending but the guest is not ready to
492 * receive it, request an interrupt window exit. This will cause
493 * a return to userspace as soon as the guest is ready to receive
494 * an interrupt.
495 */
496 if ((env->interrupt_request & CPU_INTERRUPT_HARD))
497 ht->request_interrupt_window = 1;
498 else
499 ht->request_interrupt_window = 0;
500 return 0;
501 }
502
hax_raise_event(CPUState * env)503 void hax_raise_event(CPUState *env)
504 {
505 struct hax_vcpu_state *vcpu = env->hax_vcpu;
506
507 if (!vcpu)
508 return;
509 vcpu->tunnel->user_event_pending = 1;
510 }
511
512 /*
513 * Request the HAX kernel module to run the CPU for us until one of
514 * the following occurs:
515 * 1. Guest crashes or is shut down
516 * 2. We need QEMU's emulation like when the guest executes a MMIO
517 * instruction or guest enters emulation mode (non-PG mode)
518 * 3. Guest executes HLT
519 * 4. Qemu has Signal/event pending
520 * 5. An unknown VMX-exit happens
521 */
522 extern void qemu_system_reset_request(void);
hax_vcpu_hax_exec(CPUState * env)523 static int hax_vcpu_hax_exec(CPUState *env)
524 {
525 int ret = 0;
526 struct hax_vcpu_state *vcpu = env->hax_vcpu;
527 struct hax_tunnel *ht = vcpu->tunnel;
528
529 if (hax_vcpu_emulation_mode(env))
530 {
531 dprint("Trying to vcpu execute at eip:%lx\n", env->eip);
532 return HAX_EMUL_EXITLOOP;
533 }
534
535 do {
536 int hax_ret;
537
538 if (env->exit_request) {
539 ret = HAX_EMUL_EXITLOOP ;
540 break;
541 }
542
543 hax_vcpu_interrupt(env);
544
545 hax_ret = hax_vcpu_run(vcpu);
546
547 /* Simply continue the vcpu_run if system call interrupted */
548 if (hax_ret == -EINTR || hax_ret == -EAGAIN) {
549 dprint("io window interrupted\n");
550 continue;
551 }
552
553 if (hax_ret < 0)
554 {
555 dprint("vcpu run failed for vcpu %x\n", vcpu->vcpu_id);
556 abort();
557 }
558 switch (ht->_exit_status)
559 {
560 case HAX_EXIT_IO:
561 {
562 ret = hax_handle_io(env, ht->pio._df, ht->pio._port,
563 ht->pio._direction,
564 ht->pio._size, ht->pio._count, vcpu->iobuf);
565 }
566 break;
567 case HAX_EXIT_MMIO:
568 ret = HAX_EMUL_ONE;
569 break;
570 case HAX_EXIT_FAST_MMIO:
571 ret = hax_handle_fastmmio(env,
572 (struct hax_fastmmio *)vcpu->iobuf);
573 break;
574 case HAX_EXIT_REAL:
575 ret = HAX_EMUL_REAL;
576 break;
577 /* Guest state changed, currently only for shutdown */
578 case HAX_EXIT_STATECHANGE:
579 dprint("VCPU shutdown request\n");
580 qemu_system_reset_request();
581 hax_prepare_emulation(env);
582 cpu_dump_state(env, stderr, fprintf, 0);
583 ret = HAX_EMUL_EXITLOOP;
584 break;
585 case HAX_EXIT_UNKNOWN_VMEXIT:
586 dprint("Unknown VMX exit %x from guest\n", ht->_exit_reason);
587 qemu_system_reset_request();
588 hax_prepare_emulation(env);
589 cpu_dump_state(env, stderr, fprintf, 0);
590 ret = HAX_EMUL_EXITLOOP;
591 break;
592 case HAX_EXIT_HLT:
593 if (!(env->interrupt_request & CPU_INTERRUPT_HARD) &&
594 !(env->interrupt_request & CPU_INTERRUPT_NMI)) {
595 /* hlt instruction with interrupt disabled is shutdown */
596 env->eflags |= IF_MASK;
597 env->halted = 1;
598 env->exception_index = EXCP_HLT;
599 ret = HAX_EMUL_HLT;
600 }
601 break;
602 /* these situation will continue to hax module */
603 case HAX_EXIT_INTERRUPT:
604 case HAX_EXIT_PAUSED:
605 break;
606 default:
607 dprint("Unknow exit %x from hax\n", ht->_exit_status);
608 qemu_system_reset_request();
609 hax_prepare_emulation(env);
610 cpu_dump_state(env, stderr, fprintf, 0);
611 ret = HAX_EMUL_EXITLOOP;
612 break;
613 }
614 }while (!ret);
615
616 if (env->exit_request) {
617 env->exit_request = 0;
618 env->exception_index = EXCP_INTERRUPT;
619 }
620 return ret;
621 }
622
623 /*
624 * return 1 when need to emulate, 0 when need to exit loop
625 */
hax_vcpu_exec(CPUState * env)626 int hax_vcpu_exec(CPUState *env)
627 {
628 int next = 0, ret = 0;
629 struct hax_vcpu_state *vcpu;
630
631 if (env->hax_vcpu->emulation_state != HAX_EMULATE_STATE_NONE)
632 return 1;
633
634 vcpu = env->hax_vcpu;
635 next = hax_vcpu_hax_exec(env);
636 switch (next)
637 {
638 case HAX_EMUL_ONE:
639 ret = 1;
640 env->hax_vcpu->emulation_state = HAX_EMULATE_STATE_MMIO;
641 hax_prepare_emulation(env);
642 break;
643 case HAX_EMUL_REAL:
644 ret = 1;
645 env->hax_vcpu->emulation_state =
646 HAX_EMULATE_STATE_REAL;
647 hax_prepare_emulation(env);
648 break;
649 case HAX_EMUL_HLT:
650 case HAX_EMUL_EXITLOOP:
651 break;
652 default:
653 dprint("Unknown hax vcpu exec return %x\n", next);
654 abort();
655 }
656
657 return ret;
658 }
659
660 #define HAX_RAM_INFO_ROM 0x1
661
set_v8086_seg(struct segment_desc_t * lhs,const SegmentCache * rhs)662 static void set_v8086_seg(struct segment_desc_t *lhs, const SegmentCache *rhs)
663 {
664 memset(lhs, 0, sizeof(struct segment_desc_t ));
665 lhs->selector = rhs->selector;
666 lhs->base = rhs->base;
667 lhs->limit = rhs->limit;
668 lhs->type = 3;
669 lhs->present = 1;
670 lhs->dpl = 3;
671 lhs->operand_size = 0;
672 lhs->desc = 1;
673 lhs->long_mode = 0;
674 lhs->granularity = 0;
675 lhs->available = 0;
676 }
677
get_seg(SegmentCache * lhs,const struct segment_desc_t * rhs)678 static void get_seg(SegmentCache *lhs, const struct segment_desc_t *rhs)
679 {
680 lhs->selector = rhs->selector;
681 lhs->base = rhs->base;
682 lhs->limit = rhs->limit;
683 lhs->flags =
684 (rhs->type << DESC_TYPE_SHIFT)
685 | (rhs->present * DESC_P_MASK)
686 | (rhs->dpl << DESC_DPL_SHIFT)
687 | (rhs->operand_size << DESC_B_SHIFT)
688 | (rhs->desc * DESC_S_MASK)
689 | (rhs->long_mode << DESC_L_SHIFT)
690 | (rhs->granularity * DESC_G_MASK)
691 | (rhs->available * DESC_AVL_MASK);
692 }
693
set_seg(struct segment_desc_t * lhs,const SegmentCache * rhs)694 static void set_seg(struct segment_desc_t *lhs, const SegmentCache *rhs)
695 {
696 unsigned flags = rhs->flags;
697
698 memset(lhs, 0, sizeof(struct segment_desc_t));
699 lhs->selector = rhs->selector;
700 lhs->base = rhs->base;
701 lhs->limit = rhs->limit;
702 lhs->type = (flags >> DESC_TYPE_SHIFT) & 15;
703 lhs->present = (flags & DESC_P_MASK) != 0;
704 lhs->dpl = rhs->selector & 3;
705 lhs->operand_size = (flags >> DESC_B_SHIFT) & 1;
706 lhs->desc = (flags & DESC_S_MASK) != 0;
707 lhs->long_mode = (flags >> DESC_L_SHIFT) & 1;
708 lhs->granularity = (flags & DESC_G_MASK) != 0;
709 lhs->available = (flags & DESC_AVL_MASK) != 0;
710 }
711
hax_getput_reg(uint64_t * hax_reg,target_ulong * qemu_reg,int set)712 static void hax_getput_reg(uint64_t *hax_reg, target_ulong *qemu_reg, int set)
713 {
714 target_ulong reg = *hax_reg;
715
716 if (set)
717 *hax_reg = *qemu_reg;
718 else
719 *qemu_reg = reg;
720 }
721
722 /* The sregs has been synced with HAX kernel already before this call */
hax_get_segments(CPUState * env,struct vcpu_state_t * sregs)723 static int hax_get_segments(CPUState *env, struct vcpu_state_t *sregs)
724 {
725 get_seg(&env->segs[R_CS], &sregs->_cs);
726 get_seg(&env->segs[R_DS], &sregs->_ds);
727 get_seg(&env->segs[R_ES], &sregs->_es);
728 get_seg(&env->segs[R_FS], &sregs->_fs);
729 get_seg(&env->segs[R_GS], &sregs->_gs);
730 get_seg(&env->segs[R_SS], &sregs->_ss);
731
732 get_seg(&env->tr, &sregs->_tr);
733 get_seg(&env->ldt, &sregs->_ldt);
734 env->idt.limit = sregs->_idt.limit;
735 env->idt.base = sregs->_idt.base;
736 env->gdt.limit = sregs->_gdt.limit;
737 env->gdt.base = sregs->_gdt.base;
738 return 0;
739 }
740
hax_set_segments(CPUState * env,struct vcpu_state_t * sregs)741 static int hax_set_segments(CPUState *env, struct vcpu_state_t *sregs)
742 {
743 if ((env->eflags & VM_MASK)) {
744 set_v8086_seg(&sregs->_cs, &env->segs[R_CS]);
745 set_v8086_seg(&sregs->_ds, &env->segs[R_DS]);
746 set_v8086_seg(&sregs->_es, &env->segs[R_ES]);
747 set_v8086_seg(&sregs->_fs, &env->segs[R_FS]);
748 set_v8086_seg(&sregs->_gs, &env->segs[R_GS]);
749 set_v8086_seg(&sregs->_ss, &env->segs[R_SS]);
750 } else {
751 set_seg(&sregs->_cs, &env->segs[R_CS]);
752 set_seg(&sregs->_ds, &env->segs[R_DS]);
753 set_seg(&sregs->_es, &env->segs[R_ES]);
754 set_seg(&sregs->_fs, &env->segs[R_FS]);
755 set_seg(&sregs->_gs, &env->segs[R_GS]);
756 set_seg(&sregs->_ss, &env->segs[R_SS]);
757
758 if (env->cr[0] & CR0_PE_MASK) {
759 /* force ss cpl to cs cpl */
760 sregs->_ss.selector = (sregs->_ss.selector & ~3) |
761 (sregs->_cs.selector & 3);
762 sregs->_ss.dpl = sregs->_ss.selector & 3;
763 }
764 }
765
766 set_seg(&sregs->_tr, &env->tr);
767 set_seg(&sregs->_ldt, &env->ldt);
768 sregs->_idt.limit = env->idt.limit;
769 sregs->_idt.base = env->idt.base;
770 sregs->_gdt.limit = env->gdt.limit;
771 sregs->_gdt.base = env->gdt.base;
772 return 0;
773 }
774
775 /*
776 * After get the state from the kernel module, some
777 * qemu emulator state need be updated also
778 */
hax_setup_qemu_emulator(CPUState * env)779 static int hax_setup_qemu_emulator(CPUState *env)
780 {
781
782 #define HFLAG_COPY_MASK ~( \
783 HF_CPL_MASK | HF_PE_MASK | HF_MP_MASK | HF_EM_MASK | \
784 HF_TS_MASK | HF_TF_MASK | HF_VM_MASK | HF_IOPL_MASK | \
785 HF_OSFXSR_MASK | HF_LMA_MASK | HF_CS32_MASK | \
786 HF_SS32_MASK | HF_CS64_MASK | HF_ADDSEG_MASK)
787
788 uint32_t hflags;
789
790 hflags = (env->segs[R_CS].flags >> DESC_DPL_SHIFT) & HF_CPL_MASK;
791 hflags |= (env->cr[0] & CR0_PE_MASK) << (HF_PE_SHIFT - CR0_PE_SHIFT);
792 hflags |= (env->cr[0] << (HF_MP_SHIFT - CR0_MP_SHIFT)) &
793 (HF_MP_MASK | HF_EM_MASK | HF_TS_MASK);
794 hflags |= (env->eflags & (HF_TF_MASK | HF_VM_MASK | HF_IOPL_MASK));
795 hflags |= (env->cr[4] & CR4_OSFXSR_MASK) <<
796 (HF_OSFXSR_SHIFT - CR4_OSFXSR_SHIFT);
797
798 if (env->efer & MSR_EFER_LMA) {
799 hflags |= HF_LMA_MASK;
800 }
801
802 if ((hflags & HF_LMA_MASK) && (env->segs[R_CS].flags & DESC_L_MASK)) {
803 hflags |= HF_CS32_MASK | HF_SS32_MASK | HF_CS64_MASK;
804 } else {
805 hflags |= (env->segs[R_CS].flags & DESC_B_MASK) >>
806 (DESC_B_SHIFT - HF_CS32_SHIFT);
807 hflags |= (env->segs[R_SS].flags & DESC_B_MASK) >>
808 (DESC_B_SHIFT - HF_SS32_SHIFT);
809 if (!(env->cr[0] & CR0_PE_MASK) ||
810 (env->eflags & VM_MASK) ||
811 !(hflags & HF_CS32_MASK)) {
812 hflags |= HF_ADDSEG_MASK;
813 } else {
814 hflags |= ((env->segs[R_DS].base |
815 env->segs[R_ES].base |
816 env->segs[R_SS].base) != 0) <<
817 HF_ADDSEG_SHIFT;
818 }
819 }
820 env->hflags = (env->hflags & HFLAG_COPY_MASK) | hflags;
821 return 0;
822 }
823
hax_sync_vcpu_register(CPUState * env,int set)824 static int hax_sync_vcpu_register(CPUState *env, int set)
825 {
826 struct vcpu_state_t regs;
827 int ret;
828 memset(®s, 0, sizeof(struct vcpu_state_t));
829
830 if (!set)
831 {
832 ret = hax_sync_vcpu_state(env, ®s, 0);
833 if (ret < 0)
834 return -1;
835 }
836
837 /*generic register */
838 hax_getput_reg(®s._rax, &env->regs[R_EAX], set);
839 hax_getput_reg(®s._rbx, &env->regs[R_EBX], set);
840 hax_getput_reg(®s._rcx, &env->regs[R_ECX], set);
841 hax_getput_reg(®s._rdx, &env->regs[R_EDX], set);
842 hax_getput_reg(®s._rsi, &env->regs[R_ESI], set);
843 hax_getput_reg(®s._rdi, &env->regs[R_EDI], set);
844 hax_getput_reg(®s._rsp, &env->regs[R_ESP], set);
845 hax_getput_reg(®s._rbp, &env->regs[R_EBP], set);
846
847 hax_getput_reg(®s._rflags, &env->eflags, set);
848 hax_getput_reg(®s._rip, &env->eip, set);
849
850 if (set)
851 {
852
853 regs._cr0 = env->cr[0];
854 regs._cr2 = env->cr[2];
855 regs._cr3 = env->cr[3];
856 regs._cr4 = env->cr[4];
857 hax_set_segments(env, ®s);
858 }
859 else
860 {
861 env->cr[0] = regs._cr0;
862 env->cr[2] = regs._cr2;
863 env->cr[3] = regs._cr3;
864 env->cr[4] = regs._cr4;
865 hax_get_segments(env, ®s);
866 }
867
868 if (set)
869 {
870 ret = hax_sync_vcpu_state(env, ®s, 1);
871 if (ret < 0)
872 return -1;
873 }
874 if (!set)
875 hax_setup_qemu_emulator(env);
876 return 0;
877 }
878
hax_msr_entry_set(struct vmx_msr * item,uint32_t index,uint64_t value)879 static void hax_msr_entry_set(struct vmx_msr *item,
880 uint32_t index, uint64_t value)
881 {
882 item->entry = index;
883 item->value = value;
884 }
885
hax_get_msrs(CPUState * env)886 static int hax_get_msrs(CPUState *env)
887 {
888 struct hax_msr_data md;
889 struct vmx_msr *msrs = md.entries;
890 int ret, i, n;
891
892 n = 0;
893 msrs[n++].entry = MSR_IA32_SYSENTER_CS;
894 msrs[n++].entry = MSR_IA32_SYSENTER_ESP;
895 msrs[n++].entry = MSR_IA32_SYSENTER_EIP;
896 msrs[n++].entry = MSR_IA32_TSC;
897 md.nr_msr = n;
898 ret = hax_sync_msr(env, &md, 0);
899 if (ret < 0)
900 return ret;
901
902 for (i = 0; i < md.done; i++) {
903 switch (msrs[i].entry) {
904 case MSR_IA32_SYSENTER_CS:
905 env->sysenter_cs = msrs[i].value;
906 break;
907 case MSR_IA32_SYSENTER_ESP:
908 env->sysenter_esp = msrs[i].value;
909 break;
910 case MSR_IA32_SYSENTER_EIP:
911 env->sysenter_eip = msrs[i].value;
912 break;
913 case MSR_IA32_TSC:
914 env->tsc = msrs[i].value;
915 break;
916 }
917 }
918
919 return 0;
920 }
921
hax_set_msrs(CPUState * env)922 static int hax_set_msrs(CPUState *env)
923 {
924 struct hax_msr_data md;
925 struct vmx_msr *msrs;
926 msrs = md.entries;
927 int n = 0;
928
929 memset(&md, 0, sizeof(struct hax_msr_data));
930 hax_msr_entry_set(&msrs[n++], MSR_IA32_SYSENTER_CS, env->sysenter_cs);
931 hax_msr_entry_set(&msrs[n++], MSR_IA32_SYSENTER_ESP, env->sysenter_esp);
932 hax_msr_entry_set(&msrs[n++], MSR_IA32_SYSENTER_EIP, env->sysenter_eip);
933 hax_msr_entry_set(&msrs[n++], MSR_IA32_TSC, env->tsc);
934 md.nr_msr = n;
935 md.done = 0;
936
937 return hax_sync_msr(env, &md, 1);
938
939 }
940
hax_get_fpu(CPUState * env)941 static int hax_get_fpu(CPUState *env)
942 {
943 struct fx_layout fpu;
944 int i, ret;
945
946 ret = hax_sync_fpu(env, &fpu, 0);
947 if (ret < 0)
948 return ret;
949
950 env->fpstt = (fpu.fsw >> 11) & 7;
951 env->fpus = fpu.fsw;
952 env->fpuc = fpu.fcw;
953 for (i = 0; i < 8; ++i)
954 env->fptags[i] = !((fpu.ftw >> i) & 1);
955 memcpy(env->fpregs, fpu.st_mm, sizeof(env->fpregs));
956
957 memcpy(env->xmm_regs, fpu.mmx_1, sizeof(fpu.mmx_1));
958 memcpy((XMMReg *)(env->xmm_regs) + 8, fpu.mmx_2, sizeof(fpu.mmx_2));
959 env->mxcsr = fpu.mxcsr;
960
961 return 0;
962 }
963
hax_set_fpu(CPUState * env)964 static int hax_set_fpu(CPUState *env)
965 {
966 struct fx_layout fpu;
967 int i;
968
969 memset(&fpu, 0, sizeof(fpu));
970 fpu.fsw = env->fpus & ~(7 << 11);
971 fpu.fsw |= (env->fpstt & 7) << 11;
972 fpu.fcw = env->fpuc;
973
974 for (i = 0; i < 8; ++i)
975 fpu.ftw |= (!env->fptags[i]) << i;
976
977 memcpy(fpu.st_mm, env->fpregs, sizeof (env->fpregs));
978 memcpy(fpu.mmx_1, env->xmm_regs, sizeof (fpu.mmx_1));
979 memcpy(fpu.mmx_2, (XMMReg *)(env->xmm_regs) + 8, sizeof (fpu.mmx_2));
980
981 fpu.mxcsr = env->mxcsr;
982
983 return hax_sync_fpu(env, &fpu, 1);
984 }
985
hax_arch_get_registers(CPUState * env)986 int hax_arch_get_registers(CPUState *env)
987 {
988 int ret;
989
990 ret = hax_sync_vcpu_register(env, 0);
991 if (ret < 0)
992 return ret;
993
994 ret = hax_get_fpu(env);
995 if (ret < 0)
996 return ret;
997
998 ret = hax_get_msrs(env);
999 if (ret < 0)
1000 return ret;
1001
1002 return 0;
1003 }
1004
hax_arch_set_registers(CPUState * env)1005 static int hax_arch_set_registers(CPUState *env)
1006 {
1007 int ret;
1008 ret = hax_sync_vcpu_register(env, 1);
1009
1010 if (ret < 0)
1011 {
1012 dprint("Failed to sync vcpu reg\n");
1013 return ret;
1014 }
1015 ret = hax_set_fpu(env);
1016 if (ret < 0)
1017 {
1018 dprint("FPU failed\n");
1019 return ret;
1020 }
1021 ret = hax_set_msrs(env);
1022 if (ret < 0)
1023 {
1024 dprint("MSR failed\n");
1025 return ret;
1026 }
1027
1028 return 0;
1029 }
1030
hax_vcpu_sync_state(CPUState * env,int modified)1031 void hax_vcpu_sync_state(CPUState *env, int modified)
1032 {
1033 if (hax_enabled()) {
1034 if (modified)
1035 hax_arch_set_registers(env);
1036 else
1037 hax_arch_get_registers(env);
1038 }
1039 }
1040
1041 /*
1042 * This is simpler than the one for KVM because we don't support
1043 * direct I/O device assignment at this point.
1044 */
hax_sync_vcpus(void)1045 int hax_sync_vcpus(void)
1046 {
1047 if (hax_enabled())
1048 {
1049 CPUState *env;
1050
1051 env = first_cpu;
1052 if (!env)
1053 return 0;
1054
1055 for (; env != NULL; env = env->next_cpu) {
1056 int ret;
1057
1058 ret = hax_arch_set_registers(env);
1059 if (ret < 0)
1060 {
1061 dprint("Failed to sync HAX vcpu context\n");
1062 exit(1);
1063 }
1064 }
1065 }
1066
1067 return 0;
1068 }
1069
hax_reset_vcpu_state(void * opaque)1070 void hax_reset_vcpu_state(void *opaque)
1071 {
1072 CPUState *env;
1073 for (env = first_cpu; env != NULL; env = env->next_cpu)
1074 {
1075 if (env->hax_vcpu)
1076 {
1077 env->hax_vcpu->emulation_state = HAX_EMULATE_STATE_INITIAL;
1078 env->hax_vcpu->tunnel->user_event_pending = 0;
1079 env->hax_vcpu->tunnel->ready_for_interrupt_injection = 0;
1080 }
1081 }
1082 }
1083