Changeset 72446 in vbox for trunk/src/VBox/VMM
- Timestamp:
- Jun 5, 2018 8:53:01 AM (7 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/NEMAllNativeTemplate-win.cpp.h
r72427 r72446 2520 2520 #endif /* IN_RING3 && !NEM_WIN_USE_OUR_OWN_RUN_API */ 2521 2521 2522 2523 /** 2524 * Worker for nemHCWinHandleMessageException & nemR3WinHandleExitException that 2525 * checks if the given opcodes are of interest at all. 2526 * 2527 * @returns true if interesting, false if not. 2528 * @param cbOpcodes Number of opcode bytes available. 2529 * @param pbOpcodes The opcode bytes. 2530 * @param f64BitMode Whether we're in 64-bit mode. 2531 */ 2532 DECLINLINE(bool) nemHcWinIsInterestingUndefinedOpcode(uint8_t cbOpcodes, uint8_t const *pbOpcodes, bool f64BitMode) 2533 { 2534 /* 2535 * Currently only interested in VMCALL and VMMCALL. 2536 */ 2537 while (cbOpcodes >= 3) 2538 { 2539 switch (pbOpcodes[0]) 2540 { 2541 case 0x0f: 2542 switch (pbOpcodes[1]) 2543 { 2544 case 0x01: 2545 switch (pbOpcodes[2]) 2546 { 2547 case 0xc1: /* 0f 01 c1 VMCALL */ 2548 return true; 2549 case 0xd9: /* 0f 01 d9 VMMCALL */ 2550 return true; 2551 default: 2552 break; 2553 } 2554 break; 2555 } 2556 break; 2557 2558 default: 2559 return false; 2560 2561 /* prefixes */ 2562 case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47: 2563 case 0x48: case 0x49: case 0x4a: case 0x4b: case 0x4c: case 0x4d: case 0x4e: case 0x4f: 2564 if (!f64BitMode) 2565 return false; 2566 RT_FALL_THRU(); 2567 case X86_OP_PRF_CS: 2568 case X86_OP_PRF_SS: 2569 case X86_OP_PRF_DS: 2570 case X86_OP_PRF_ES: 2571 case X86_OP_PRF_FS: 2572 case X86_OP_PRF_GS: 2573 case X86_OP_PRF_SIZE_OP: 2574 case X86_OP_PRF_SIZE_ADDR: 2575 case X86_OP_PRF_LOCK: 2576 case X86_OP_PRF_REPZ: 2577 case X86_OP_PRF_REPNZ: 2578 cbOpcodes--; 2579 pbOpcodes++; 2580 continue; 2581 } 2582 break; 2583 } 2584 return false; 2585 } 2586 2587 2588 #ifdef NEM_WIN_USE_OUR_OWN_RUN_API 2589 /** 2590 * Copies state included in a exception intercept message. 2591 * 2592 * @param pVCpu The cross context per CPU structure. 2593 * @param pMsg The message. 2594 * @param pCtx The register context. 2595 * @param fClearXcpt Clear pending exception. 2596 */ 2597 DECLINLINE(void) nemHCWinCopyStateFromExceptionMessage(PVMCPU pVCpu, HV_X64_EXCEPTION_INTERCEPT_MESSAGE const *pMsg, 2598 PCPUMCTX pCtx, bool fClearXcpt) 2599 { 2600 nemHCWinCopyStateFromX64Header(pVCpu, pCtx, &pMsg->Header); 2601 pCtx->fExtrn &= ~( CPUMCTX_EXTRN_GPRS_MASK | CPUMCTX_EXTRN_SS | CPUMCTX_EXTRN_DS 2602 | (fClearXcpt ? CPUMCTX_EXTRN_NEM_WIN_EVENT_INJECT : 0) ); 2603 pCtx->rax = pMsg->Rax; 2604 pCtx->rcx = pMsg->Rcx; 2605 pCtx->rdx = pMsg->Rdx; 2606 pCtx->rbx = pMsg->Rbx; 2607 pCtx->rsp = pMsg->Rsp; 2608 pCtx->rbp = pMsg->Rbp; 2609 pCtx->rsi = pMsg->Rsi; 2610 pCtx->rdi = pMsg->Rdi; 2611 pCtx->r8 = pMsg->R8; 2612 pCtx->r9 = pMsg->R9; 2613 pCtx->r10 = pMsg->R10; 2614 pCtx->r11 = pMsg->R11; 2615 pCtx->r12 = pMsg->R12; 2616 pCtx->r13 = pMsg->R13; 2617 pCtx->r14 = pMsg->R14; 2618 pCtx->r15 = pMsg->R15; 2619 NEM_WIN_COPY_BACK_SEG(pCtx->ds, pMsg->DsSegment); 2620 NEM_WIN_COPY_BACK_SEG(pCtx->ss, pMsg->SsSegment); 2621 } 2622 #elif defined(IN_RING3) 2623 /** 2624 * Copies state included in a exception intercept exit. 2625 * 2626 * @param pVCpu The cross context per CPU structure. 2627 * @param pExit The VM exit information. 2628 * @param pCtx The register context. 2629 * @param fClearXcpt Clear pending exception. 2630 */ 2631 DECLINLINE(void) nemR3WinCopyStateFromExceptionMessage(PVMCPU pVCpu, WHV_RUN_VP_EXIT_CONTEXT const *pExit, 2632 PCPUMCTX pCtx, bool fClearXcpt) 2633 { 2634 nemR3WinCopyStateFromX64Header(pVCpu, pCtx, &pExit->VpContext); 2635 if (fClearXcpt) 2636 pCtx->fExtrn &= ~CPUMCTX_EXTRN_NEM_WIN_EVENT_INJECT; 2637 } 2638 #endif /* IN_RING3 && !NEM_WIN_USE_OUR_OWN_RUN_API */ 2639 2640 2641 #ifdef NEM_WIN_USE_OUR_OWN_RUN_API 2642 /** 2643 * Deals with exception intercept message (HvMessageTypeX64ExceptionIntercept). 2644 * 2645 * @returns Strict VBox status code. 2646 * @param pVCpu The cross context per CPU structure. 2647 * @param pMsg The message. 2648 * @param pCtx The register context. 2649 * @param pGVCpu The global (ring-0) per CPU structure (NULL in r3). 2650 * @sa nemR3WinHandleExitMsr 2651 */ 2652 NEM_TMPL_STATIC VBOXSTRICTRC 2653 nemHCWinHandleMessageException(PVMCPU pVCpu, HV_X64_EXCEPTION_INTERCEPT_MESSAGE const *pMsg, PCPUMCTX pCtx, PGVMCPU pGVCpu) 2654 { 2655 /* 2656 * Assert sanity. 2657 */ 2658 AssertMsg(pMsg->Header.InstructionLength < 0x10, ("%#x\n", pMsg->Header.InstructionLength)); 2659 Assert( pMsg->Header.InterceptAccessType == HV_INTERCEPT_ACCESS_READ 2660 || pMsg->Header.InterceptAccessType == HV_INTERCEPT_ACCESS_WRITE 2661 || pMsg->Header.InterceptAccessType == HV_INTERCEPT_ACCESS_EXECUTE); 2662 Assert(pMsg->Header.ExecutionState.InterruptionPending); 2663 2664 /* 2665 * Handle the intercept. 2666 */ 2667 switch (pMsg->ExceptionVector) 2668 { 2669 /* 2670 * We get undefined opcodes on VMMCALL(AMD) & VMCALL(Intel) instructions 2671 * and need to turn them over to GIM. 2672 */ 2673 case X86_XCPT_UD: 2674 if (nemHcWinIsInterestingUndefinedOpcode(pMsg->InstructionByteCount, pMsg->InstructionBytes, 2675 pMsg->Header.ExecutionState.EferLma && pMsg->Header.CsSegment.Long )) 2676 { 2677 nemHCWinCopyStateFromExceptionMessage(pVCpu, pMsg, pCtx, true /*fClearXcpt*/); 2678 VBOXSTRICTRC rcStrict = nemHCWinImportStateIfNeededStrict(pVCpu, pGVCpu, pCtx, 2679 NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM, "#UD"); 2680 if (rcStrict == VINF_SUCCESS) 2681 { 2682 rcStrict = IEMExecOneWithPrefetchedByPC(pVCpu, CPUMCTX2CORE(pCtx), pMsg->Header.Rip, pMsg->InstructionBytes, 2683 pMsg->InstructionByteCount); 2684 Log4(("XcptExit/%u: %04x:%08RX64/%s: #UD -> emulated -> %Rrc\n", pVCpu->idCpu, pMsg->Header.CsSegment.Selector, 2685 pMsg->Header.Rip, nemHCWinExecStateToLogStr(&pMsg->Header), VBOXSTRICTRC_VAL(rcStrict) )); 2686 } 2687 else 2688 Log4(("XcptExit/%u: %04x:%08RX64/%s: #UD -> state import (emulate) -> %Rrc\n", 2689 pVCpu->idCpu, pMsg->Header.CsSegment.Selector, pMsg->Header.Rip, 2690 nemHCWinExecStateToLogStr(&pMsg->Header), VBOXSTRICTRC_VAL(rcStrict) )); 2691 return rcStrict; 2692 } 2693 Log4(("XcptExit/%u: %04x:%08RX64/%s: #UD [%.*Rhxs] -> re-injected\n", pVCpu->idCpu, pMsg->Header.CsSegment.Selector, 2694 pMsg->Header.Rip, nemHCWinExecStateToLogStr(&pMsg->Header), pMsg->InstructionByteCount, pMsg->InstructionBytes )); 2695 break; 2696 2697 /* 2698 * Filter debug exceptions. 2699 */ 2700 case X86_XCPT_DB: 2701 break; 2702 2703 case X86_XCPT_BP: 2704 break; 2705 2706 /* This shouldn't happen. */ 2707 default: 2708 AssertLogRelMsgFailedReturn(("ExceptionVector=%#x\n", pMsg->ExceptionVector), VERR_IEM_IPE_6); 2709 } 2710 2711 return VINF_SUCCESS; 2712 } 2713 #elif defined(IN_RING3) 2714 /** 2715 * Deals with MSR access exits (WHvRunVpExitReasonException). 2716 * 2717 * @returns Strict VBox status code. 2718 * @param pVM The cross context VM structure. 2719 * @param pVCpu The cross context per CPU structure. 2720 * @param pExit The VM exit information to handle. 2721 * @param pCtx The register context. 2722 * @sa nemR3WinHandleExitException 2723 */ 2724 NEM_TMPL_STATIC VBOXSTRICTRC 2725 nemR3WinHandleExitException(PVM pVM, PVMCPU pVCpu, WHV_RUN_VP_EXIT_CONTEXT const *pExit, PCPUMCTX pCtx) 2726 { 2727 /* 2728 * Assert sanity. 2729 */ 2730 AssertMsg(pExit->VpContext.InstructionLength < 0x10, ("%#x\n", pExit->VpContext.InstructionLength)); 2731 #if 0 2732 Log4(("XcptExit/%u: %04x:%08RX64/%s: %x\n", pVCpu->idCpu, pExit->VpContext.Cs.Selector, pExit->VpContext.Rip, nemR3WinExecStateToLogStr(&pExit->VpContext), pExit->VpException.ExceptionType)); 2733 nemR3WinCopyStateFromExceptionMessage(pVCpu, pExit, pCtx, true /*fClearXcpt*/); 2734 VBOXSTRICTRC rcStrict = nemHCWinImportStateIfNeededStrict(pVCpu, NULL, pCtx, NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM, "#UD"); 2735 if (rcStrict != VINF_SUCCESS) 2736 return rcStrict; 2737 #endif 2738 Assert(pExit->VpContext.ExecutionState.InterruptionPending); 2739 2740 /* 2741 * Handle the intercept. 2742 */ 2743 switch (pExit->VpException.ExceptionType) 2744 { 2745 /* 2746 * We get undefined opcodes on VMMCALL(AMD) & VMCALL(Intel) instructions 2747 * and need to turn them over to GIM. 2748 */ 2749 case X86_XCPT_UD: 2750 if (nemHcWinIsInterestingUndefinedOpcode(pExit->VpException.InstructionByteCount, pExit->VpException.InstructionBytes, 2751 pExit->VpContext.ExecutionState.EferLma && pExit->VpContext.Cs.Long )) 2752 { 2753 nemR3WinCopyStateFromExceptionMessage(pVCpu, pExit, pCtx, true /*fClearXcpt*/); 2754 VBOXSTRICTRC rcStrict = nemHCWinImportStateIfNeededStrict(pVCpu, NULL, pCtx, 2755 NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM, "#UD"); 2756 if (rcStrict == VINF_SUCCESS) 2757 { 2758 rcStrict = IEMExecOneWithPrefetchedByPC(pVCpu, CPUMCTX2CORE(pCtx), pExit->VpContext.Rip, 2759 pExit->VpException.InstructionBytes, 2760 pExit->VpException.InstructionByteCount); 2761 Log4(("XcptExit/%u: %04x:%08RX64/%s: #UD -> emulated -> %Rrc\n", 2762 pVCpu->idCpu, pExit->VpContext.Cs.Selector, pExit->VpContext.Rip, 2763 nemR3WinExecStateToLogStr(&pExit->VpContext), VBOXSTRICTRC_VAL(rcStrict) )); 2764 } 2765 else 2766 Log4(("XcptExit/%u: %04x:%08RX64/%s: #UD -> state import (emulate) -> %Rrc\n", 2767 pVCpu->idCpu, pExit->VpContext.Cs.Selector, pExit->VpContext.Rip, 2768 nemR3WinExecStateToLogStr(&pExit->VpContext), VBOXSTRICTRC_VAL(rcStrict) )); 2769 return rcStrict; 2770 } 2771 Log4(("XcptExit/%u: %04x:%08RX64/%s: #UD [%.*Rhxs] -> re-injected\n", pVCpu->idCpu, 2772 pExit->VpContext.Cs.Selector, pExit->VpContext.Rip, nemR3WinExecStateToLogStr(&pExit->VpContext), 2773 pExit->VpException.InstructionByteCount, pExit->VpException.InstructionBytes )); 2774 break; 2775 2776 /* 2777 * Filter debug exceptions. 2778 */ 2779 case X86_XCPT_DB: 2780 break; 2781 2782 case X86_XCPT_BP: 2783 break; 2784 2785 /* This shouldn't happen. */ 2786 default: 2787 AssertLogRelMsgFailedReturn(("ExceptionType=%#x\n", pExit->VpException.ExceptionType), VERR_IEM_IPE_6); 2788 } 2789 2790 RT_NOREF_PV(pVM); 2791 return VINF_SUCCESS; 2792 } 2793 #endif /* IN_RING3 && !NEM_WIN_USE_OUR_OWN_RUN_API */ 2794 2795 2522 2796 #ifdef NEM_WIN_USE_OUR_OWN_RUN_API 2523 2797 /** … … 2693 2967 return nemHCWinHandleMessageMsr(pVCpu, &pMsg->X64MsrIntercept, pCtx, pGVCpu); 2694 2968 2969 case HvMessageTypeX64ExceptionIntercept: 2970 Assert(pMsg->Header.PayloadSize == sizeof(pMsg->X64ExceptionIntercept)); 2971 STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatExitException); 2972 return nemHCWinHandleMessageException(pVCpu, &pMsg->X64ExceptionIntercept, pCtx, pGVCpu); 2973 2695 2974 case HvMessageTypeUnrecoverableException: 2696 2975 Assert(pMsg->Header.PayloadSize == sizeof(pMsg->X64InterceptHeader)); … … 2705 2984 VERR_NEM_IPE_3); 2706 2985 2707 case HvMessageTypeX64ExceptionIntercept:2708 2986 case HvMessageTypeX64ApicEoi: 2709 2987 case HvMessageTypeX64LegacyFpError: … … 2771 3049 return nemR3WinHandleExitMsr(pVM, pVCpu, pExit, pCtx); 2772 3050 3051 case WHvRunVpExitReasonException: 3052 STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatExitException); 3053 return nemR3WinHandleExitException(pVM, pVCpu, pExit, pCtx); 3054 2773 3055 case WHvRunVpExitReasonUnrecoverableException: 2774 3056 STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatExitUnrecoverable); 2775 3057 return nemR3WinHandleExitUnrecoverableException(pVM, pVCpu, pExit, pCtx); 2776 3058 2777 case WHvRunVpExitReasonException: /* needs configuring */2778 3059 case WHvRunVpExitReasonUnsupportedFeature: 2779 3060 case WHvRunVpExitReasonInvalidVpRegisterValue: -
trunk/src/VBox/VMM/VMMR3/NEMR3Native-win.cpp
r72430 r72446 612 612 hrc = WHvGetCapabilityWrapper(WHvCapabilityCodeExceptionExitBitmap, &Caps, sizeof(Caps)); 613 613 if (SUCCEEDED(hrc)) 614 LogRel(("NEM: Warning! Supported exception exit bitmap: %#RX64\n", Caps.Features.AsUINT64));614 LogRel(("NEM: Supported exception exit bitmap: %#RX64\n", Caps.ExceptionExitBitmap)); 615 615 else 616 616 LogRel(("NEM: Warning! WHvGetCapability/WHvCapabilityCodeExceptionExitBitmap failed: %Rhrc (Last=%#x/%u)", … … 1052 1052 Property.ExtendedVmExits.X64CpuidExit = pVM->nem.s.fExtendedCpuIdExit; /** @todo Register fixed results and restrict cpuid exits */ 1053 1053 Property.ExtendedVmExits.X64MsrExit = pVM->nem.s.fExtendedMsrExit; 1054 #if 0 /** @todo handle some MSRs too. */1055 1054 Property.ExtendedVmExits.ExceptionExit = pVM->nem.s.fExtendedXcptExit; 1056 #endif1057 1055 hrc = WHvSetPartitionProperty(hPartition, WHvPartitionPropertyCodeExtendedVmExits, &Property, sizeof(Property)); 1058 1056 if (SUCCEEDED(hrc)) … … 1218 1216 STAMR3RegisterF(pVM, &pNemCpu->StatExitCpuId, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of CPUID exits", "/NEM/CPU%u/ExitCpuId", iCpu); 1219 1217 STAMR3RegisterF(pVM, &pNemCpu->StatExitMsr, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of MSR access exits", "/NEM/CPU%u/ExitMsr", iCpu); 1218 STAMR3RegisterF(pVM, &pNemCpu->StatExitException, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of exception exits", "/NEM/CPU%u/ExitException", iCpu); 1220 1219 STAMR3RegisterF(pVM, &pNemCpu->StatExitUnrecoverable, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of unrecoverable exits", "/NEM/CPU%u/ExitUnrecoverable", iCpu); 1221 1220 STAMR3RegisterF(pVM, &pNemCpu->StatGetMsgTimeout, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of get message timeouts/alerts", "/NEM/CPU%u/GetMsgTimeout", iCpu); … … 1301 1300 "Failed to set WHvPartitionPropertyCodeProcessorClFlushSize to %u: %Rhrc (Last=%#x/%u)", 1302 1301 pVM->nem.s.cCacheLineFlushShift, hrc, RTNtLastStatusValue(), RTNtLastErrorValue()); 1302 1303 /* Intercept #DB, #BP and #UD exceptions. */ 1304 RT_ZERO(Property); 1305 Property.ExceptionExitBitmap = RT_BIT_64(WHvX64ExceptionTypeDivideErrorFault) 1306 | RT_BIT_64(WHvX64ExceptionTypeBreakpointTrap) 1307 | RT_BIT_64(WHvX64ExceptionTypeInvalidOpcodeFault); 1308 hrc = WHvSetPartitionProperty(hPartition, WHvPartitionPropertyCodeExceptionExitBitmap, &Property, sizeof(Property)); 1309 if (FAILED(hrc)) 1310 return VMSetError(pVM, VERR_NEM_VM_CREATE_FAILED, RT_SRC_POS, 1311 "Failed to set WHvPartitionPropertyCodeExceptionExitBitmap to %#RX64: %Rhrc (Last=%#x/%u)", 1312 Property.ExceptionExitBitmap, hrc, RTNtLastStatusValue(), RTNtLastErrorValue()); 1313 1303 1314 1304 1315 /* -
trunk/src/VBox/VMM/include/NEMInternal.h
r72412 r72446 251 251 STAMCOUNTER StatExitCpuId; 252 252 STAMCOUNTER StatExitMsr; 253 STAMCOUNTER StatExitException; 253 254 STAMCOUNTER StatExitUnrecoverable; 254 255 STAMCOUNTER StatGetMsgTimeout;
Note:
See TracChangeset
for help on using the changeset viewer.