• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(&regs, 0, sizeof(struct vcpu_state_t));
829 
830     if (!set)
831     {
832         ret = hax_sync_vcpu_state(env, &regs, 0);
833         if (ret < 0)
834             return -1;
835     }
836 
837     /*generic register */
838     hax_getput_reg(&regs._rax, &env->regs[R_EAX], set);
839     hax_getput_reg(&regs._rbx, &env->regs[R_EBX], set);
840     hax_getput_reg(&regs._rcx, &env->regs[R_ECX], set);
841     hax_getput_reg(&regs._rdx, &env->regs[R_EDX], set);
842     hax_getput_reg(&regs._rsi, &env->regs[R_ESI], set);
843     hax_getput_reg(&regs._rdi, &env->regs[R_EDI], set);
844     hax_getput_reg(&regs._rsp, &env->regs[R_ESP], set);
845     hax_getput_reg(&regs._rbp, &env->regs[R_EBP], set);
846 
847     hax_getput_reg(&regs._rflags, &env->eflags, set);
848     hax_getput_reg(&regs._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, &regs);
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, &regs);
866     }
867 
868     if (set)
869     {
870         ret = hax_sync_vcpu_state(env, &regs, 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