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