Changeset 92499 in vbox
- Timestamp:
- Nov 18, 2021 4:07:42 PM (3 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 2 edited
-
VMMR3/NEMR3Native-darwin.cpp (modified) (18 diffs)
-
include/NEMInternal.h (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR3/NEMR3Native-darwin.cpp
r92475 r92499 818 818 } while(0) 819 819 820 STAM_PROFILE_ADV_START(&pVCpu->nem.s.StatProfGstStateImport, x); 821 820 822 RT_NOREF(pVM); 821 823 fWhat &= pVCpu->cpum.GstCtx.fExtrn; … … 960 962 } 961 963 } 964 965 #if 0 /* Always done. */ 962 966 if (fWhat & CPUMCTX_EXTRN_APIC_TPR) 963 967 { … … 967 971 APICSetTpr(pVCpu, u64Cr8 << 4); 968 972 } 973 #endif 974 969 975 if (fWhat & CPUMCTX_EXTRN_XCRx) 970 976 READ_GREG(HV_X86_XCR0, pVCpu->cpum.GstCtx.aXcr[0]); … … 1010 1016 { /* likely */ } 1011 1017 else 1018 { 1019 STAM_PROFILE_ADV_STOP(&pVCpu->nem.s.StatProfGstStateImport, x); 1012 1020 return nemR3DarwinHvSts2Rc(hrc); 1021 } 1013 1022 } 1014 1023 … … 1095 1104 /* Typical. */ 1096 1105 if (!fMaybeChangedMode && !fUpdateCr3) 1106 { 1107 STAM_PROFILE_ADV_STOP(&pVCpu->nem.s.StatProfGstStateImport, x); 1097 1108 return VINF_SUCCESS; 1109 } 1098 1110 1099 1111 /* … … 1114 1126 AssertMsgFailedReturn(("rc=%Rrc\n", rc), RT_FAILURE_NP(rc) ? rc : VERR_NEM_IPE_2); 1115 1127 } 1128 1129 STAM_PROFILE_ADV_STOP(&pVCpu->nem.s.StatProfGstStateImport, x); 1116 1130 1117 1131 return VINF_SUCCESS; … … 1551 1565 #endif 1552 1566 1567 STAM_PROFILE_ADV_START(&pVCpu->nem.s.StatProfGstStateExport, x); 1568 1553 1569 uint64_t const fWhat = ~pVCpu->cpum.GstCtx.fExtrn & CPUMCTX_EXTRN_ALL; 1554 1570 if (!fWhat) … … 1591 1607 if (fWhat & CPUMCTX_EXTRN_APIC_TPR) 1592 1608 { 1593 WRITE_GREG(HV_X86_TPR, CPUMGetGuestCR8(pVCpu)); 1609 Assert(pVCpu->nem.s.fCtxChanged & HM_CHANGED_GUEST_APIC_TPR); 1610 vmxHCExportGuestApicTpr(pVCpu, pVmxTransient); 1611 1612 rc = APICGetTpr(pVCpu, &pVmxTransient->u8GuestTpr, NULL /*pfPending*/, NULL /*pu8PendingIntr*/); 1613 AssertRC(rc); 1614 1615 WRITE_GREG(HV_X86_TPR, pVmxTransient->u8GuestTpr); 1594 1616 ASMAtomicUoAndU64(&pVCpu->nem.s.fCtxChanged, ~HM_CHANGED_GUEST_APIC_TPR); 1595 1617 } … … 1654 1676 if (fWhat & CPUMCTX_EXTRN_OTHER_MSRS) 1655 1677 { 1678 #if 0 1656 1679 hv_return_t hrc = hv_vmx_vcpu_set_apic_address(pVCpu->nem.s.hVCpuId, APICGetBaseMsrNoCheck(pVCpu) & PAGE_BASE_GC_MASK); 1657 1680 if (RT_UNLIKELY(hrc != HV_SUCCESS)) 1658 1681 return nemR3DarwinHvSts2Rc(hrc); 1682 #endif 1659 1683 1660 1684 ASMAtomicUoAndU64(&pVCpu->nem.s.fCtxChanged, ~HM_CHANGED_GUEST_OTHER_MSRS); … … 1705 1729 | (HM_CHANGED_KEEPER_STATE_MASK & ~HM_CHANGED_VMX_MASK))); 1706 1730 1731 STAM_PROFILE_ADV_STOP(&pVCpu->nem.s.StatProfGstStateExport, x); 1707 1732 return VINF_SUCCESS; 1708 1733 #undef WRITE_GREG … … 1739 1764 rc = nemR3DarwinCopyStateFromHv(pVM, pVCpu, CPUMCTX_EXTRN_ALL); 1740 1765 AssertRCReturn(rc, rc); 1766 1767 STAM_COUNTER_INC(&pVCpu->nem.s.pVmxStats->aStatExitReason[pVmxTransient->uExitReason & MASK_EXITREASON_STAT]); 1768 STAM_REL_COUNTER_INC(&pVCpu->nem.s.pVmxStats->StatExitAll); 1741 1769 1742 1770 #ifndef HMVMX_USE_FUNCTION_TABLE … … 2141 2169 } 2142 2170 2143 /* Use TPR shadowing if supported by the CPU. */2144 if ( PDMHasApic(pVM)2145 && (g_HmMsrs.u.vmx.ProcCtls.n.allowed1 & VMX_PROC_CTLS_USE_TPR_SHADOW))2146 {2147 fVal |= VMX_PROC_CTLS_USE_TPR_SHADOW; /* CR8 reads from the Virtual-APIC page. */2148 /* CR8 writes cause a VM-exit based on TPR threshold. */2149 Assert(!(fVal & VMX_PROC_CTLS_CR8_STORE_EXIT));2150 Assert(!(fVal & VMX_PROC_CTLS_CR8_LOAD_EXIT));2151 }2152 else2153 {2154 fVal |= VMX_PROC_CTLS_CR8_STORE_EXIT /* CR8 reads cause a VM-exit. */2155 | VMX_PROC_CTLS_CR8_LOAD_EXIT; /* CR8 writes cause a VM-exit. */2156 }2157 2158 2171 /* Use the secondary processor-based VM-execution controls if supported by the CPU. */ 2159 2172 if (g_HmMsrs.u.vmx.ProcCtls.n.allowed1 & VMX_PROC_CTLS_USE_SECONDARY_CTLS) … … 2303 2316 2304 2317 /** 2318 * Registers statistics for the given vCPU. 2319 * 2320 * @returns VBox status code. 2321 * @param pVM The cross context VM structure. 2322 * @param idCpu The CPU ID. 2323 * @param pNemCpu The NEM CPU structure. 2324 */ 2325 static int nemR3DarwinStatisticsRegister(PVM pVM, VMCPUID idCpu, PNEMCPU pNemCpu) 2326 { 2327 #define NEM_REG_STAT(a_pVar, a_enmType, s_enmVisibility, a_enmUnit, a_szNmFmt, a_szDesc) do { \ 2328 int rc = STAMR3RegisterF(pVM, a_pVar, a_enmType, s_enmVisibility, a_enmUnit, a_szDesc, a_szNmFmt, idCpu); \ 2329 AssertRC(rc); \ 2330 } while (0) 2331 #define NEM_REG_PROFILE(a_pVar, a_szNmFmt, a_szDesc) \ 2332 NEM_REG_STAT(a_pVar, STAMTYPE_PROFILE, STAMVISIBILITY_USED, STAMUNIT_TICKS_PER_CALL, a_szNmFmt, a_szDesc) 2333 #define NEM_REG_COUNTER(a, b, desc) NEM_REG_STAT(a, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, b, desc) 2334 2335 NEM_REG_COUNTER(&pNemCpu->pVmxStats->StatExitCR0Read, "/NEM/CPU%u/Exit/Instr/CR-Read/CR0", "CR0 read."); 2336 NEM_REG_COUNTER(&pNemCpu->pVmxStats->StatExitCR2Read, "/NEM/CPU%u/Exit/Instr/CR-Read/CR2", "CR2 read."); 2337 NEM_REG_COUNTER(&pNemCpu->pVmxStats->StatExitCR3Read, "/NEM/CPU%u/Exit/Instr/CR-Read/CR3", "CR3 read."); 2338 NEM_REG_COUNTER(&pNemCpu->pVmxStats->StatExitCR4Read, "/NEM/CPU%u/Exit/Instr/CR-Read/CR4", "CR4 read."); 2339 NEM_REG_COUNTER(&pNemCpu->pVmxStats->StatExitCR8Read, "/NEM/CPU%u/Exit/Instr/CR-Read/CR8", "CR8 read."); 2340 NEM_REG_COUNTER(&pNemCpu->pVmxStats->StatExitCR0Write, "/NEM/CPU%u/Exit/Instr/CR-Write/CR0", "CR0 write."); 2341 NEM_REG_COUNTER(&pNemCpu->pVmxStats->StatExitCR2Write, "/NEM/CPU%u/Exit/Instr/CR-Write/CR2", "CR2 write."); 2342 NEM_REG_COUNTER(&pNemCpu->pVmxStats->StatExitCR3Write, "/NEM/CPU%u/Exit/Instr/CR-Write/CR3", "CR3 write."); 2343 NEM_REG_COUNTER(&pNemCpu->pVmxStats->StatExitCR4Write, "/NEM/CPU%u/Exit/Instr/CR-Write/CR4", "CR4 write."); 2344 NEM_REG_COUNTER(&pNemCpu->pVmxStats->StatExitCR8Write, "/NEM/CPU%u/Exit/Instr/CR-Write/CR8", "CR8 write."); 2345 2346 NEM_REG_COUNTER(&pNemCpu->pVmxStats->StatExitAll, "/NEM/CPU%u/Exit/All", "Total exits (including nested-guest exits)."); 2347 2348 #ifdef VBOX_WITH_STATISTICS 2349 NEM_REG_PROFILE(&pNemCpu->StatProfGstStateImport, "/NEM/CPU%u/ImportGuestState", "Profiling of importing guest state from hardware after VM-exit."); 2350 NEM_REG_PROFILE(&pNemCpu->StatProfGstStateExport, "/NEM/CPU%u/ExportGuestState", "Profiling of exporting guest state from hardware after VM-exit."); 2351 2352 for (int j = 0; j < MAX_EXITREASON_STAT; j++) 2353 { 2354 const char *pszExitName = HMGetVmxExitName(j); 2355 if (pszExitName) 2356 { 2357 int rc = STAMR3RegisterF(pVM, &pNemCpu->pVmxStats->aStatExitReason[j], STAMTYPE_COUNTER, STAMVISIBILITY_USED, 2358 STAMUNIT_OCCURENCES, pszExitName, "/NEM/CPU%u/Exit/Reason/%02x", idCpu, j); 2359 AssertRCReturn(rc, rc); 2360 } 2361 } 2362 #endif 2363 2364 return VINF_SUCCESS; 2365 2366 #undef NEM_REG_COUNTER 2367 #undef NEM_REG_PROFILE 2368 #undef NEM_REG_STAT 2369 } 2370 2371 2372 /** 2305 2373 * Try initialize the native API. 2306 2374 * … … 2354 2422 PVMXSTATISTICS pVmxStats = (PVMXSTATISTICS)RTMemAllocZ(sizeof(*pVmxStats)); 2355 2423 if (RT_LIKELY(pVmxStats)) 2424 { 2356 2425 pNemCpu->pVmxStats = pVmxStats; 2426 rc = nemR3DarwinStatisticsRegister(pVM, idCpu, pNemCpu); 2427 AssertRC(rc); 2428 } 2357 2429 else 2358 2430 { … … 2443 2515 2444 2516 /** 2517 * Worker to setup the TPR shadowing feature if available on the CPU and the VM has an APIC enabled. 2518 * 2519 * @returns VBox status code 2520 * @param pVM The VM handle. 2521 * @param pVCpu The vCPU handle. 2522 * @param idCpu ID of the CPU to create. 2523 */ 2524 static DECLCALLBACK(int) nemR3DarwinNativeInitTprShadowing(PVM pVM, PVMCPU pVCpu, VMCPUID idCpu) 2525 { 2526 PVMXVMCSINFO pVmcsInfo = &pVCpu->nem.s.VmcsInfo; 2527 uint32_t fVal = pVmcsInfo->u32ProcCtls; 2528 2529 /* Use TPR shadowing if supported by the CPU. */ 2530 if ( PDMHasApic(pVM) 2531 && (g_HmMsrs.u.vmx.ProcCtls.n.allowed1 & VMX_PROC_CTLS_USE_TPR_SHADOW)) 2532 { 2533 fVal |= VMX_PROC_CTLS_USE_TPR_SHADOW; /* CR8 reads from the Virtual-APIC page. */ 2534 /* CR8 writes cause a VM-exit based on TPR threshold. */ 2535 Assert(!(fVal & VMX_PROC_CTLS_CR8_STORE_EXIT)); 2536 Assert(!(fVal & VMX_PROC_CTLS_CR8_LOAD_EXIT)); 2537 } 2538 else 2539 { 2540 fVal |= VMX_PROC_CTLS_CR8_STORE_EXIT /* CR8 reads cause a VM-exit. */ 2541 | VMX_PROC_CTLS_CR8_LOAD_EXIT; /* CR8 writes cause a VM-exit. */ 2542 } 2543 2544 /* Commit it to the VMCS and update our cache. */ 2545 int rc = nemR3DarwinWriteVmcs32(pVCpu, VMX_VMCS32_CTRL_PROC_EXEC, fVal); 2546 AssertRC(rc); 2547 pVmcsInfo->u32ProcCtls = fVal; 2548 2549 return VINF_SUCCESS; 2550 } 2551 2552 2553 /** 2445 2554 * This is called after CPUMR3Init is done. 2446 2555 * … … 2481 2590 int nemR3NativeInitCompleted(PVM pVM, VMINITCOMPLETED enmWhat) 2482 2591 { 2483 NOREF(pVM); NOREF(enmWhat); 2592 if (enmWhat == VMINITCOMPLETED_RING3) 2593 { 2594 /* Now that PDM is initialized the APIC state is known in order to enable the TPR shadowing feature on all EMTs. */ 2595 for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++) 2596 { 2597 PVMCPU pVCpu = pVM->apCpusR3[idCpu]; 2598 2599 int rc = VMR3ReqCallWait(pVM, idCpu, (PFNRT)nemR3DarwinNativeInitTprShadowing, 3, pVM, pVCpu, idCpu); 2600 if (RT_FAILURE(rc)) 2601 return VMSetError(pVM, VERR_NEM_VM_CREATE_FAILED, RT_SRC_POS, "Call to hv_vcpu_create failed: %Rrc", rc); 2602 } 2603 } 2484 2604 return VINF_SUCCESS; 2485 2605 } … … 2658 2778 && !VMCPU_FF_IS_ANY_SET(pVCpu, VMCPU_FF_HM_TO_R3_MASK)) 2659 2779 { 2660 if (VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED_EXEC_NEM_WAIT, VMCPUSTATE_STARTED_EXEC_NEM)) 2780 LogFlowFunc(("Running vCPU\n")); 2781 pVCpu->nem.s.Event.fPending = false; 2782 2783 TMNotifyStartOfExecution(pVM, pVCpu); 2784 2785 Assert(!pVCpu->nem.s.fCtxChanged); 2786 hv_return_t hrc; 2787 if (hv_vcpu_run_until) 2788 hrc = hv_vcpu_run_until(pVCpu->nem.s.hVCpuId, HV_DEADLINE_FOREVER); 2789 else 2790 hrc = hv_vcpu_run(pVCpu->nem.s.hVCpuId); 2791 2792 TMNotifyEndOfExecution(pVM, pVCpu, ASMReadTSC()); 2793 2794 /* 2795 * Sync the TPR shadow with our APIC state. 2796 */ 2797 if ( !VmxTransient.fIsNestedGuest 2798 && (pVCpu->nem.s.VmcsInfo.u32ProcCtls & VMX_PROC_CTLS_USE_TPR_SHADOW)) 2661 2799 { 2662 LogFlowFunc(("Running vCPU\n")); 2663 pVCpu->nem.s.Event.fPending = false; 2664 2665 TMNotifyStartOfExecution(pVM, pVCpu); 2666 2667 Assert(!pVCpu->nem.s.fCtxChanged); 2668 hv_return_t hrc; 2669 if (hv_vcpu_run_until) 2670 hrc = hv_vcpu_run_until(pVCpu->nem.s.hVCpuId, HV_DEADLINE_FOREVER); 2671 else 2672 hrc = hv_vcpu_run(pVCpu->nem.s.hVCpuId); 2673 2674 VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED_EXEC_NEM, VMCPUSTATE_STARTED_EXEC_NEM_WAIT); 2675 TMNotifyEndOfExecution(pVM, pVCpu, ASMReadTSC()); 2676 2677 if (hrc == HV_SUCCESS) 2800 uint64_t u64Tpr; 2801 hrc = hv_vcpu_read_register(pVCpu->nem.s.hVCpuId, HV_X86_TPR, &u64Tpr); 2802 Assert(hrc == HV_SUCCESS); 2803 2804 if (VmxTransient.u8GuestTpr != (uint8_t)u64Tpr) 2678 2805 { 2679 /* 2680 * Deal with the message. 2681 */ 2682 rcStrict = nemR3DarwinHandleExit(pVM, pVCpu, &VmxTransient); 2683 if (rcStrict == VINF_SUCCESS) 2684 { /* hopefully likely */ } 2685 else 2686 { 2687 LogFlow(("NEM/%u: breaking: nemR3DarwinHandleExit -> %Rrc\n", pVCpu->idCpu, VBOXSTRICTRC_VAL(rcStrict) )); 2688 STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatBreakOnStatus); 2689 break; 2690 } 2691 //Assert(!pVCpu->cpum.GstCtx.fExtrn); 2806 rc = APICSetTpr(pVCpu, (uint8_t)u64Tpr); 2807 AssertRC(rc); 2808 ASMAtomicUoOrU64(&pVCpu->nem.s.fCtxChanged, HM_CHANGED_GUEST_APIC_TPR); 2692 2809 } 2810 } 2811 2812 if (hrc == HV_SUCCESS) 2813 { 2814 /* 2815 * Deal with the message. 2816 */ 2817 rcStrict = nemR3DarwinHandleExit(pVM, pVCpu, &VmxTransient); 2818 if (rcStrict == VINF_SUCCESS) 2819 { /* hopefully likely */ } 2693 2820 else 2694 2821 { 2695 AssertLogRelMsgFailedReturn(("hv_vcpu_run()) failed for CPU #%u: %#x %u\n",2696 pVCpu->idCpu, hrc, vmxHCCheckGuestState(pVCpu, &pVCpu->nem.s.VmcsInfo)),2697 VERR_NEM_IPE_0);2822 LogFlow(("NEM/%u: breaking: nemR3DarwinHandleExit -> %Rrc\n", pVCpu->idCpu, VBOXSTRICTRC_VAL(rcStrict) )); 2823 STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatBreakOnStatus); 2824 break; 2698 2825 } 2699 2700 /* 2701 * If no relevant FFs are pending, loop. 2702 */ 2703 if ( !VM_FF_IS_ANY_SET( pVM, !fSingleStepping ? VM_FF_HP_R0_PRE_HM_MASK : VM_FF_HP_R0_PRE_HM_STEP_MASK) 2704 && !VMCPU_FF_IS_ANY_SET(pVCpu, !fSingleStepping ? VMCPU_FF_HP_R0_PRE_HM_MASK : VMCPU_FF_HP_R0_PRE_HM_STEP_MASK) ) 2705 continue; 2706 2707 /** @todo Try handle pending flags, not just return to EM loops. Take care 2708 * not to set important RCs here unless we've handled a message. */ 2709 LogFlow(("NEM/%u: breaking: pending FF (%#x / %#RX64)\n", 2710 pVCpu->idCpu, pVM->fGlobalForcedActions, (uint64_t)pVCpu->fLocalForcedActions)); 2711 STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatBreakOnFFPost); 2826 //Assert(!pVCpu->cpum.GstCtx.fExtrn); 2712 2827 } 2713 2828 else 2714 2829 { 2715 LogFlow(("NEM/%u: breaking: canceled %d (pre exec)\n", pVCpu->idCpu, VMCPU_GET_STATE(pVCpu) )); 2716 STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatBreakOnCancel); 2830 AssertLogRelMsgFailedReturn(("hv_vcpu_run()) failed for CPU #%u: %#x %u\n", 2831 pVCpu->idCpu, hrc, vmxHCCheckGuestState(pVCpu, &pVCpu->nem.s.VmcsInfo)), 2832 VERR_NEM_IPE_0); 2717 2833 } 2834 2835 /* 2836 * If no relevant FFs are pending, loop. 2837 */ 2838 if ( !VM_FF_IS_ANY_SET( pVM, !fSingleStepping ? VM_FF_HP_R0_PRE_HM_MASK : VM_FF_HP_R0_PRE_HM_STEP_MASK) 2839 && !VMCPU_FF_IS_ANY_SET(pVCpu, !fSingleStepping ? VMCPU_FF_HP_R0_PRE_HM_MASK : VMCPU_FF_HP_R0_PRE_HM_STEP_MASK) ) 2840 continue; 2841 2842 /** @todo Try handle pending flags, not just return to EM loops. Take care 2843 * not to set important RCs here unless we've handled a message. */ 2844 LogFlow(("NEM/%u: breaking: pending FF (%#x / %#RX64)\n", 2845 pVCpu->idCpu, pVM->fGlobalForcedActions, (uint64_t)pVCpu->fLocalForcedActions)); 2846 STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatBreakOnFFPost); 2718 2847 } 2719 2848 else … … 2926 3055 void *pvMmio2, uint8_t *pu2State, uint32_t *puNemRange) 2927 3056 { 2928 RT_NOREF(pVM );3057 RT_NOREF(pVM, puNemRange); 2929 3058 2930 3059 Log5(("NEMR3NotifyPhysMmioExUnmap: %RGp LB %RGp fFlags=%#x pvRam=%p pvMmio2=%p pu2State=%p uNemRange=%#x (%#x)\n", -
trunk/src/VBox/VMM/include/NEMInternal.h
r92495 r92499 559 559 /** @name Statistics 560 560 * @{ */ 561 STAMCOUNTER StatExitAll; 561 562 STAMCOUNTER StatBreakOnCancel; 562 563 STAMCOUNTER StatBreakOnFFPre; … … 567 568 STAMCOUNTER StatImportOnReturnSkipped; 568 569 STAMCOUNTER StatQueryCpuTick; 570 #ifdef VBOX_WITH_STATISTICS 571 STAMPROFILEADV StatProfGstStateImport; 572 STAMPROFILEADV StatProfGstStateExport; 573 #endif 569 574 /** @} */ 570 575
Note:
See TracChangeset
for help on using the changeset viewer.

