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