- Timestamp:
- May 13, 2011 10:18:29 AM (14 years ago)
- svn:sync-xref-src-repo-rev:
- 71699
- Location:
- trunk/src/VBox
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostDrivers/Support/SUPDrv.c
r36730 r37062 322 322 { "RTMpIsCpuOnline", (void *)RTMpIsCpuOnline }, 323 323 { "RTMpIsCpuWorkPending", (void *)RTMpIsCpuWorkPending }, 324 { "RTMpNotificationRegister", (void *)RTMpNotificationRegister }, 325 { "RTMpNotificationDeregister", (void *)RTMpNotificationDeregister }, 324 326 { "RTMpOnAll", (void *)RTMpOnAll }, 325 327 { "RTMpOnOthers", (void *)RTMpOnOthers }, … … 4990 4992 4991 4993 /** 4994 * Helper for finding the CPU index from the CPU Id. 4995 * 4996 * @param pGip The GIP. 4997 * @param idCpu The CPU ID. 4998 * 4999 * @returns Index of the CPU in the cache set. 5000 */ 5001 static inline uint32_t supdrvGipCpuIndexFromCpuId(PSUPGLOBALINFOPAGE pGip, RTCPUID idCpu) 5002 { 5003 uint32_t i = 0; 5004 5005 /* 5006 * Find our entry, or allocate one if not found. 5007 * ASSUMES that CPU IDs are constant. 5008 */ 5009 for (i = 0; i < pGip->cCpus; i++) 5010 if (pGip->aCPUs[i].idCpu == idCpu) 5011 break; 5012 5013 if (i >= pGip->cCpus) 5014 for (i = 0; i < pGip->cCpus; i++) 5015 { 5016 bool fRc; 5017 ASMAtomicCmpXchgSize(&pGip->aCPUs[i].idCpu, idCpu, NIL_RTCPUID, fRc); 5018 if (fRc) 5019 break; 5020 } 5021 5022 AssertRelease(i < pGip->cCpus); 5023 return i; 5024 } 5025 5026 5027 /** 4992 5028 * The calling CPU should be accounted as online, update GIP accordingly. 4993 5029 * … … 4999 5035 static void supdrvGipMpEventOnline(PSUPGLOBALINFOPAGE pGip, RTCPUID idCpu) 5000 5036 { 5001 int iCpuSet ;5002 uint 8_t idApic;5003 uint32_t i ;5004 5005 Assert (idCpu == RTMpCpuId());5037 int iCpuSet = 0; 5038 uint16_t idApic = UINT16_MAX; 5039 uint32_t i = 0; 5040 5041 AssertRelease(idCpu == RTMpCpuId()); 5006 5042 Assert(pGip->cPossibleCpus == RTMpGetCount()); 5007 5043 … … 5019 5055 } 5020 5056 5021 /* 5022 * Find our entry, or allocate one if not found. 5023 * ASSUMES that CPU IDs are constant. 5024 */ 5025 for (i = 0; i < pGip->cCpus; i++) 5026 if (pGip->aCPUs[i].idCpu == idCpu) 5027 break; 5028 5029 if (i >= pGip->cCpus) 5030 for (i = 0; i < pGip->cCpus; i++) 5031 { 5032 bool fRc; 5033 ASMAtomicCmpXchgSize(&pGip->aCPUs[i].idCpu, idCpu, NIL_RTCPUID, fRc); 5034 if (fRc) 5035 break; 5036 } 5037 5038 AssertReturnVoid(i < pGip->cCpus); 5057 i = supdrvGipCpuIndexFromCpuId(pGip, idCpu); 5039 5058 5040 5059 /* … … 5045 5064 ASMAtomicUoWriteS16(&pGip->aCPUs[i].iCpuSet, (int16_t)iCpuSet); 5046 5065 ASMAtomicUoWriteSize(&pGip->aCPUs[i].idCpu, idCpu); 5047 ASMAtomicWriteSize(&pGip->aCPUs[i].enmState, SUPGIPCPUSTATE_ONLINE);5048 5066 5049 5067 /* … … 5052 5070 ASMAtomicWriteU16(&pGip->aiCpuFromApicId[idApic], i); 5053 5071 ASMAtomicWriteU16(&pGip->aiCpuFromCpuSetIdx[iCpuSet], i); 5072 5073 ASMAtomicWriteSize(&pGip->aCPUs[i].enmState, SUPGIPCPUSTATE_ONLINE); 5054 5074 } 5055 5075 … … 5076 5096 5077 5097 Assert(RTCpuSetIsMemberByIndex(&pGip->PossibleCpuSet, iCpuSet)); 5098 RTCpuSetDelByIndex(&pGip->OnlineCpuSet, iCpuSet); 5078 5099 ASMAtomicWriteSize(&pGip->aCPUs[i].enmState, SUPGIPCPUSTATE_OFFLINE); 5079 RTCpuSetDelByIndex(&pGip->OnlineCpuSet, iCpuSet);5080 5100 } 5081 5101 … … 5095 5115 PSUPDRVDEVEXT pDevExt = (PSUPDRVDEVEXT)pvUser; 5096 5116 PSUPGLOBALINFOPAGE pGip = pDevExt->pGip; 5117 5118 AssertRelease(!RTThreadPreemptIsEnabled(NIL_RTTHREAD)); 5097 5119 5098 5120 /* … … 5359 5381 pGip->aCPUs[i].idCpu = NIL_RTCPUID; 5360 5382 pGip->aCPUs[i].iCpuSet = -1; 5361 pGip->aCPUs[i].idApic = UINT 8_MAX;5383 pGip->aCPUs[i].idApic = UINT16_MAX; 5362 5384 5363 5385 /* … … 5618 5640 RTCPUID idCpu, uint8_t idApic, uint64_t iTick) 5619 5641 { 5642 /* 5643 * Avoid a potential race when a CPU online notification doesn't fire on the onlined CPU 5644 * but the tick creeps in before the event notification is run. 5645 */ 5646 if (iTick == 1) 5647 { 5648 uint32_t i = supdrvGipCpuIndexFromCpuId(pGip, idCpu); 5649 if (pGip->aCPUs[i].enmState == SUPGIPCPUSTATE_OFFLINE) 5650 supdrvGipMpEventOnline(pGip, idCpu); 5651 } 5652 5620 5653 unsigned iCpu = pGip->aiCpuFromApicId[idApic]; 5621 5654 -
trunk/src/VBox/Runtime/r0drv/solaris/vbi/mp-r0drv-solaris.c
r36232 r37062 174 174 PRTMPARGS pArgs = (PRTMPARGS)(uArg); 175 175 176 /* 177 * Solaris CPU cross calls execute on offline CPUs too. Check our CPU cache 178 * set and ignore if it's offline. 179 */ 180 if (!RTMpIsCpuOnline(RTMpCpuId())) 181 return 0; 182 176 183 pArgs->pfnWorker(RTMpCpuId(), pArgs->pvUser1, pArgs->pvUser2); 177 184 … … 279 286 return VERR_CPU_NOT_FOUND; 280 287 288 if (RT_UNLIKELY(!RTMpIsCpuOnline(idCpu))) 289 return RTMpIsCpuPresent(idCpu) ? VERR_CPU_OFFLINE : VERR_CPU_NOT_FOUND; 290 281 291 Args.pfnWorker = pfnWorker; 282 292 Args.pvUser1 = pvUser1; -
trunk/src/VBox/Runtime/r0drv/solaris/vbi/mpnotification-r0drv-solaris.c
r36555 r37062 34 34 #include <iprt/mp.h> 35 35 #include <iprt/cpuset.h> 36 #include <iprt/string.h> 36 37 #include "r0drv/mp-r0drv.h" 37 38 … … 49 50 50 51 51 static void rtMpNotificationSolaris Callback(void *pvUser, int iCpu, int online)52 static void rtMpNotificationSolarisOnCurrentCpu(void *pvArgs, void *uIgnored1, void *uIgnored2) 52 53 { 53 NOREF(pvUser); 54 NOREF(uIgnored1); 55 NOREF(uIgnored2); 54 56 55 /* ASSUMES iCpu == RTCPUID */ 57 PRTMPARGS pArgs = (PRTMPARGS)(pvArgs); 58 AssertRelease(pArgs && pArgs->idCpu == RTMpCpuId()); 59 Assert(pArgs->pvUser2); 60 Assert(!RTThreadPreemptIsEnabled(NIL_RTTHREAD)); 61 62 int online = *(int *)pArgs->pvUser2; 56 63 if (online) 57 64 { 58 RTCpuSetAdd(&g_rtMpSolarisCpuSet, iCpu);59 rtMpNotificationDoCallbacks(RTMPEVENT_ONLINE, iCpu);65 RTCpuSetAdd(&g_rtMpSolarisCpuSet, pArgs->idCpu); 66 rtMpNotificationDoCallbacks(RTMPEVENT_ONLINE, pArgs->idCpu); 60 67 } 61 68 else 62 69 { 63 RTCpuSetDel(&g_rtMpSolarisCpuSet, iCpu);64 rtMpNotificationDoCallbacks(RTMPEVENT_OFFLINE, iCpu);70 RTCpuSetDel(&g_rtMpSolarisCpuSet, pArgs->idCpu); 71 rtMpNotificationDoCallbacks(RTMPEVENT_OFFLINE, pArgs->idCpu); 65 72 } 73 } 74 75 76 static void rtMpNotificationSolarisCallback(void *pvUser, int iCpu, int online) 77 { 78 vbi_preempt_disable(); 79 80 RTMPARGS Args; 81 RT_ZERO(Args); 82 Args.pvUser1 = pvUser; 83 Args.pvUser2 = &online; 84 Args.idCpu = iCpu; 85 86 /* 87 * If we're not on the target CPU, schedule (synchronous) the event notification callback 88 * to run on the target CPU i.e. the one pertaining to the MP event. 89 */ 90 bool fRunningOnTargetCpu = iCpu == RTMpCpuId(); /* ASSUMES iCpu == RTCPUID */ 91 if (fRunningOnTargetCpu) 92 rtMpNotificationSolarisOnCurrentCpu(&Args, NULL /* pvIgnored1 */, NULL /* pvIgnored2 */); 93 else 94 vbi_execute_on_one(rtMpNotificationSolarisOnCurrentCpu, &Args, iCpu); 95 96 vbi_preempt_enable(); 66 97 } 67 98 -
trunk/src/VBox/VMM/VMMR0/HWACCMR0.cpp
r36913 r37062 51 51 static bool hwaccmR0IsSubjectToVmxPreemptionTimerErratum(void); 52 52 static DECLCALLBACK(void) hwaccmR0PowerCallback(RTPOWEREVENT enmEvent, void *pvUser); 53 static DECLCALLBACK(void) hwaccmR0CpuCallback(RTMPEVENT enmEvent, RTCPUID idCpu, void *pvData); 53 54 54 55 /******************************************************************************* … … 498 499 if (!HWACCMR0Globals.vmx.fUsingSUPR0EnableVTx) 499 500 { 501 rc = RTMpNotificationRegister(hwaccmR0CpuCallback, 0); 502 AssertRC(rc); 503 500 504 rc = RTPowerNotificationRegister(hwaccmR0PowerCallback, 0); 501 505 AssertRC(rc); … … 575 579 if (!HWACCMR0Globals.vmx.fUsingSUPR0EnableVTx) 576 580 { 581 /* Doesn't really matter if this fails. */ 582 rc = RTMpNotificationDeregister(hwaccmR0CpuCallback, 0); 583 AssertRC(rc); 577 584 rc = RTPowerNotificationDeregister(hwaccmR0PowerCallback, 0); 578 585 AssertRC(rc); … … 732 739 Assert(!HWACCMR0Globals.aCpuInfo[i].pMemObj); 733 740 734 /** @todo this is rather dangerous if cpus can be taken offline; we don't care for now */ 735 if (RTMpIsCpuOnline(i)) 741 if (RTMpIsCpuPossible(RTMpCpuId())) 736 742 { 737 743 rc = RTR0MemObjAllocCont(&HWACCMR0Globals.aCpuInfo[i].pMemObj, 1 << PAGE_SHIFT, true /* executable R0 mapping */); … … 748 754 #endif 749 755 } 756 HWACCMR0Globals.aCpuInfo[i].fConfigured = false; 750 757 } 751 758 if (HWACCMR0Globals.fGlobalInit) … … 798 805 if (!pCpu->pMemObj) 799 806 { 807 LogRel(("HWACCMR0: hwaccmR0EnableCpu failed idCpu=%d.\n", idCpu)); 800 808 AssertFailed(); 801 809 return VERR_INTERNAL_ERROR; … … 883 891 hwaccmR0FirstRcSetStatus(pFirstRc, hwaccmR0DisableCpu(idCpu)); 884 892 } 893 894 895 /** 896 * Callback function invoked when a cpu goes online or offline. 897 * 898 * @param enmEvent The Mp event. 899 * @param idCpu The identifier for the CPU the function is called on. 900 * @param pvData Opaque data (PVM pointer). 901 */ 902 static DECLCALLBACK(void) hwaccmR0CpuCallback(RTMPEVENT enmEvent, RTCPUID idCpu, void *pvData) 903 { 904 /* 905 * We only care about uninitializing a CPU that is going offline. When a 906 * CPU comes online, the initialization is done lazily in HWACCMR0Enter(). 907 */ 908 AssertRelease(idCpu == RTMpCpuId()); 909 Assert(!RTThreadPreemptIsEnabled(NIL_RTTHREAD)); 910 switch (enmEvent) 911 { 912 case RTMPEVENT_OFFLINE: 913 { 914 int rc = hwaccmR0DisableCpu(idCpu); 915 AssertRC(rc); 916 break; 917 } 918 919 default: 920 break; 921 } 922 } 923 885 924 886 925 /** … … 1129 1168 * 1130 1169 * @returns VBox status code. 1131 * @param pVM 1132 * @param pVCpu VMCPU D id.1170 * @param pVM The VM to operate on. 1171 * @param pVCpu VMCPU handle. 1133 1172 */ 1134 1173 VMMR0DECL(int) HWACCMR0Enter(PVM pVM, PVMCPU pVCpu) … … 1163 1202 pVM->hwaccm.s.u64RegisterMask = UINT64_C(0xFFFFFFFF); 1164 1203 1165 /* Enable VT-x or AMD-V if local init is required. */ 1166 if (!HWACCMR0Globals.fGlobalInit) 1204 /* Enable VT-x or AMD-V if local init is required, or enable if it's a freshly onlined CPU. */ 1205 if ( !pCpu->fConfigured 1206 || !HWACCMR0Globals.fGlobalInit) 1167 1207 { 1168 1208 rc = hwaccmR0EnableCpu(pVM, idCpu); … … 1198 1238 * 1199 1239 * @returns VBox status code. 1200 * @param pVM 1201 * @param pVCpu VMCPU D id.1240 * @param pVM The VM to operate on. 1241 * @param pVCpu VMCPU handle. 1202 1242 */ 1203 1243 VMMR0DECL(int) HWACCMR0Leave(PVM pVM, PVMCPU pVCpu)
Note:
See TracChangeset
for help on using the changeset viewer.