4 * Copyright IBM, Corp. 2008
8 * Anthony Liguori <aliguori@us.ibm.com>
9 * Glauber Costa <gcosta@redhat.com>
11 * Copyright (c) 2011 Intel Corporation
13 * Jiang Yunhong<yunhong.jiang@intel.com>
14 * Xin Xiaohui<xiaohui.xin@intel.com>
15 * Zhang Xiantao<xiantao.zhang@intel.com>
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.
23 * HAX common code for both windows and darwin
26 #include "qemu/osdep.h"
28 #include "exec/address-spaces.h"
30 #include "qemu/accel.h"
31 #include "sysemu/reset.h"
32 #include "sysemu/runstate.h"
33 #include "hw/boards.h"
35 #include "hax-accel-ops.h"
39 #define DPRINTF(fmt, ...) \
42 fprintf(stdout, fmt, ## __VA_ARGS__); \
47 const uint32_t hax_cur_version
= 0x4; /* API v4: unmapping and MMIO moves */
48 /* Minimum HAX kernel version */
49 const uint32_t hax_min_version
= 0x4; /* API v4: supports unmapping */
53 struct hax_state hax_global
;
55 static void hax_vcpu_sync_state(CPUArchState
*env
, int modified
);
56 static int hax_arch_get_registers(CPUArchState
*env
);
58 int valid_hax_tunnel_size(uint16_t size
)
60 return size
>= sizeof(struct hax_tunnel
);
63 hax_fd
hax_vcpu_get_fd(CPUArchState
*env
)
65 struct hax_vcpu_state
*vcpu
= env_cpu(env
)->hax_vcpu
;
67 return HAX_INVALID_FD
;
72 static int hax_get_capability(struct hax_state
*hax
)
75 struct hax_capabilityinfo capinfo
, *cap
= &capinfo
;
77 ret
= hax_capability(hax
, cap
);
82 if ((cap
->wstatus
& HAX_CAP_WORKSTATUS_MASK
) == HAX_CAP_STATUS_NOTWORKING
) {
83 if (cap
->winfo
& HAX_CAP_FAILREASON_VT
) {
85 ("VTX feature is not enabled, HAX driver will not work.\n");
86 } else if (cap
->winfo
& HAX_CAP_FAILREASON_NX
) {
88 ("NX feature is not enabled, HAX driver will not work.\n");
94 if (!(cap
->winfo
& HAX_CAP_UG
)) {
95 fprintf(stderr
, "UG mode is not supported by the hardware.\n");
99 hax
->supports_64bit_ramblock
= !!(cap
->winfo
& HAX_CAP_64BIT_RAMBLOCK
);
101 if (cap
->wstatus
& HAX_CAP_MEMQUOTA
) {
102 if (cap
->mem_quota
< hax
->mem_quota
) {
103 fprintf(stderr
, "The VM memory needed exceeds the driver limit.\n");
110 static int hax_version_support(struct hax_state
*hax
)
113 struct hax_module_version version
;
115 ret
= hax_mod_version(hax
, &version
);
120 if (hax_min_version
> version
.cur_version
) {
121 fprintf(stderr
, "Incompatible HAX module version %d,",
122 version
.cur_version
);
123 fprintf(stderr
, "requires minimum version %d\n", hax_min_version
);
126 if (hax_cur_version
< version
.compat_version
) {
127 fprintf(stderr
, "Incompatible QEMU HAX API version %x,",
129 fprintf(stderr
, "requires minimum HAX API version %x\n",
130 version
.compat_version
);
137 int hax_vcpu_create(int id
)
139 struct hax_vcpu_state
*vcpu
= NULL
;
142 if (!hax_global
.vm
) {
143 fprintf(stderr
, "vcpu %x created failed, vm is null\n", id
);
147 if (hax_global
.vm
->vcpus
[id
]) {
148 fprintf(stderr
, "vcpu %x allocated already\n", id
);
152 vcpu
= g_new0(struct hax_vcpu_state
, 1);
154 ret
= hax_host_create_vcpu(hax_global
.vm
->fd
, id
);
156 fprintf(stderr
, "Failed to create vcpu %x\n", id
);
161 vcpu
->fd
= hax_host_open_vcpu(hax_global
.vm
->id
, id
);
162 if (hax_invalid_fd(vcpu
->fd
)) {
163 fprintf(stderr
, "Failed to open the vcpu\n");
168 hax_global
.vm
->vcpus
[id
] = vcpu
;
170 ret
= hax_host_setup_vcpu_channel(vcpu
);
172 fprintf(stderr
, "Invalid hax tunnel size\n");
179 /* vcpu and tunnel will be closed automatically */
180 if (vcpu
&& !hax_invalid_fd(vcpu
->fd
)) {
181 hax_close_fd(vcpu
->fd
);
184 hax_global
.vm
->vcpus
[id
] = NULL
;
189 int hax_vcpu_destroy(CPUState
*cpu
)
191 struct hax_vcpu_state
*vcpu
= cpu
->hax_vcpu
;
193 if (!hax_global
.vm
) {
194 fprintf(stderr
, "vcpu %x destroy failed, vm is null\n", vcpu
->vcpu_id
);
203 * 1. The hax_tunnel is also destroyed when vcpu is destroyed
204 * 2. close fd will cause hax module vcpu be cleaned
206 hax_close_fd(vcpu
->fd
);
207 hax_global
.vm
->vcpus
[vcpu
->vcpu_id
] = NULL
;
212 int hax_init_vcpu(CPUState
*cpu
)
216 ret
= hax_vcpu_create(cpu
->cpu_index
);
218 fprintf(stderr
, "Failed to create HAX vcpu\n");
222 cpu
->hax_vcpu
= hax_global
.vm
->vcpus
[cpu
->cpu_index
];
223 cpu
->vcpu_dirty
= true;
224 qemu_register_reset(hax_reset_vcpu_state
, cpu
->env_ptr
);
229 struct hax_vm
*hax_vm_create(struct hax_state
*hax
, int max_cpus
)
232 int vm_id
= 0, ret
, i
;
234 if (hax_invalid_fd(hax
->fd
)) {
242 if (max_cpus
> HAX_MAX_VCPU
) {
243 fprintf(stderr
, "Maximum VCPU number QEMU supported is %d\n", HAX_MAX_VCPU
);
247 vm
= g_new0(struct hax_vm
, 1);
249 ret
= hax_host_create_vm(hax
, &vm_id
);
251 fprintf(stderr
, "Failed to create vm %x\n", ret
);
255 vm
->fd
= hax_host_open_vm(hax
, vm_id
);
256 if (hax_invalid_fd(vm
->fd
)) {
257 fprintf(stderr
, "Failed to open vm %d\n", vm_id
);
261 vm
->numvcpus
= max_cpus
;
262 vm
->vcpus
= g_new0(struct hax_vcpu_state
*, vm
->numvcpus
);
263 for (i
= 0; i
< vm
->numvcpus
; i
++) {
276 int hax_vm_destroy(struct hax_vm
*vm
)
280 for (i
= 0; i
< vm
->numvcpus
; i
++)
282 fprintf(stderr
, "VCPU should be cleaned before vm clean\n");
285 hax_close_fd(vm
->fd
);
289 hax_global
.vm
= NULL
;
293 static int hax_init(ram_addr_t ram_size
, int max_cpus
)
295 struct hax_state
*hax
= NULL
;
296 struct hax_qemu_version qversion
;
301 memset(hax
, 0, sizeof(struct hax_state
));
302 hax
->mem_quota
= ram_size
;
304 hax
->fd
= hax_mod_open();
305 if (hax_invalid_fd(hax
->fd
)) {
311 ret
= hax_get_capability(hax
);
314 if (ret
!= -ENOSPC
) {
320 if (!hax_version_support(hax
)) {
325 hax
->vm
= hax_vm_create(hax
, max_cpus
);
327 fprintf(stderr
, "Failed to create HAX VM\n");
334 qversion
.cur_version
= hax_cur_version
;
335 qversion
.min_version
= hax_min_version
;
336 hax_notify_qemu_version(hax
->vm
->fd
, &qversion
);
341 hax_vm_destroy(hax
->vm
);
350 static int hax_accel_init(MachineState
*ms
)
352 int ret
= hax_init(ms
->ram_size
, (int)ms
->smp
.max_cpus
);
354 if (ret
&& (ret
!= -ENOSPC
)) {
355 fprintf(stderr
, "No accelerator found.\n");
357 fprintf(stdout
, "HAX is %s and emulator runs in %s mode.\n",
358 !ret
? "working" : "not working",
359 !ret
? "fast virt" : "emulation");
361 "NOTE: HAX is deprecated and will be removed in a future release.\n"
362 " Use 'whpx' (on Windows) or 'hvf' (on macOS) instead.\n");
367 static int hax_handle_fastmmio(CPUArchState
*env
, struct hax_fastmmio
*hft
)
369 if (hft
->direction
< 2) {
370 cpu_physical_memory_rw(hft
->gpa
, &hft
->value
, hft
->size
,
374 * HAX API v4 supports transferring data between two MMIO addresses,
375 * hft->gpa and hft->gpa2 (instructions such as MOVS require this):
376 * hft->direction == 2: gpa ==> gpa2
379 cpu_physical_memory_read(hft
->gpa
, &value
, hft
->size
);
380 cpu_physical_memory_write(hft
->gpa2
, &value
, hft
->size
);
386 static int hax_handle_io(CPUArchState
*env
, uint32_t df
, uint16_t port
,
387 int direction
, int size
, int count
, void *buffer
)
391 MemTxAttrs attrs
= { 0 };
396 ptr
= buffer
+ size
* count
- size
;
398 for (i
= 0; i
< count
; i
++) {
399 address_space_rw(&address_space_io
, port
, attrs
,
400 ptr
, size
, direction
== HAX_EXIT_IO_OUT
);
411 static int hax_vcpu_interrupt(CPUArchState
*env
)
413 CPUState
*cpu
= env_cpu(env
);
414 struct hax_vcpu_state
*vcpu
= cpu
->hax_vcpu
;
415 struct hax_tunnel
*ht
= vcpu
->tunnel
;
418 * Try to inject an interrupt if the guest can accept it
419 * Unlike KVM, HAX kernel check for the eflags, instead of qemu
421 if (ht
->ready_for_interrupt_injection
&&
422 (cpu
->interrupt_request
& CPU_INTERRUPT_HARD
)) {
425 irq
= cpu_get_pic_interrupt(env
);
427 hax_inject_interrupt(env
, irq
);
428 cpu
->interrupt_request
&= ~CPU_INTERRUPT_HARD
;
432 /* If we have an interrupt but the guest is not ready to receive an
433 * interrupt, request an interrupt window exit. This will
434 * cause a return to userspace as soon as the guest is ready to
435 * receive interrupts. */
436 if ((cpu
->interrupt_request
& CPU_INTERRUPT_HARD
)) {
437 ht
->request_interrupt_window
= 1;
439 ht
->request_interrupt_window
= 0;
444 void hax_raise_event(CPUState
*cpu
)
446 struct hax_vcpu_state
*vcpu
= cpu
->hax_vcpu
;
451 vcpu
->tunnel
->user_event_pending
= 1;
455 * Ask hax kernel module to run the CPU for us till:
456 * 1. Guest crash or shutdown
457 * 2. Need QEMU's emulation like guest execute MMIO instruction
458 * 3. Guest execute HLT
459 * 4. QEMU have Signal/event pending
460 * 5. An unknown VMX exit happens
462 static int hax_vcpu_hax_exec(CPUArchState
*env
)
465 CPUState
*cpu
= env_cpu(env
);
466 X86CPU
*x86_cpu
= X86_CPU(cpu
);
467 struct hax_vcpu_state
*vcpu
= cpu
->hax_vcpu
;
468 struct hax_tunnel
*ht
= vcpu
->tunnel
;
470 if (!hax_enabled()) {
471 DPRINTF("Trying to vcpu execute at eip:" TARGET_FMT_lx
"\n", env
->eip
);
475 if (cpu
->interrupt_request
& CPU_INTERRUPT_POLL
) {
476 cpu
->interrupt_request
&= ~CPU_INTERRUPT_POLL
;
477 apic_poll_irq(x86_cpu
->apic_state
);
480 /* After a vcpu is halted (either because it is an AP and has just been
481 * reset, or because it has executed the HLT instruction), it will not be
482 * run (hax_vcpu_run()) until it is unhalted. The next few if blocks check
483 * for events that may change the halted state of this vcpu:
484 * a) Maskable interrupt, when RFLAGS.IF is 1;
485 * Note: env->eflags may not reflect the current RFLAGS state, because
486 * it is not updated after each hax_vcpu_run(). We cannot afford
487 * to fail to recognize any unhalt-by-maskable-interrupt event
488 * (in which case the vcpu will halt forever), and yet we cannot
489 * afford the overhead of hax_vcpu_sync_state(). The current
490 * solution is to err on the side of caution and have the HLT
491 * handler (see case HAX_EXIT_HLT below) unconditionally set the
492 * IF_MASK bit in env->eflags, which, in effect, disables the
498 if (((cpu
->interrupt_request
& CPU_INTERRUPT_HARD
) &&
499 (env
->eflags
& IF_MASK
)) ||
500 (cpu
->interrupt_request
& CPU_INTERRUPT_NMI
)) {
504 if (cpu
->interrupt_request
& CPU_INTERRUPT_INIT
) {
505 DPRINTF("\nhax_vcpu_hax_exec: handling INIT for %d\n",
507 do_cpu_init(x86_cpu
);
508 hax_vcpu_sync_state(env
, 1);
511 if (cpu
->interrupt_request
& CPU_INTERRUPT_SIPI
) {
512 DPRINTF("hax_vcpu_hax_exec: handling SIPI for %d\n",
514 hax_vcpu_sync_state(env
, 0);
515 do_cpu_sipi(x86_cpu
);
516 hax_vcpu_sync_state(env
, 1);
520 /* If this vcpu is halted, we must not ask HAXM to run it. Instead, we
521 * break out of hax_smp_cpu_exec() as if this vcpu had executed HLT.
522 * That way, this vcpu thread will be trapped in qemu_wait_io_event(),
523 * until the vcpu is unhalted.
525 cpu
->exception_index
= EXCP_HLT
;
532 if (cpu
->exit_request
) {
537 hax_vcpu_interrupt(env
);
539 qemu_mutex_unlock_iothread();
541 hax_ret
= hax_vcpu_run(vcpu
);
543 qemu_mutex_lock_iothread();
545 /* Simply continue the vcpu_run if system call interrupted */
546 if (hax_ret
== -EINTR
|| hax_ret
== -EAGAIN
) {
547 DPRINTF("io window interrupted\n");
552 fprintf(stderr
, "vcpu run failed for vcpu %x\n", vcpu
->vcpu_id
);
555 switch (ht
->_exit_status
) {
557 ret
= hax_handle_io(env
, ht
->pio
._df
, ht
->pio
._port
,
559 ht
->pio
._size
, ht
->pio
._count
, vcpu
->iobuf
);
561 case HAX_EXIT_FAST_MMIO
:
562 ret
= hax_handle_fastmmio(env
, (struct hax_fastmmio
*) vcpu
->iobuf
);
564 /* Guest state changed, currently only for shutdown */
565 case HAX_EXIT_STATECHANGE
:
566 fprintf(stdout
, "VCPU shutdown request\n");
567 qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN
);
568 hax_vcpu_sync_state(env
, 0);
571 case HAX_EXIT_UNKNOWN_VMEXIT
:
572 fprintf(stderr
, "Unknown VMX exit %x from guest\n",
574 qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET
);
575 hax_vcpu_sync_state(env
, 0);
576 cpu_dump_state(cpu
, stderr
, 0);
580 if (!(cpu
->interrupt_request
& CPU_INTERRUPT_HARD
) &&
581 !(cpu
->interrupt_request
& CPU_INTERRUPT_NMI
)) {
582 /* hlt instruction with interrupt disabled is shutdown */
583 env
->eflags
|= IF_MASK
;
585 cpu
->exception_index
= EXCP_HLT
;
589 /* these situations will continue to hax module */
590 case HAX_EXIT_INTERRUPT
:
591 case HAX_EXIT_PAUSED
:
594 /* Should not happen on UG system */
595 fprintf(stderr
, "HAX: unsupported MMIO emulation\n");
599 /* Should not happen on UG system */
600 fprintf(stderr
, "HAX: unimplemented real mode emulation\n");
604 fprintf(stderr
, "Unknown exit %x from HAX\n", ht
->_exit_status
);
605 qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET
);
606 hax_vcpu_sync_state(env
, 0);
607 cpu_dump_state(cpu
, stderr
, 0);
613 if (cpu
->exit_request
) {
614 cpu
->exit_request
= 0;
615 cpu
->exception_index
= EXCP_INTERRUPT
;
620 static void do_hax_cpu_synchronize_state(CPUState
*cpu
, run_on_cpu_data arg
)
622 CPUArchState
*env
= cpu
->env_ptr
;
624 hax_arch_get_registers(env
);
625 cpu
->vcpu_dirty
= true;
628 void hax_cpu_synchronize_state(CPUState
*cpu
)
630 if (!cpu
->vcpu_dirty
) {
631 run_on_cpu(cpu
, do_hax_cpu_synchronize_state
, RUN_ON_CPU_NULL
);
635 static void do_hax_cpu_synchronize_post_reset(CPUState
*cpu
,
638 CPUArchState
*env
= cpu
->env_ptr
;
640 hax_vcpu_sync_state(env
, 1);
641 cpu
->vcpu_dirty
= false;
644 void hax_cpu_synchronize_post_reset(CPUState
*cpu
)
646 run_on_cpu(cpu
, do_hax_cpu_synchronize_post_reset
, RUN_ON_CPU_NULL
);
649 static void do_hax_cpu_synchronize_post_init(CPUState
*cpu
, run_on_cpu_data arg
)
651 CPUArchState
*env
= cpu
->env_ptr
;
653 hax_vcpu_sync_state(env
, 1);
654 cpu
->vcpu_dirty
= false;
657 void hax_cpu_synchronize_post_init(CPUState
*cpu
)
659 run_on_cpu(cpu
, do_hax_cpu_synchronize_post_init
, RUN_ON_CPU_NULL
);
662 static void do_hax_cpu_synchronize_pre_loadvm(CPUState
*cpu
, run_on_cpu_data arg
)
664 cpu
->vcpu_dirty
= true;
667 void hax_cpu_synchronize_pre_loadvm(CPUState
*cpu
)
669 run_on_cpu(cpu
, do_hax_cpu_synchronize_pre_loadvm
, RUN_ON_CPU_NULL
);
672 int hax_smp_cpu_exec(CPUState
*cpu
)
674 CPUArchState
*env
= cpu
->env_ptr
;
679 if (cpu
->exception_index
>= EXCP_INTERRUPT
) {
680 ret
= cpu
->exception_index
;
681 cpu
->exception_index
= -1;
685 fatal
= hax_vcpu_hax_exec(env
);
688 fprintf(stderr
, "Unsupported HAX vcpu return\n");
696 static void set_v8086_seg(struct segment_desc_t
*lhs
, const SegmentCache
*rhs
)
698 memset(lhs
, 0, sizeof(struct segment_desc_t
));
699 lhs
->selector
= rhs
->selector
;
700 lhs
->base
= rhs
->base
;
701 lhs
->limit
= rhs
->limit
;
705 lhs
->operand_size
= 0;
708 lhs
->granularity
= 0;
712 static void get_seg(SegmentCache
*lhs
, const struct segment_desc_t
*rhs
)
714 lhs
->selector
= rhs
->selector
;
715 lhs
->base
= rhs
->base
;
716 lhs
->limit
= rhs
->limit
;
717 lhs
->flags
= (rhs
->type
<< DESC_TYPE_SHIFT
)
718 | (rhs
->present
* DESC_P_MASK
)
719 | (rhs
->dpl
<< DESC_DPL_SHIFT
)
720 | (rhs
->operand_size
<< DESC_B_SHIFT
)
721 | (rhs
->desc
* DESC_S_MASK
)
722 | (rhs
->long_mode
<< DESC_L_SHIFT
)
723 | (rhs
->granularity
* DESC_G_MASK
) | (rhs
->available
* DESC_AVL_MASK
);
726 static void set_seg(struct segment_desc_t
*lhs
, const SegmentCache
*rhs
)
728 unsigned flags
= rhs
->flags
;
730 memset(lhs
, 0, sizeof(struct segment_desc_t
));
731 lhs
->selector
= rhs
->selector
;
732 lhs
->base
= rhs
->base
;
733 lhs
->limit
= rhs
->limit
;
734 lhs
->type
= (flags
>> DESC_TYPE_SHIFT
) & 15;
735 lhs
->present
= (flags
& DESC_P_MASK
) != 0;
736 lhs
->dpl
= rhs
->selector
& 3;
737 lhs
->operand_size
= (flags
>> DESC_B_SHIFT
) & 1;
738 lhs
->desc
= (flags
& DESC_S_MASK
) != 0;
739 lhs
->long_mode
= (flags
>> DESC_L_SHIFT
) & 1;
740 lhs
->granularity
= (flags
& DESC_G_MASK
) != 0;
741 lhs
->available
= (flags
& DESC_AVL_MASK
) != 0;
744 static void hax_getput_reg(uint64_t *hax_reg
, target_ulong
*qemu_reg
, int set
)
746 target_ulong reg
= *hax_reg
;
749 *hax_reg
= *qemu_reg
;
755 /* The sregs has been synced with HAX kernel already before this call */
756 static int hax_get_segments(CPUArchState
*env
, struct vcpu_state_t
*sregs
)
758 get_seg(&env
->segs
[R_CS
], &sregs
->_cs
);
759 get_seg(&env
->segs
[R_DS
], &sregs
->_ds
);
760 get_seg(&env
->segs
[R_ES
], &sregs
->_es
);
761 get_seg(&env
->segs
[R_FS
], &sregs
->_fs
);
762 get_seg(&env
->segs
[R_GS
], &sregs
->_gs
);
763 get_seg(&env
->segs
[R_SS
], &sregs
->_ss
);
765 get_seg(&env
->tr
, &sregs
->_tr
);
766 get_seg(&env
->ldt
, &sregs
->_ldt
);
767 env
->idt
.limit
= sregs
->_idt
.limit
;
768 env
->idt
.base
= sregs
->_idt
.base
;
769 env
->gdt
.limit
= sregs
->_gdt
.limit
;
770 env
->gdt
.base
= sregs
->_gdt
.base
;
774 static int hax_set_segments(CPUArchState
*env
, struct vcpu_state_t
*sregs
)
776 if ((env
->eflags
& VM_MASK
)) {
777 set_v8086_seg(&sregs
->_cs
, &env
->segs
[R_CS
]);
778 set_v8086_seg(&sregs
->_ds
, &env
->segs
[R_DS
]);
779 set_v8086_seg(&sregs
->_es
, &env
->segs
[R_ES
]);
780 set_v8086_seg(&sregs
->_fs
, &env
->segs
[R_FS
]);
781 set_v8086_seg(&sregs
->_gs
, &env
->segs
[R_GS
]);
782 set_v8086_seg(&sregs
->_ss
, &env
->segs
[R_SS
]);
784 set_seg(&sregs
->_cs
, &env
->segs
[R_CS
]);
785 set_seg(&sregs
->_ds
, &env
->segs
[R_DS
]);
786 set_seg(&sregs
->_es
, &env
->segs
[R_ES
]);
787 set_seg(&sregs
->_fs
, &env
->segs
[R_FS
]);
788 set_seg(&sregs
->_gs
, &env
->segs
[R_GS
]);
789 set_seg(&sregs
->_ss
, &env
->segs
[R_SS
]);
791 if (env
->cr
[0] & CR0_PE_MASK
) {
792 /* force ss cpl to cs cpl */
793 sregs
->_ss
.selector
= (sregs
->_ss
.selector
& ~3) |
794 (sregs
->_cs
.selector
& 3);
795 sregs
->_ss
.dpl
= sregs
->_ss
.selector
& 3;
799 set_seg(&sregs
->_tr
, &env
->tr
);
800 set_seg(&sregs
->_ldt
, &env
->ldt
);
801 sregs
->_idt
.limit
= env
->idt
.limit
;
802 sregs
->_idt
.base
= env
->idt
.base
;
803 sregs
->_gdt
.limit
= env
->gdt
.limit
;
804 sregs
->_gdt
.base
= env
->gdt
.base
;
808 static int hax_sync_vcpu_register(CPUArchState
*env
, int set
)
810 struct vcpu_state_t regs
;
812 memset(®s
, 0, sizeof(struct vcpu_state_t
));
815 ret
= hax_sync_vcpu_state(env
, ®s
, 0);
821 /* generic register */
822 hax_getput_reg(®s
._rax
, &env
->regs
[R_EAX
], set
);
823 hax_getput_reg(®s
._rbx
, &env
->regs
[R_EBX
], set
);
824 hax_getput_reg(®s
._rcx
, &env
->regs
[R_ECX
], set
);
825 hax_getput_reg(®s
._rdx
, &env
->regs
[R_EDX
], set
);
826 hax_getput_reg(®s
._rsi
, &env
->regs
[R_ESI
], set
);
827 hax_getput_reg(®s
._rdi
, &env
->regs
[R_EDI
], set
);
828 hax_getput_reg(®s
._rsp
, &env
->regs
[R_ESP
], set
);
829 hax_getput_reg(®s
._rbp
, &env
->regs
[R_EBP
], set
);
831 hax_getput_reg(®s
._r8
, &env
->regs
[8], set
);
832 hax_getput_reg(®s
._r9
, &env
->regs
[9], set
);
833 hax_getput_reg(®s
._r10
, &env
->regs
[10], set
);
834 hax_getput_reg(®s
._r11
, &env
->regs
[11], set
);
835 hax_getput_reg(®s
._r12
, &env
->regs
[12], set
);
836 hax_getput_reg(®s
._r13
, &env
->regs
[13], set
);
837 hax_getput_reg(®s
._r14
, &env
->regs
[14], set
);
838 hax_getput_reg(®s
._r15
, &env
->regs
[15], set
);
840 hax_getput_reg(®s
._rflags
, &env
->eflags
, set
);
841 hax_getput_reg(®s
._rip
, &env
->eip
, set
);
844 regs
._cr0
= env
->cr
[0];
845 regs
._cr2
= env
->cr
[2];
846 regs
._cr3
= env
->cr
[3];
847 regs
._cr4
= env
->cr
[4];
848 hax_set_segments(env
, ®s
);
850 env
->cr
[0] = regs
._cr0
;
851 env
->cr
[2] = regs
._cr2
;
852 env
->cr
[3] = regs
._cr3
;
853 env
->cr
[4] = regs
._cr4
;
854 hax_get_segments(env
, ®s
);
858 ret
= hax_sync_vcpu_state(env
, ®s
, 1);
866 static void hax_msr_entry_set(struct vmx_msr
*item
, uint32_t index
,
873 static int hax_get_msrs(CPUArchState
*env
)
875 struct hax_msr_data md
;
876 struct vmx_msr
*msrs
= md
.entries
;
880 msrs
[n
++].entry
= MSR_IA32_SYSENTER_CS
;
881 msrs
[n
++].entry
= MSR_IA32_SYSENTER_ESP
;
882 msrs
[n
++].entry
= MSR_IA32_SYSENTER_EIP
;
883 msrs
[n
++].entry
= MSR_IA32_TSC
;
885 msrs
[n
++].entry
= MSR_EFER
;
886 msrs
[n
++].entry
= MSR_STAR
;
887 msrs
[n
++].entry
= MSR_LSTAR
;
888 msrs
[n
++].entry
= MSR_CSTAR
;
889 msrs
[n
++].entry
= MSR_FMASK
;
890 msrs
[n
++].entry
= MSR_KERNELGSBASE
;
893 ret
= hax_sync_msr(env
, &md
, 0);
898 for (i
= 0; i
< md
.done
; i
++) {
899 switch (msrs
[i
].entry
) {
900 case MSR_IA32_SYSENTER_CS
:
901 env
->sysenter_cs
= msrs
[i
].value
;
903 case MSR_IA32_SYSENTER_ESP
:
904 env
->sysenter_esp
= msrs
[i
].value
;
906 case MSR_IA32_SYSENTER_EIP
:
907 env
->sysenter_eip
= msrs
[i
].value
;
910 env
->tsc
= msrs
[i
].value
;
914 env
->efer
= msrs
[i
].value
;
917 env
->star
= msrs
[i
].value
;
920 env
->lstar
= msrs
[i
].value
;
923 env
->cstar
= msrs
[i
].value
;
926 env
->fmask
= msrs
[i
].value
;
928 case MSR_KERNELGSBASE
:
929 env
->kernelgsbase
= msrs
[i
].value
;
938 static int hax_set_msrs(CPUArchState
*env
)
940 struct hax_msr_data md
;
941 struct vmx_msr
*msrs
;
945 memset(&md
, 0, sizeof(struct hax_msr_data
));
946 hax_msr_entry_set(&msrs
[n
++], MSR_IA32_SYSENTER_CS
, env
->sysenter_cs
);
947 hax_msr_entry_set(&msrs
[n
++], MSR_IA32_SYSENTER_ESP
, env
->sysenter_esp
);
948 hax_msr_entry_set(&msrs
[n
++], MSR_IA32_SYSENTER_EIP
, env
->sysenter_eip
);
949 hax_msr_entry_set(&msrs
[n
++], MSR_IA32_TSC
, env
->tsc
);
951 hax_msr_entry_set(&msrs
[n
++], MSR_EFER
, env
->efer
);
952 hax_msr_entry_set(&msrs
[n
++], MSR_STAR
, env
->star
);
953 hax_msr_entry_set(&msrs
[n
++], MSR_LSTAR
, env
->lstar
);
954 hax_msr_entry_set(&msrs
[n
++], MSR_CSTAR
, env
->cstar
);
955 hax_msr_entry_set(&msrs
[n
++], MSR_FMASK
, env
->fmask
);
956 hax_msr_entry_set(&msrs
[n
++], MSR_KERNELGSBASE
, env
->kernelgsbase
);
961 return hax_sync_msr(env
, &md
, 1);
964 static int hax_get_fpu(CPUArchState
*env
)
966 struct fx_layout fpu
;
969 ret
= hax_sync_fpu(env
, &fpu
, 0);
974 env
->fpstt
= (fpu
.fsw
>> 11) & 7;
977 for (i
= 0; i
< 8; ++i
) {
978 env
->fptags
[i
] = !((fpu
.ftw
>> i
) & 1);
980 memcpy(env
->fpregs
, fpu
.st_mm
, sizeof(env
->fpregs
));
982 for (i
= 0; i
< 8; i
++) {
983 env
->xmm_regs
[i
].ZMM_Q(0) = ldq_p(&fpu
.mmx_1
[i
][0]);
984 env
->xmm_regs
[i
].ZMM_Q(1) = ldq_p(&fpu
.mmx_1
[i
][8]);
985 if (CPU_NB_REGS
> 8) {
986 env
->xmm_regs
[i
+ 8].ZMM_Q(0) = ldq_p(&fpu
.mmx_2
[i
][0]);
987 env
->xmm_regs
[i
+ 8].ZMM_Q(1) = ldq_p(&fpu
.mmx_2
[i
][8]);
990 env
->mxcsr
= fpu
.mxcsr
;
995 static int hax_set_fpu(CPUArchState
*env
)
997 struct fx_layout fpu
;
1000 memset(&fpu
, 0, sizeof(fpu
));
1001 fpu
.fsw
= env
->fpus
& ~(7 << 11);
1002 fpu
.fsw
|= (env
->fpstt
& 7) << 11;
1003 fpu
.fcw
= env
->fpuc
;
1005 for (i
= 0; i
< 8; ++i
) {
1006 fpu
.ftw
|= (!env
->fptags
[i
]) << i
;
1009 memcpy(fpu
.st_mm
, env
->fpregs
, sizeof(env
->fpregs
));
1010 for (i
= 0; i
< 8; i
++) {
1011 stq_p(&fpu
.mmx_1
[i
][0], env
->xmm_regs
[i
].ZMM_Q(0));
1012 stq_p(&fpu
.mmx_1
[i
][8], env
->xmm_regs
[i
].ZMM_Q(1));
1013 if (CPU_NB_REGS
> 8) {
1014 stq_p(&fpu
.mmx_2
[i
][0], env
->xmm_regs
[i
+ 8].ZMM_Q(0));
1015 stq_p(&fpu
.mmx_2
[i
][8], env
->xmm_regs
[i
+ 8].ZMM_Q(1));
1019 fpu
.mxcsr
= env
->mxcsr
;
1021 return hax_sync_fpu(env
, &fpu
, 1);
1024 static int hax_arch_get_registers(CPUArchState
*env
)
1028 ret
= hax_sync_vcpu_register(env
, 0);
1033 ret
= hax_get_fpu(env
);
1038 ret
= hax_get_msrs(env
);
1043 x86_update_hflags(env
);
1047 static int hax_arch_set_registers(CPUArchState
*env
)
1050 ret
= hax_sync_vcpu_register(env
, 1);
1053 fprintf(stderr
, "Failed to sync vcpu reg\n");
1056 ret
= hax_set_fpu(env
);
1058 fprintf(stderr
, "FPU failed\n");
1061 ret
= hax_set_msrs(env
);
1063 fprintf(stderr
, "MSR failed\n");
1070 static void hax_vcpu_sync_state(CPUArchState
*env
, int modified
)
1072 if (hax_enabled()) {
1074 hax_arch_set_registers(env
);
1076 hax_arch_get_registers(env
);
1082 * much simpler than kvm, at least in first stage because:
1083 * We don't need consider the device pass-through, we don't need
1084 * consider the framebuffer, and we may even remove the bios at all
1086 int hax_sync_vcpus(void)
1088 if (hax_enabled()) {
1096 for (; cpu
!= NULL
; cpu
= CPU_NEXT(cpu
)) {
1099 ret
= hax_arch_set_registers(cpu
->env_ptr
);
1109 void hax_reset_vcpu_state(void *opaque
)
1112 for (cpu
= first_cpu
; cpu
!= NULL
; cpu
= CPU_NEXT(cpu
)) {
1113 cpu
->hax_vcpu
->tunnel
->user_event_pending
= 0;
1114 cpu
->hax_vcpu
->tunnel
->ready_for_interrupt_injection
= 0;
1118 static void hax_accel_class_init(ObjectClass
*oc
, void *data
)
1120 AccelClass
*ac
= ACCEL_CLASS(oc
);
1122 ac
->init_machine
= hax_accel_init
;
1123 ac
->allowed
= &hax_allowed
;
1126 static const TypeInfo hax_accel_type
= {
1127 .name
= ACCEL_CLASS_NAME("hax"),
1128 .parent
= TYPE_ACCEL
,
1129 .class_init
= hax_accel_class_init
,
1132 static void hax_type_init(void)
1134 type_register_static(&hax_accel_type
);
1137 type_init(hax_type_init
);