af4bb50263a7d6664abfb6480e725cf377b520ba
[sdk/emulator/qemu.git] / target-i386 / hax-all.c
1 /*
2  * QEMU KVM support
3  *
4  * Copyright IBM, Corp. 2008
5  *           Red Hat, Inc. 2008
6  *
7  * Authors:
8  *  Anthony Liguori   <aliguori@us.ibm.com>
9  *  Glauber Costa     <gcosta@redhat.com>
10  *
11  * Copyright (c) 2011 Intel Corporation
12  *  Written by:
13  *  Jiang Yunhong<yunhong.jiang@intel.com>
14  *  Xin Xiaohui<xiaohui.xin@intel.com>
15  *  Zhang Xiantao<xiantao.zhang@intel.com>
16  *
17  * This work is licensed under the terms of the GNU GPL, version 2 or later.
18  * See the COPYING file in the top-level directory.
19  *
20  */
21
22 /*
23  * HAX common code for both windows and darwin
24  * some code from KVM side
25  */
26
27 #include "strings.h"
28 #include "hax-i386.h"
29 #include "sysemu/kvm.h"
30 #include "exec/address-spaces.h"
31 #include "qemu/main-loop.h"
32
33 #define HAX_EMUL_ONE    0x1
34 #define HAX_EMUL_REAL   0x2
35 #define HAX_EMUL_HLT    0x4
36 #define HAX_EMUL_EXITLOOP    0x5
37
38 #define HAX_EMULATE_STATE_MMIO  0x1
39 #define HAX_EMULATE_STATE_REAL  0x2
40 #define HAX_EMULATE_STATE_NONE  0x3
41 #define HAX_EMULATE_STATE_INITIAL       0x4
42
43 struct hax_state hax_global;
44 int ret_hax_init = 0;
45 static int hax_disabled = 1;
46
47 int hax_support = -1;
48
49 /* Called after hax_init */
50 int hax_enabled(void)
51 {
52     return (!hax_disabled && hax_support);
53 }
54
55 void hax_disable(int disable)
56 {
57     hax_disabled = disable;
58 }
59
60 /* Currently non-PG modes are emulated by QEMU */
61 int hax_vcpu_emulation_mode(CPUArchState *env)
62 {
63     // Tcg is single-thread, so we need haxm to run smp.
64     // If the host has no UG, we always run tcg.
65
66     if (hax_enabled())
67         return 0;
68     else
69         return 1;
70 }
71
72 static int hax_prepare_emulation(CPUArchState *env)
73 {
74     /* Flush all emulation states */
75     tlb_flush(ENV_GET_CPU(env), 1);
76     tb_flush(env);
77     /* Sync the vcpu state from hax kernel module */
78     hax_vcpu_sync_state(env, 0);
79     return 0;
80 }
81
82 /*
83  * Check whether to break the translation block loop
84  * break tbloop after one MMIO emulation, or after finish emulation mode
85  */
86 static int hax_stop_tbloop(CPUArchState *env)
87 {
88     CPUState *cpu = ENV_GET_CPU(env);
89     switch (cpu->hax_vcpu->emulation_state)
90     {
91     case HAX_EMULATE_STATE_MMIO:
92         if (cpu->hax_vcpu->resync) {
93             hax_prepare_emulation(env);     
94             cpu->hax_vcpu->resync = 0;
95             return 0;
96         }
97         return 1;
98         break;
99     case HAX_EMULATE_STATE_INITIAL:
100     case HAX_EMULATE_STATE_REAL:
101         if (!hax_vcpu_emulation_mode(env))
102             return 1;
103         break;
104     default:
105         dprint("Invalid emulation state in hax_sto_tbloop state %x\n",
106         cpu->hax_vcpu->emulation_state);
107         break;
108     }
109
110     return 0;
111 }
112
113 int hax_stop_emulation(CPUArchState *env)
114 {
115     CPUState *cpu = ENV_GET_CPU(env);
116     if (hax_stop_tbloop(env))
117     {
118         cpu->hax_vcpu->emulation_state =  HAX_EMULATE_STATE_NONE;
119         /*
120          * QEMU emulation changes vcpu state,
121          * Sync the vcpu state to HAX kernel module
122          */
123         hax_vcpu_sync_state(env, 1);
124         return 1;
125     }
126
127     return 0;
128 }
129
130 int hax_stop_translate(CPUArchState *env)
131 {
132     struct hax_vcpu_state *vstate;
133
134     vstate = ENV_GET_CPU(env)->hax_vcpu;
135     assert(vstate->emulation_state);
136     if (vstate->emulation_state == HAX_EMULATE_STATE_MMIO )
137         return 1;
138
139     return 0;
140 }
141
142 int valid_hax_tunnel_size(uint16_t size)
143 {
144     return size >= sizeof(struct hax_tunnel);
145 }
146
147 hax_fd hax_vcpu_get_fd(CPUArchState *env)
148 {
149     struct hax_vcpu_state *vcpu = ENV_GET_CPU(env)->hax_vcpu;
150     if (!vcpu)
151         return HAX_INVALID_FD;
152     return vcpu->fd;
153 }
154
155 /* Current version */
156 uint32_t hax_cur_version = 0x2; // ver 2.0: support fast mmio
157 /* Least HAX kernel version */
158 uint32_t hax_lest_version = 0x1;
159
160 static int hax_get_capability(struct hax_state *hax)
161 {
162     int ret;
163     struct hax_capabilityinfo capinfo, *cap = &capinfo;
164
165     ret = hax_capability(hax, cap);
166     if (ret)
167         return ret;
168
169     if ( ((cap->wstatus & HAX_CAP_WORKSTATUS_MASK) ==
170         HAX_CAP_STATUS_NOTWORKING ))
171     {
172         if (cap->winfo & HAX_CAP_FAILREASON_VT)
173             dprint("VTX feature is not enabled. which will cause HAX driver not working.\n");
174         else if (cap->winfo & HAX_CAP_FAILREASON_NX)
175             dprint("NX feature is not enabled, which will cause HAX driver not working.\n");
176         return -ENXIO;
177     }
178
179     if (!(cap->winfo & HAX_CAP_UG))
180     {
181         dprint("UG feature is not available on platform needed to support HAXM.\n");
182         return -ENXIO;
183     }
184
185     if (cap->wstatus & HAX_CAP_MEMQUOTA)
186     {
187         if (cap->mem_quota < hax->mem_quota)
188         {
189             dprint("The memory needed by this VM exceeds the driver limit.\n");
190             return -ENOSPC;
191         }
192     }
193     return 0;
194 }
195
196 static int hax_version_support(struct hax_state *hax)
197 {
198     int ret;
199     struct hax_module_version version;
200
201     ret = hax_mod_version(hax, &version);
202     if (ret < 0)
203         return 0;
204
205     if ( (hax_lest_version > version.cur_version) ||
206          (hax_cur_version < version.compat_version) )
207         return 0;
208
209     return 1;
210 }
211
212 int hax_vcpu_create(int id)
213 {
214     struct hax_vcpu_state *vcpu = NULL;
215     int ret;
216
217     if (!hax_global.vm)
218     {
219         dprint("vcpu %x created failed, vm is null\n", id);
220         return -1;
221     }
222
223     if (hax_global.vm->vcpus[id])
224     {
225         dprint("vcpu %x allocated already\n", id);
226         return 0;
227     }
228
229     vcpu = g_malloc(sizeof(struct hax_vcpu_state));
230     if (!vcpu)
231     {
232         dprint("Failed to alloc vcpu state\n");
233         return -ENOMEM;
234     }
235
236     memset(vcpu, 0, sizeof(struct hax_vcpu_state));
237
238     ret = hax_host_create_vcpu(hax_global.vm->fd, id);
239     if (ret)
240     {
241         dprint("Failed to create vcpu %x\n", id);
242         goto error;
243     }
244
245     vcpu->vcpu_id = id;
246     vcpu->fd = hax_host_open_vcpu(hax_global.vm->id, id);
247     if (hax_invalid_fd(vcpu->fd))
248     {
249         dprint("Failed to open the vcpu\n");
250         ret = -ENODEV;
251         goto error;
252     }
253
254     hax_global.vm->vcpus[id] = vcpu;
255
256     ret = hax_host_setup_vcpu_channel(vcpu);
257     if (ret)
258     {
259         dprint("Invalid hax tunnel size \n");
260         ret = -EINVAL;
261         goto error;
262     }
263     return 0;
264
265 error:
266     /* vcpu and tunnel will be closed automatically */
267     if (vcpu && !hax_invalid_fd(vcpu->fd))
268         hax_close_fd(vcpu->fd);
269
270     hax_global.vm->vcpus[id] = NULL;
271     g_free(vcpu);
272     return -1;
273 }
274
275 int hax_vcpu_destroy(CPUArchState *env)
276 {
277     struct hax_vcpu_state *vcpu = ENV_GET_CPU(env)->hax_vcpu;
278
279     if (!hax_global.vm)
280     {
281         dprint("vcpu %x destroy failed, vm is null\n", vcpu->vcpu_id);
282         return -1;
283     }
284
285     if (!vcpu)
286         return 0;
287
288     /*
289      * 1. The hax_tunnel is also destroied when vcpu destroy
290      * 2. close fd will cause hax module vcpu be cleaned
291      */
292     hax_close_fd(vcpu->fd);
293     hax_global.vm->vcpus[vcpu->vcpu_id] = NULL;
294     g_free(vcpu);
295     return 0;
296 }
297
298 int hax_init_vcpu(CPUArchState *env)
299 {
300     int ret;
301     CPUState *cpu = ENV_GET_CPU(env);
302
303     ret = hax_vcpu_create(cpu->cpu_index);
304     if (ret < 0)
305     {
306         dprint("Failed to create HAX vcpu\n");
307         exit(-1);
308     }
309
310     cpu->hax_vcpu = hax_global.vm->vcpus[cpu->cpu_index];
311     cpu->hax_vcpu->emulation_state = HAX_EMULATE_STATE_INITIAL;
312     cpu->hax_vcpu_dirty = 1;
313     qemu_register_reset(hax_reset_vcpu_state, env);
314
315     return ret;
316 }
317
318 struct hax_vm *hax_vm_create(struct hax_state *hax)
319 {
320     struct hax_vm *vm;
321     int vm_id = 0, ret;
322     char *vm_name = NULL;
323
324     if (hax_invalid_fd(hax->fd))
325         return NULL;
326
327     if (hax->vm)
328         return hax->vm;
329
330     vm = g_malloc(sizeof(struct hax_vm));
331     if (!vm)
332         return NULL;
333     memset(vm, 0, sizeof(struct hax_vm));
334     ret = hax_host_create_vm(hax, &vm_id);
335     if (ret) {
336         dprint("Failed to create vm %x\n", ret);
337         goto error;
338     }
339     vm->id = vm_id;
340     vm->fd = hax_host_open_vm(hax, vm_id);
341     if (hax_invalid_fd(vm->fd))
342     {
343         dprint("Open the vm devcie error:%s\n", vm_name);
344         goto error;
345     }
346
347     hax->vm = vm;
348     dprint("End of VM create, id %d\n", vm->id);
349     return vm;
350
351 error:
352     g_free(vm);
353     hax->vm = NULL;
354     return NULL;
355 }
356
357 int hax_vm_destroy(struct hax_vm *vm)
358 {
359     int i;
360
361     for (i = 0; i < HAX_MAX_VCPU; i++)
362         if (vm->vcpus[i])
363         {
364             dprint("VCPU should be cleaned before vm clean\n");
365             return -1;
366         }
367     hax_close_fd(vm->fd);
368     g_free(vm);
369     hax_global.vm = NULL;
370     return 0;
371 }
372
373 static void
374 hax_region_add(MemoryListener *listener, MemoryRegionSection *section)
375 {
376     hax_set_phys_mem(section);
377 }
378
379 static void
380 hax_region_del(MemoryListener *listener, MemoryRegionSection *section)
381 {
382     hax_set_phys_mem(section);
383 }
384
385
386 /* currently we fake the dirty bitmap sync, always dirty */
387 // avoid implicit declaration warning on Windows
388 int ffsl(long value);
389 static void hax_log_sync(MemoryListener *listener, MemoryRegionSection *section)
390 {
391     MemoryRegion *mr = section->mr;
392     unsigned long c;
393     unsigned int len = ((int128_get64(section->size) / TARGET_PAGE_SIZE) + HOST_LONG_BITS - 1) /
394                         HOST_LONG_BITS;
395     unsigned long bitmap[len];
396     int i, j;
397
398     for (i = 0; i < len; i++) {
399         bitmap[i] = 1;
400         c = leul_to_cpu(bitmap[i]);
401         do {
402             j = ffsl(c) - 1;
403             c &= ~(1ul << j);
404             memory_region_set_dirty(mr, (i * HOST_LONG_BITS + j) *
405                 TARGET_PAGE_SIZE, TARGET_PAGE_SIZE);
406         } while (c != 0);
407     }
408 }
409
410 static void hax_log_global_start(struct MemoryListener *listener)
411 {
412 }
413
414 static void hax_log_global_stop(struct MemoryListener *listener)
415 {
416 }
417
418 static void hax_log_start(MemoryListener *listener,
419                            MemoryRegionSection *section)
420 {
421 }
422
423 static void hax_log_stop(MemoryListener *listener,
424                           MemoryRegionSection *section)
425 {
426 }
427
428 static void hax_begin(MemoryListener *listener)
429 {
430 }
431
432 static void hax_commit(MemoryListener *listener)
433 {
434 }
435
436 static void hax_region_nop(MemoryListener *listener,
437                         MemoryRegionSection *section)
438 {
439 }
440
441 static MemoryListener hax_memory_listener = {
442     .begin = hax_begin,
443     .commit = hax_commit,
444     .region_add = hax_region_add,
445     .region_del = hax_region_del,
446     .region_nop = hax_region_nop,
447     .log_start = hax_log_start,
448     .log_stop = hax_log_stop,
449     .log_sync = hax_log_sync,
450     .log_global_start = hax_log_global_start,
451     .log_global_stop = hax_log_global_stop,
452 };
453
454 static void hax_handle_interrupt(CPUState *cpu, int mask)
455 {
456     cpu->interrupt_request |= mask;
457
458     if (!qemu_cpu_is_self(cpu)) {
459         qemu_cpu_kick(cpu);
460     }
461 }
462
463 int hax_pre_init(uint64_t ram_size)
464 {
465     struct hax_state *hax = NULL;
466
467     dprint("hax_disabled %d\n", hax_disabled);
468     if (hax_disabled)
469         return 0;
470     hax = &hax_global;
471     memset(hax, 0, sizeof(struct hax_state));
472     hax->mem_quota = ram_size;
473     dprint("ram_size %lx\n", ram_size);
474
475     return 0;
476 }
477
478 static int hax_init(void)
479 {
480     struct hax_state *hax = NULL;
481     struct hax_qemu_version qversion;
482     int ret;
483
484     hax_support = 0;
485
486     hax = &hax_global;
487
488
489     hax->fd = hax_mod_open();
490     if (hax_invalid_fd(hax->fd))
491     {
492         hax->fd = 0;
493         ret = -ENODEV;
494         goto error;
495     }
496
497     ret = hax_get_capability(hax);
498
499     if (ret)
500     {
501         if (ret != -ENOSPC)
502             ret = -EINVAL;
503         goto error;
504     }
505
506     if (!hax_version_support(hax))
507     {
508         dprint("Incompat Hax version. Qemu current version %x ", hax_cur_version );
509         dprint("requires least HAX version %x\n", hax_lest_version);
510         ret = -EINVAL;
511         goto error;
512     }
513
514     hax->vm = hax_vm_create(hax);
515     if (!hax->vm)
516     {
517         dprint("Failed to create HAX VM\n");
518         ret = -EINVAL;
519         goto error;
520     }
521
522     memory_listener_register(&hax_memory_listener, &address_space_memory);
523
524     qversion.cur_version = hax_cur_version;
525     qversion.least_version = hax_lest_version;
526     hax_notify_qemu_version(hax->vm->fd, &qversion);
527     cpu_interrupt_handler = hax_handle_interrupt;
528     hax_support = 1;
529
530     return ret;
531 error:
532     if (hax->vm)
533         hax_vm_destroy(hax->vm);
534     if (hax->fd)
535         hax_mod_close(hax);
536
537     return ret;
538 }
539
540 int hax_accel_init(void)
541 {
542     if (hax_disabled) {
543         dprint("HAX is disabled and emulator runs in emulation mode.\n");
544         return 0;
545     }
546
547     ret_hax_init = hax_init();
548     if (ret_hax_init && (ret_hax_init != -ENOSPC)) {
549         dprint("No accelerator found.\n");
550         return ret_hax_init;
551     } else {
552         dprint("HAX is %s and emulator runs in %s mode.\n",
553         !ret_hax_init ? "working" : "not working",
554         !ret_hax_init ? "fast virt" : "emulation");
555         return 0;
556     }
557 }
558
559 int  hax_handle_fastmmio(CPUArchState *env, struct hax_fastmmio *hft)
560 {
561     uint64_t buf = 0;
562     /*
563      * With fast MMIO, QEMU need not sync vCPU state with HAXM
564      * driver because it will only invoke MMIO handler
565      * However, some MMIO operations utilize virtual address like qemu_pipe
566      * Thus we need to sync the CR0, CR3 and CR4 so that QEMU
567      * can translate the guest virtual address to guest physical
568      * address
569      */
570     env->cr[0] = hft->_cr0;
571     env->cr[2] = hft->_cr2;
572     env->cr[3] = hft->_cr3;
573     env->cr[4] = hft->_cr4;
574
575     buf = hft->value;
576
577     cpu_physical_memory_rw(hft->gpa, (uint8_t *)&buf, hft->size, hft->direction);
578     if (hft->direction == 0)
579         hft->value = buf;
580
581     return 0;
582 }
583
584 int hax_handle_io(CPUArchState *env, uint32_t df, uint16_t port, int direction,
585   int size, int count, void *buffer)
586 {
587     uint8_t *ptr;
588     int i;
589
590     if (!df)
591         ptr = (uint8_t *)buffer;
592     else
593         ptr = buffer + size * count - size;
594     for (i = 0; i < count; i++)
595     {
596         if (direction == HAX_EXIT_IO_IN) {
597             switch (size) {
598                 case 1:
599                     stb_p(ptr, cpu_inb(port));
600                     break;
601                 case 2:
602                     stw_p(ptr, cpu_inw(port));
603                     break;
604                 case 4:
605                     stl_p(ptr, cpu_inl(port));
606                     break;
607             }
608         } else {
609             switch (size) {
610                 case 1:
611                     cpu_outb(port, ldub_p(ptr));
612                     break;
613                 case 2:
614                     cpu_outw(port, lduw_p(ptr));
615                     break;
616                 case 4:
617                     cpu_outl(port, ldl_p(ptr));
618                     break;
619             }
620         }
621         if (!df)
622             ptr += size;
623         else
624             ptr -= size;
625     }
626
627     return 0;
628 }
629
630 static int hax_vcpu_interrupt(CPUArchState *env)
631 {
632     CPUState *cpu = ENV_GET_CPU(env);
633     struct hax_vcpu_state *vcpu = cpu->hax_vcpu;
634     struct hax_tunnel *ht = vcpu->tunnel;
635
636     /*
637      * Try to inject an interrupt if the guest can accept it
638      * Unlike KVM, HAX kernel check for the eflags, instead of qemu
639      */
640     if (ht->ready_for_interrupt_injection /*&&
641       (cpu->interrupt_request & CPU_INTERRUPT_HARD)*/)
642     {
643         int irq;
644
645         cpu->interrupt_request &= ~CPU_INTERRUPT_HARD;
646         irq = cpu_get_pic_interrupt(env);
647         if (irq >= 0) {
648             hax_inject_interrupt(env, irq);
649         }
650     }
651
652     /* If we have an interrupt but the guest is not ready to receive an
653      * interrupt, request an interrupt window exit.  This will
654      * cause a return to userspace as soon as the guest is ready to
655      * receive interrupts. */
656     if ((cpu->interrupt_request & CPU_INTERRUPT_HARD))
657         ht->request_interrupt_window = 1;
658     else
659         ht->request_interrupt_window = 0;
660     return 0;
661 }
662
663 void hax_raise_event(CPUArchState *env)
664 {
665     struct hax_vcpu_state *vcpu = ENV_GET_CPU(env)->hax_vcpu;
666
667     if (!vcpu)
668         return;
669     vcpu->tunnel->user_event_pending = 1;
670 }
671
672 /*
673  * Ask hax kernel module to run the CPU for us till:
674  * 1. Guest crash or shutdown
675  * 2. Need QEMU's emulation like guest execute MMIO instruction or guest
676  *    enter emulation mode (non-PG mode)
677  * 3. Guest execute HLT
678  * 4. Qemu have Signal/event pending
679  * 5. An unknown VMX exit happens
680  */
681 extern void qemu_system_reset_request(void);
682 static int hax_vcpu_hax_exec(CPUArchState *env)
683 {
684     int ret = 0;
685     CPUState *cpu = ENV_GET_CPU(env);
686     struct hax_vcpu_state *vcpu = cpu->hax_vcpu;
687     struct hax_tunnel *ht = vcpu->tunnel;
688
689     if (hax_vcpu_emulation_mode(env))
690     {
691         dprint("Trying to vcpu execute at eip:%lx\n", env->eip);
692         return  HAX_EMUL_EXITLOOP;
693     }
694
695     if (cpu->interrupt_request & CPU_INTERRUPT_INIT) {
696         fprintf(stderr, "\nhax_vcpu_hax_exec: handling INIT for %d \n", cpu->cpu_index);
697         do_cpu_init(cpu);
698         hax_vcpu_sync_state(env, 1);
699     }
700     if (cpu->interrupt_request & CPU_INTERRUPT_SIPI) {
701         fprintf(stderr, "hax_vcpu_hax_exec: handling SIPI for %d \n", cpu->cpu_index);
702         hax_vcpu_sync_state(env, 0);
703         do_cpu_sipi(cpu);
704         hax_vcpu_sync_state(env, 1);
705     }
706
707     //hax_cpu_synchronize_state(env);
708
709     do {
710         int hax_ret;
711
712         if (cpu->exit_request) {
713             ret = HAX_EMUL_EXITLOOP ;
714             break;
715         }
716
717 #if 0
718         if (env->hax_vcpu_dirty) {
719                 hax_vcpu_sync_state(env, 1);
720                 env->hax_vcpu_dirty = 0;
721         }
722 #endif
723
724         hax_vcpu_interrupt(env);
725         qemu_mutex_unlock_iothread();
726         hax_ret = hax_vcpu_run(vcpu);
727         qemu_mutex_lock_iothread();
728
729 #ifdef CONFIG_DARWIN
730         current_cpu = cpu;
731 #endif
732         /* Simply continue the vcpu_run if system call interrupted */
733         if (hax_ret == -EINTR || hax_ret == -EAGAIN) {
734             dprint("io window interrupted\n");
735             continue;
736         }
737
738         if (hax_ret < 0)
739         {
740             dprint("vcpu run failed for vcpu  %x\n", vcpu->vcpu_id);
741             abort();
742         }
743         switch (ht->_exit_status)
744         {
745             case HAX_EXIT_IO:
746                 {
747                       ret = hax_handle_io(env, ht->pio._df, ht->pio._port,
748                       ht->pio._direction,
749                       ht->pio._size, ht->pio._count, vcpu->iobuf);
750                 }
751                 break;
752             case HAX_EXIT_MMIO:
753                 ret = HAX_EMUL_ONE;
754                 break;
755             case HAX_EXIT_FAST_MMIO:
756                 ret = hax_handle_fastmmio(env,
757                         (struct hax_fastmmio *)vcpu->iobuf);
758                 break;
759             case HAX_EXIT_REAL:
760                 ret = HAX_EMUL_REAL;
761                 break;
762                 /* Guest state changed, currently only for shutdown */
763             case HAX_EXIT_STATECHANGE:
764                 dprint("VCPU shutdown request\n");
765                 qemu_system_reset_request();
766                 hax_prepare_emulation(env);
767                 cpu_dump_state(cpu, stderr, fprintf, 0);
768                 ret = HAX_EMUL_EXITLOOP;
769                 break;
770             case HAX_EXIT_UNKNOWN_VMEXIT:
771                 dprint("Unknown VMX exit %x from guest\n", ht->_exit_reason);
772                 qemu_system_reset_request();
773                 hax_prepare_emulation(env);
774                 cpu_dump_state(cpu, stderr, fprintf, 0);
775                 ret = HAX_EMUL_EXITLOOP;
776                 break;
777             case HAX_EXIT_HLT:
778                 if (!(cpu->interrupt_request & CPU_INTERRUPT_HARD) &&
779                   !(cpu->interrupt_request & CPU_INTERRUPT_NMI)) {
780                     /* hlt instruction with interrupt disabled is shutdown */
781                     env->eflags |= IF_MASK;
782                     cpu->halted = 1;
783                     cpu->exception_index = EXCP_HLT;
784                     ret = HAX_EMUL_HLT;
785                 }
786                 break;
787                 /* these situation will continue to hax module */
788             case HAX_EXIT_INTERRUPT:
789             case HAX_EXIT_PAUSED:
790                 break;
791             default:
792                 dprint("Unknow exit %x from hax\n", ht->_exit_status);
793                 qemu_system_reset_request();
794                 hax_prepare_emulation(env);
795                 cpu_dump_state(cpu, stderr, fprintf, 0);
796                 ret = HAX_EMUL_EXITLOOP;
797                 break;
798         }
799     }while (!ret);
800
801     if (cpu->exit_request) {
802         cpu->exit_request = 0;
803         cpu->exception_index = EXCP_INTERRUPT;
804     }
805     return ret;
806 }
807
808 #if 0
809 static void do_hax_cpu_synchronize_state(void *_env)
810 {
811     CPUArchState *env = _env;
812     CPUState *cpu = ENV_GET_CPU(env);
813     if (!cpu->hax_vcpu_dirty) {
814         hax_vcpu_sync_state(env, 0);
815         cpu->hax_vcpu_dirty = 1;
816     }
817 }
818
819 void hax_cpu_synchronize_state(CPUState *cpu)
820 {
821     if (!cpu->hax_vcpu_dirty) {
822         run_on_cpu(cpu, do_hax_cpu_synchronize_state, cpu);
823     }
824 }
825 #endif
826
827 void hax_cpu_synchronize_post_reset(CPUArchState *env)
828 {
829     hax_vcpu_sync_state(env, 1);
830     ENV_GET_CPU(env)->hax_vcpu_dirty = 0;
831 }
832
833 void hax_cpu_synchronize_post_init(CPUArchState *env)
834 {
835     hax_vcpu_sync_state(env, 1);
836     ENV_GET_CPU(env)->hax_vcpu_dirty = 0;
837 }
838
839 /*
840  * return 1 when need emulate, 0 when need exit loop
841  */
842 int hax_vcpu_exec(CPUArchState *env)
843 {
844     int next = 0, ret = 0;
845     struct hax_vcpu_state *vcpu;
846     CPUState *cpu = ENV_GET_CPU(env);
847
848     if (cpu->hax_vcpu->emulation_state != HAX_EMULATE_STATE_NONE)
849         return 1;
850
851     vcpu = cpu->hax_vcpu;
852     next = hax_vcpu_hax_exec(env);
853     switch (next)
854     {
855         case HAX_EMUL_ONE:
856             ret = 1;
857             vcpu->emulation_state = HAX_EMULATE_STATE_MMIO;
858             hax_prepare_emulation(env);
859             break;
860         case HAX_EMUL_REAL:
861             ret = 1;
862             vcpu->emulation_state =
863               HAX_EMULATE_STATE_REAL;
864             hax_prepare_emulation(env);
865             break;
866         case HAX_EMUL_HLT:
867         case HAX_EMUL_EXITLOOP:
868             break;
869         default:
870             dprint("Unknown hax vcpu exec return %x\n", next);
871             abort();
872     }
873
874     return ret;
875 }
876
877 int hax_smp_cpu_exec(CPUArchState *env)
878 {
879     CPUState *cpu = ENV_GET_CPU(env);
880     int why;
881     int ret;
882
883     while (1) {
884         if (cpu->exception_index >= EXCP_INTERRUPT) {
885             ret = cpu->exception_index;
886             cpu->exception_index = -1;
887             break;
888         }
889
890         why = hax_vcpu_hax_exec(env);
891
892         if ((why != HAX_EMUL_HLT) && (why != HAX_EMUL_EXITLOOP))
893         {
894             dprint("Unknown hax vcpu return %x\n", why);
895             abort();
896         }
897     }
898
899     return ret;
900 }
901
902 #define HAX_RAM_INFO_ROM 0x1
903
904 static void set_v8086_seg(struct segment_desc_t *lhs, const SegmentCache *rhs)
905 {
906     memset(lhs, 0, sizeof(struct segment_desc_t ));
907     lhs->selector = rhs->selector;
908     lhs->base = rhs->base;
909     lhs->limit = rhs->limit;
910     lhs->type = 3;
911     lhs->present = 1;
912     lhs->dpl = 3;
913     lhs->operand_size = 0;
914     lhs->desc = 1;
915     lhs->long_mode = 0;
916     lhs->granularity = 0;
917     lhs->available = 0;
918 }
919
920 static void get_seg(SegmentCache *lhs, const struct segment_desc_t *rhs)
921 {
922     lhs->selector = rhs->selector;
923     lhs->base = rhs->base;
924     lhs->limit = rhs->limit;
925     lhs->flags =
926       (rhs->type << DESC_TYPE_SHIFT)
927       | (rhs->present * DESC_P_MASK)
928       | (rhs->dpl << DESC_DPL_SHIFT)
929       | (rhs->operand_size << DESC_B_SHIFT)
930       | (rhs->desc * DESC_S_MASK)
931       | (rhs->long_mode << DESC_L_SHIFT)
932       | (rhs->granularity * DESC_G_MASK)
933       | (rhs->available * DESC_AVL_MASK);
934 }
935
936 static void set_seg(struct segment_desc_t *lhs, const SegmentCache *rhs)
937 {
938     unsigned flags = rhs->flags;
939
940     memset(lhs, 0, sizeof(struct segment_desc_t));
941     lhs->selector = rhs->selector;
942     lhs->base = rhs->base;
943     lhs->limit = rhs->limit;
944     lhs->type = (flags >> DESC_TYPE_SHIFT) & 15;
945     lhs->present = (flags & DESC_P_MASK) != 0;
946     lhs->dpl = rhs->selector & 3;
947     lhs->operand_size = (flags >> DESC_B_SHIFT) & 1;
948     lhs->desc = (flags & DESC_S_MASK) != 0;
949     lhs->long_mode = (flags >> DESC_L_SHIFT) & 1;
950     lhs->granularity = (flags & DESC_G_MASK) != 0;
951     lhs->available = (flags & DESC_AVL_MASK) != 0;
952 }
953
954 static void hax_getput_reg(uint64_t *hax_reg, target_ulong *qemu_reg, int set)
955 {
956     target_ulong reg = *hax_reg;
957
958     if (set)
959         *hax_reg = *qemu_reg;
960     else
961         *qemu_reg = reg;
962 }
963
964 /* The sregs has been synced with HAX kernel already before this call */
965 static int hax_get_segments(CPUArchState *env, struct vcpu_state_t *sregs)
966 {
967     get_seg(&env->segs[R_CS], &sregs->_cs);
968     get_seg(&env->segs[R_DS], &sregs->_ds);
969     get_seg(&env->segs[R_ES], &sregs->_es);
970     get_seg(&env->segs[R_FS], &sregs->_fs);
971     get_seg(&env->segs[R_GS], &sregs->_gs);
972     get_seg(&env->segs[R_SS], &sregs->_ss);
973
974     get_seg(&env->tr, &sregs->_tr);
975     get_seg(&env->ldt, &sregs->_ldt);
976     env->idt.limit = sregs->_idt.limit;
977     env->idt.base = sregs->_idt.base;
978     env->gdt.limit = sregs->_gdt.limit;
979     env->gdt.base = sregs->_gdt.base;
980     return 0;
981 }
982
983 static int hax_set_segments(CPUArchState *env, struct vcpu_state_t *sregs)
984 {
985     if ((env->eflags & VM_MASK)) {
986         set_v8086_seg(&sregs->_cs, &env->segs[R_CS]);
987         set_v8086_seg(&sregs->_ds, &env->segs[R_DS]);
988         set_v8086_seg(&sregs->_es, &env->segs[R_ES]);
989         set_v8086_seg(&sregs->_fs, &env->segs[R_FS]);
990         set_v8086_seg(&sregs->_gs, &env->segs[R_GS]);
991         set_v8086_seg(&sregs->_ss, &env->segs[R_SS]);
992     } else {
993         set_seg(&sregs->_cs, &env->segs[R_CS]);
994         set_seg(&sregs->_ds, &env->segs[R_DS]);
995         set_seg(&sregs->_es, &env->segs[R_ES]);
996         set_seg(&sregs->_fs, &env->segs[R_FS]);
997         set_seg(&sregs->_gs, &env->segs[R_GS]);
998         set_seg(&sregs->_ss, &env->segs[R_SS]);
999
1000         if (env->cr[0] & CR0_PE_MASK) {
1001             /* force ss cpl to cs cpl */
1002             sregs->_ss.selector = (sregs->_ss.selector & ~3) |
1003               (sregs->_cs.selector & 3);
1004             sregs->_ss.dpl = sregs->_ss.selector & 3;
1005         }
1006     }
1007
1008     set_seg(&sregs->_tr, &env->tr);
1009     set_seg(&sregs->_ldt, &env->ldt);
1010     sregs->_idt.limit = env->idt.limit;
1011     sregs->_idt.base = env->idt.base;
1012     sregs->_gdt.limit = env->gdt.limit;
1013     sregs->_gdt.base = env->gdt.base;
1014     return 0;
1015 }
1016
1017 /*
1018  * After get the state from the kernel module, some
1019  * qemu emulator state need be updated also
1020  */
1021 static int hax_setup_qemu_emulator(CPUArchState *env)
1022 {
1023
1024 #define HFLAG_COPY_MASK ~( \
1025   HF_CPL_MASK | HF_PE_MASK | HF_MP_MASK | HF_EM_MASK | \
1026   HF_TS_MASK | HF_TF_MASK | HF_VM_MASK | HF_IOPL_MASK | \
1027   HF_OSFXSR_MASK | HF_LMA_MASK | HF_CS32_MASK | \
1028   HF_SS32_MASK | HF_CS64_MASK | HF_ADDSEG_MASK)
1029
1030     uint32_t hflags;
1031
1032     hflags = (env->segs[R_CS].flags >> DESC_DPL_SHIFT) & HF_CPL_MASK;
1033     hflags |= (env->cr[0] & CR0_PE_MASK) << (HF_PE_SHIFT - CR0_PE_SHIFT);
1034     hflags |= (env->cr[0] << (HF_MP_SHIFT - CR0_MP_SHIFT)) &
1035       (HF_MP_MASK | HF_EM_MASK | HF_TS_MASK);
1036     hflags |= (env->eflags & (HF_TF_MASK | HF_VM_MASK | HF_IOPL_MASK));
1037     hflags |= (env->cr[4] & CR4_OSFXSR_MASK) <<
1038       (HF_OSFXSR_SHIFT - CR4_OSFXSR_SHIFT);
1039
1040     if (env->efer & MSR_EFER_LMA) {
1041         hflags |= HF_LMA_MASK;
1042     }
1043
1044     if ((hflags & HF_LMA_MASK) && (env->segs[R_CS].flags & DESC_L_MASK)) {
1045         hflags |= HF_CS32_MASK | HF_SS32_MASK | HF_CS64_MASK;
1046     } else {
1047         hflags |= (env->segs[R_CS].flags & DESC_B_MASK) >>
1048           (DESC_B_SHIFT - HF_CS32_SHIFT);
1049         hflags |= (env->segs[R_SS].flags & DESC_B_MASK) >>
1050           (DESC_B_SHIFT - HF_SS32_SHIFT);
1051         if (!(env->cr[0] & CR0_PE_MASK) ||
1052           (env->eflags & VM_MASK) ||
1053           !(hflags & HF_CS32_MASK)) {
1054             hflags |= HF_ADDSEG_MASK;
1055         } else {
1056             hflags |= ((env->segs[R_DS].base |
1057                   env->segs[R_ES].base |
1058                   env->segs[R_SS].base) != 0) <<
1059               HF_ADDSEG_SHIFT;
1060         }
1061     }
1062     env->hflags = (env->hflags & HFLAG_COPY_MASK) | hflags;
1063     return 0;
1064 }
1065
1066 static int hax_sync_vcpu_register(CPUArchState *env, int set)
1067 {
1068     struct vcpu_state_t regs;
1069     int ret;
1070     memset(&regs, 0, sizeof(struct vcpu_state_t));
1071
1072     if (!set)
1073     {
1074         ret = hax_sync_vcpu_state(env, &regs, 0);
1075         if (ret < 0)
1076             return -1;
1077     }
1078
1079     /*generic register */
1080     hax_getput_reg(&regs._rax, &env->regs[R_EAX], set);
1081     hax_getput_reg(&regs._rbx, &env->regs[R_EBX], set);
1082     hax_getput_reg(&regs._rcx, &env->regs[R_ECX], set);
1083     hax_getput_reg(&regs._rdx, &env->regs[R_EDX], set);
1084     hax_getput_reg(&regs._rsi, &env->regs[R_ESI], set);
1085     hax_getput_reg(&regs._rdi, &env->regs[R_EDI], set);
1086     hax_getput_reg(&regs._rsp, &env->regs[R_ESP], set);
1087     hax_getput_reg(&regs._rbp, &env->regs[R_EBP], set);
1088
1089     hax_getput_reg(&regs._rflags, &env->eflags, set);
1090     hax_getput_reg(&regs._rip, &env->eip, set);
1091
1092     if (set)
1093     {
1094
1095         regs._cr0 = env->cr[0];
1096         regs._cr2 = env->cr[2];
1097         regs._cr3 = env->cr[3];
1098         regs._cr4 = env->cr[4];
1099         hax_set_segments(env, &regs);
1100     }
1101     else
1102     {
1103         env->cr[0] = regs._cr0;
1104         env->cr[2] = regs._cr2;
1105         env->cr[3] = regs._cr3;
1106         env->cr[4] = regs._cr4;
1107         hax_get_segments(env, &regs);
1108     }
1109
1110     if (set)
1111     {
1112         ret = hax_sync_vcpu_state(env, &regs, 1);
1113         if (ret < 0)
1114             return -1;
1115     }
1116     if (!set)
1117         hax_setup_qemu_emulator(env);
1118     return 0;
1119 }
1120
1121 static void hax_msr_entry_set(struct vmx_msr *item,
1122   uint32_t index, uint64_t value)
1123 {
1124     item->entry = index;
1125     item->value = value;
1126 }
1127
1128 static int hax_get_msrs(CPUArchState *env)
1129 {
1130     struct hax_msr_data md;
1131     struct vmx_msr *msrs = md.entries;
1132     int ret, i, n;
1133
1134     n = 0;
1135     msrs[n++].entry = MSR_IA32_SYSENTER_CS;
1136     msrs[n++].entry = MSR_IA32_SYSENTER_ESP;
1137     msrs[n++].entry = MSR_IA32_SYSENTER_EIP;
1138     msrs[n++].entry = MSR_IA32_TSC;
1139     md.nr_msr = n;
1140     ret = hax_sync_msr(env, &md, 0);
1141     if (ret < 0)
1142         return ret;
1143
1144     for (i = 0; i < md.done; i++) {
1145         switch (msrs[i].entry) {
1146             case MSR_IA32_SYSENTER_CS:
1147                 env->sysenter_cs = msrs[i].value;
1148                 break;
1149             case MSR_IA32_SYSENTER_ESP:
1150                 env->sysenter_esp = msrs[i].value;
1151                 break;
1152             case MSR_IA32_SYSENTER_EIP:
1153                 env->sysenter_eip = msrs[i].value;
1154                 break;
1155             case MSR_IA32_TSC:
1156                 env->tsc = msrs[i].value;
1157                 break;
1158         }
1159     }
1160
1161     return 0;
1162 }
1163
1164 static int hax_set_msrs(CPUArchState *env)
1165 {
1166     struct hax_msr_data md;
1167     struct vmx_msr *msrs;
1168     msrs = md.entries;
1169     int n = 0;
1170
1171     memset(&md, 0, sizeof(struct hax_msr_data));
1172     hax_msr_entry_set(&msrs[n++], MSR_IA32_SYSENTER_CS, env->sysenter_cs);
1173     hax_msr_entry_set(&msrs[n++], MSR_IA32_SYSENTER_ESP, env->sysenter_esp);
1174     hax_msr_entry_set(&msrs[n++], MSR_IA32_SYSENTER_EIP, env->sysenter_eip);
1175     hax_msr_entry_set(&msrs[n++], MSR_IA32_TSC, env->tsc);
1176     md.nr_msr = n;
1177     md.done = 0;
1178
1179     return hax_sync_msr(env, &md, 1);
1180
1181 }
1182
1183 static int hax_get_fpu(CPUArchState *env)
1184 {
1185     struct fx_layout fpu;
1186     int i, ret;
1187
1188     ret = hax_sync_fpu(env, &fpu, 0);
1189     if (ret < 0)
1190         return ret;
1191
1192     env->fpstt = (fpu.fsw >> 11) & 7;
1193     env->fpus = fpu.fsw;
1194     env->fpuc = fpu.fcw;
1195     for (i = 0; i < 8; ++i)
1196         env->fptags[i] = !((fpu.ftw >> i) & 1);
1197     memcpy(env->fpregs, fpu.st_mm, sizeof(env->fpregs));
1198
1199     memcpy(env->xmm_regs, fpu.mmx_1, sizeof(fpu.mmx_1));
1200     memcpy((XMMReg *)(env->xmm_regs) + 8, fpu.mmx_2, sizeof(fpu.mmx_2));
1201     env->mxcsr = fpu.mxcsr;
1202
1203     return 0;
1204 }
1205
1206 static int hax_set_fpu(CPUArchState *env)
1207 {
1208     struct fx_layout fpu;
1209     int i;
1210
1211     memset(&fpu, 0, sizeof(fpu));
1212     fpu.fsw = env->fpus & ~(7 << 11);
1213     fpu.fsw |= (env->fpstt & 7) << 11;
1214     fpu.fcw = env->fpuc;
1215
1216     for (i = 0; i < 8; ++i)
1217         fpu.ftw |= (!env->fptags[i]) << i;
1218
1219     memcpy(fpu.st_mm, env->fpregs, sizeof (env->fpregs));
1220     memcpy(fpu.mmx_1, env->xmm_regs, sizeof (fpu.mmx_1));
1221     memcpy(fpu.mmx_2, (XMMReg *)(env->xmm_regs) + 8, sizeof (fpu.mmx_2));
1222
1223     fpu.mxcsr = env->mxcsr;
1224
1225     return hax_sync_fpu(env, &fpu, 1);
1226 }
1227
1228 int hax_arch_get_registers(CPUArchState *env)
1229 {
1230     int ret;
1231
1232     ret = hax_sync_vcpu_register(env, 0);
1233     if (ret < 0)
1234         return ret;
1235
1236     ret = hax_get_fpu(env);
1237     if (ret < 0)
1238         return ret;
1239
1240     ret = hax_get_msrs(env);
1241     if (ret < 0)
1242         return ret;
1243
1244     return 0;
1245 }
1246
1247 static int hax_arch_set_registers(CPUArchState *env)
1248 {
1249     int ret;
1250     ret = hax_sync_vcpu_register(env, 1);
1251
1252     if (ret < 0)
1253     {
1254         dprint("Failed to sync vcpu reg\n");
1255         return ret;
1256     }
1257     ret = hax_set_fpu(env);
1258     if (ret < 0)
1259     {
1260         dprint("FPU failed\n");
1261         return ret;
1262     }
1263     ret = hax_set_msrs(env);
1264     if (ret < 0)
1265     {
1266         dprint("MSR failed\n");
1267         return ret;
1268     }
1269
1270     return 0;
1271 }
1272
1273 void hax_vcpu_sync_state(CPUArchState *env, int modified)
1274 {
1275     if (hax_enabled()) {
1276         if (modified)
1277             hax_arch_set_registers(env);
1278         else
1279             hax_arch_get_registers(env);
1280     }
1281 }
1282
1283 /*
1284  * much simpler than kvm, at least in first stage because:
1285  * We don't need consider the device pass-through, we don't need
1286  * consider the framebuffer, and we may even remove the bios at all
1287  */
1288 int hax_sync_vcpus(void)
1289 {
1290     if (hax_enabled())
1291     {
1292         CPUState *cpu;
1293
1294         cpu = first_cpu;
1295         if (!cpu)
1296             return 0;
1297
1298         for (; cpu != NULL; cpu = CPU_NEXT(cpu)) {
1299             int ret;
1300
1301             ret = hax_arch_set_registers(cpu->env_ptr);
1302             if (ret < 0)
1303             {
1304                 dprint("Failed to sync HAX vcpu context\n");
1305                 exit(1);
1306             }
1307         }
1308     }
1309
1310     return 0;
1311 }
1312 void hax_reset_vcpu_state(void *opaque)
1313 {
1314     CPUState *cpu;
1315     for (cpu = first_cpu; cpu != NULL; cpu = CPU_NEXT(cpu))
1316     {
1317         dprint("*********ReSet hax_vcpu->emulation_state \n");
1318         cpu->hax_vcpu->emulation_state  = HAX_EMULATE_STATE_INITIAL;
1319         cpu->hax_vcpu->tunnel->user_event_pending = 0;
1320         cpu->hax_vcpu->tunnel->ready_for_interrupt_injection = 0;
1321     }
1322 }
1323