Changeset 9475 in vbox
- Timestamp:
- Jun 6, 2008 1:10:55 PM (16 years ago)
- Location:
- trunk/src/VBox/VMM/VMMR0
- Files:
-
- 2 edited
-
HWACCMR0A.asm (modified) (1 diff)
-
HWVMXR0.cpp (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR0/HWACCMR0A.asm
r9457 r9475 395 395 ; */ 396 396 BEGINPROC VMXR0StartVM64 397 ret 397 push xBP 398 mov xBP, xSP 399 400 pushf 401 cli 402 403 ;/* First we have to save some final CPU context registers. */ 404 mov rax, qword .vmlaunch64_done 405 push rax 406 mov rax, VMX_VMCS_HOST_RIP ;/* return address (too difficult to continue after VMLAUNCH?) */ 407 vmwrite rax, [xSP] 408 ;/* Note: assumes success... */ 409 add xSP, xS 410 411 ;/* Manual save and restore: 412 ; * - General purpose registers except RIP, RSP 413 ; * 414 ; * Trashed: 415 ; * - CR2 (we don't care) 416 ; * - LDTR (reset to 0) 417 ; * - DRx (presumably not changed at all) 418 ; * - DR7 (reset to 0x400) 419 ; * - EFLAGS (reset to RT_BIT(1); not relevant) 420 ; * 421 ; */ 422 423 ;/* Save all general purpose host registers. */ 424 MYPUSHAD 425 426 ;/* Save the Guest CPU context pointer. */ 427 %ifdef ASM_CALL64_GCC 428 ; fResume already in rdi 429 ; pCtx already in rsi 430 %else 431 mov rdi, rcx ; fResume 432 mov rsi, rdx ; pCtx 433 %endif 434 435 ;/* Save segment registers */ 436 ; Note: MYPUSHSEGS trashes rdx (among others), so we moved it here (msvc amd64 case) 437 MYPUSHSEGS xAX, ax 438 439 ; Save the pCtx pointer 440 push xSI 441 442 ; Save LDTR 443 xor eax, eax 444 sldt ax 445 push xAX 446 447 ; VMX only saves the base of the GDTR & IDTR and resets the limit to 0xffff; we must restore the limit correctly! 448 sub xSP, xS*2 449 sgdt [xSP] 450 451 sub xSP, xS*2 452 sidt [xSP] 453 454 %ifdef VBOX_WITH_DR6_EXPERIMENT 455 ; Restore DR6 - experiment, not safe! 456 mov xBX, [xSI + CPUMCTX.dr6] 457 mov dr6, xBX 458 %endif 459 460 ; Restore CR2 461 mov rbx, qword [xSI + CPUMCTX.cr2] 462 mov cr2, rbx 463 464 mov eax, VMX_VMCS_HOST_RSP 465 vmwrite xAX, xSP 466 ;/* Note: assumes success... */ 467 ;/* Don't mess with ESP anymore!! */ 468 469 ;/* Restore Guest's general purpose registers. */ 470 mov rax, qword [xSI + CPUMCTX.eax] 471 mov rbx, qword [xSI + CPUMCTX.ebx] 472 mov rcx, qword [xSI + CPUMCTX.ecx] 473 mov rdx, qword [xSI + CPUMCTX.edx] 474 mov rbp, qword [xSI + CPUMCTX.ebp] 475 mov r8, qword [xSI + CPUMCTX.r8] 476 mov r9, qword [xSI + CPUMCTX.r9] 477 mov r10, qword [xSI + CPUMCTX.r10] 478 mov r11, qword [xSI + CPUMCTX.r11] 479 mov r12, qword [xSI + CPUMCTX.r12] 480 mov r13, qword [xSI + CPUMCTX.r13] 481 mov r14, qword [xSI + CPUMCTX.r14] 482 mov r15, qword [xSI + CPUMCTX.r15] 483 484 ; resume or start? 485 cmp xDI, 0 ; fResume 486 je .vmlauch64_lauch 487 488 ;/* Restore edi & esi. */ 489 mov rdi, qword [xSI + CPUMCTX.edi] 490 mov rsi, qword [xSI + CPUMCTX.esi] 491 492 vmresume 493 jmp .vmlaunch64_done; ;/* here if vmresume detected a failure. */ 494 495 .vmlauch64_lauch: 496 ;/* Restore rdi & rsi. */ 497 mov rdi, qword [xSI + CPUMCTX.edi] 498 mov rsi, qword [xSI + CPUMCTX.esi] 499 500 vmlaunch 501 jmp .vmlaunch64_done; ;/* here if vmlaunch detected a failure. */ 502 503 ALIGNCODE(16) 504 .vmlaunch64_done: 505 jc near .vmxstart64_invalid_vmxon_ptr 506 jz near .vmxstart64_start_failed 507 508 ; Restore base and limit of the IDTR & GDTR 509 lidt [xSP] 510 add xSP, xS*2 511 lgdt [xSP] 512 add xSP, xS*2 513 514 push xDI 515 mov xDI, [xSP + xS * 2] ; pCtx 516 517 mov qword [xDI + CPUMCTX.eax], rax 518 mov qword [xDI + CPUMCTX.ebx], rbx 519 mov qword [xDI + CPUMCTX.ecx], rcx 520 mov qword [xDI + CPUMCTX.edx], rdx 521 mov qword [xDI + CPUMCTX.esi], rsi 522 mov qword [xDI + CPUMCTX.ebp], rbp 523 mov qword [xDI + CPUMCTX.r8], r8 524 mov qword [xDI + CPUMCTX.r9], r9 525 mov qword [xDI + CPUMCTX.r10], r10 526 mov qword [xDI + CPUMCTX.r11], r11 527 mov qword [xDI + CPUMCTX.r12], r12 528 mov qword [xDI + CPUMCTX.r13], r13 529 mov qword [xDI + CPUMCTX.r14], r14 530 mov qword [xDI + CPUMCTX.r15], r15 531 532 pop xAX ; the guest edi we pushed above 533 mov qword [xDI + CPUMCTX.edi], rax 534 535 %ifdef VBOX_WITH_DR6_EXPERIMENT 536 ; Save DR6 - experiment, not safe! 537 mov xAX, dr6 538 mov [xDI + CPUMCTX.dr6], xAX 539 %endif 540 541 pop xAX ; saved LDTR 542 lldt ax 543 544 add xSP, xS ; pCtx 545 546 ; Restore segment registers 547 MYPOPSEGS xAX, ax 548 549 ; Restore general purpose registers 550 MYPOPAD 551 552 mov eax, VINF_SUCCESS 553 554 .vmstart64_end: 555 popf 556 pop xBP 557 ret 558 559 560 .vmxstart64_invalid_vmxon_ptr: 561 ; Restore base and limit of the IDTR & GDTR 562 lidt [xSP] 563 add xSP, xS*2 564 lgdt [xSP] 565 add xSP, xS*2 566 567 pop xAX ; saved LDTR 568 lldt ax 569 570 add xSP, xS ; pCtx 571 572 ; Restore segment registers 573 MYPOPSEGS xAX, ax 574 575 ; Restore all general purpose host registers. 576 MYPOPAD 577 mov eax, VERR_VMX_INVALID_VMXON_PTR 578 jmp .vmstart64_end 579 580 .vmxstart64_start_failed: 581 ; Restore base and limit of the IDTR & GDTR 582 lidt [xSP] 583 add xSP, xS*2 584 lgdt [xSP] 585 add xSP, xS*2 586 587 pop xAX ; saved LDTR 588 lldt ax 589 590 add xSP, xS ; pCtx 591 592 ; Restore segment registers 593 MYPOPSEGS xAX, ax 594 595 ; Restore all general purpose host registers. 596 MYPOPAD 597 mov eax, VERR_VMX_UNABLE_TO_START_VM 598 jmp .vmstart64_end 398 599 ENDPROC VMXR0StartVM64 399 600 -
trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp
r9457 r9475 681 681 AssertRC(rc); 682 682 683 /* @todo are the hidden base registers in sync with the MSRs? */ 683 684 VMX_WRITE_SELREG(FS, fs); 684 685 AssertRC(rc); … … 967 968 pVM->hwaccm.s.vmx.pfnStartVM = VMXR0StartVM64; 968 969 #endif 970 rc = VMXWriteVMCS(VMX_VMCS_GUEST_FS_BASE, pCtx->msrFSBASE); 971 AssertRC(rc); 972 rc = VMXWriteVMCS(VMX_VMCS_GUEST_GS_BASE, pCtx->msrGSBASE); 973 AssertRC(rc); 969 974 } 970 975 else … … 1982 1987 break; 1983 1988 1984 case VMX_EXIT_RDPMC: /* 15 Guest software attempted to execute RDPMC. */1985 1989 case VMX_EXIT_RDMSR: /* 31 RDMSR. Guest software attempted to execute RDMSR. */ 1986 1990 case VMX_EXIT_WRMSR: /* 32 WRMSR. Guest software attempted to execute WRMSR. */ 1991 /* Note: If we decide to emulate them here, then we must sync the MSRs that could have been changed (sysenter, fs/gs base)!!! */ 1992 case VMX_EXIT_RDPMC: /* 15 Guest software attempted to execute RDPMC. */ 1987 1993 case VMX_EXIT_MWAIT: /* 36 Guest software executed MWAIT. */ 1988 1994 case VMX_EXIT_MONITOR: /* 39 Guest software attempted to execute MONITOR. */ … … 2031 2037 VMXReadVMCS(VMX_VMCS_GUEST_SYSENTER_ESP, &val); 2032 2038 pCtx->SysEnter.esp = val; 2039 2040 /* 64 bits guest mode? */ 2041 if (pCtx->msrEFER & MSR_K6_EFER_LMA) 2042 { 2043 /* Note: we assume that either you can't rely on fs/gs base staying intact when switching in and out of 64 bits mode or that in 2044 * reality it really doesn't matter (as the guest OS restores them manually). 2045 */ 2046 VMXReadVMCS(VMX_VMCS_GUEST_FS_BASE, &val); 2047 pCtx->msrFSBASE = val; 2048 VMXReadVMCS(VMX_VMCS_GUEST_GS_BASE, &val); 2049 pCtx->msrGSBASE = val; 2050 } 2033 2051 } 2034 2052
Note:
See TracChangeset
for help on using the changeset viewer.

