Changeset 54224 in vbox for trunk/src/VBox/HostDrivers/Support
- Timestamp:
- Feb 16, 2015 10:41:32 PM (10 years ago)
- svn:sync-xref-src-repo-rev:
- 98289
- Location:
- trunk/src/VBox/HostDrivers/Support
- Files:
-
- 1 added
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostDrivers/Support/Makefile.kmk
r54046 r54224 43 43 LIBRARIES += SUPR0 44 44 endif 45 endif 46 if !defined(VBOX_ONLY_BUILD) && defined(VBOX_WITH_RAW_MODE) 47 LIBRARIES += SUPRC 45 48 endif 46 49 if !defined(VBOX_ONLY_DOCS) \ … … 152 155 SUPLibSem.cpp \ 153 156 SUPLibTracerA.asm \ 157 SUPLibAll.cpp \ 154 158 SUPR3HardenedIPRT.cpp \ 155 159 SUPR3HardenedVerify.cpp \ … … 460 464 461 465 # 466 # SUPRC - The raw-mode context library. 467 # 468 SUPRC_TEMPLATE = VBoxRc 469 SUPRC_SOURCES = SUPLibAll.cpp 470 471 472 # 462 473 # SUPR0IdcClient - The Ring-0 IDC client driver library. 463 474 # … … 507 518 os2/SUPDrv-os2.cpp \ 508 519 SUPDrv.c \ 509 SUPDrvSem.c 520 SUPDrvSem.c \ 521 SUPLibAll.cpp 510 522 511 523 endif # os2 … … 523 535 $(PATH_SUB_CURRENT)/$(KBUILD_TARGET)/SUPDrv-$(KBUILD_TARGET).def \ 524 536 SUPDrv.c \ 525 SUPDrvSem.c 537 SUPDrvSem.c \ 538 SUPLibAll.cpp 526 539 ## @todo the SUPDrv-freebsd.def is most probably gonna break it and require build system hacking... 527 540 … … 644 657 SUPDrv.c \ 645 658 SUPDrvSem.c \ 646 SUPDrvTracer.cpp 659 SUPDrvTracer.cpp \ 660 SUPLibAll.cpp 647 661 ifdef VBOX_WITH_NATIVE_DTRACE 648 662 VBoxDrv_SOURCES += \ -
trunk/src/VBox/HostDrivers/Support/SUPDrv.c
r54214 r54224 164 164 static int supdrvIOCtl_MsrProber(PSUPDRVDEVEXT pDevExt, PSUPMSRPROBER pReq); 165 165 static int supdrvIOCtl_TscDeltaMeasure(PSUPDRVDEVEXT pDevExt, PSUPTSCDELTAMEASURE pReq); 166 static int supdrvIOCtl_TscRead(PSUPDRVDEVEXT pDevExt, PSUP TSCREAD pReq);166 static int supdrvIOCtl_TscRead(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, PSUPTSCREAD pReq); 167 167 static int supdrvGipCreate(PSUPDRVDEVEXT pDevExt); 168 168 static void supdrvGipDestroy(PSUPDRVDEVEXT pDevExt); … … 2262 2262 REQ_CHECK_SIZES(SUP_IOCTL_TSC_READ); 2263 2263 2264 pReqHdr->rc = supdrvIOCtl_TscRead(pDevExt, p Req);2264 pReqHdr->rc = supdrvIOCtl_TscRead(pDevExt, pSession, pReq); 2265 2265 return 0; 2266 2266 } … … 6140 6140 6141 6141 /** 6142 * Applies the TSC delta to the supplied raw TSC value. 6143 * 6144 * @returns VBox status code. (Ignored by all users, just FYI.) 6145 * @param pGip Pointer to the GIP. 6146 * @param puTsc Pointer to a valid TSC value before the TSC delta has been applied. 6147 * @param idApic The APIC ID of the CPU @c puTsc corresponds to. 6148 * @param fDeltaApplied Where to store whether the TSC delta was succesfully 6149 * applied or not (optional, can be NULL). 6150 * 6151 * @remarks Maybe called with interrupts disabled in ring-0! 6152 * 6153 * @note Don't you dare change the delta calculation. If you really do, make 6154 * sure you update all places where it's used (IPRT, SUPLibAll.cpp, 6155 * SUPDrv.c, supdrvGipMpEvent, and more). 6156 */ 6157 DECLINLINE(int) supdrvTscDeltaApply(PSUPGLOBALINFOPAGE pGip, uint64_t *puTsc, uint16_t idApic, bool *pfDeltaApplied) 6158 { 6159 int rc; 6160 6161 /* 6162 * Validate input. 6163 */ 6164 AssertPtr(puTsc); 6165 AssertPtr(pGip); 6166 Assert(GIP_ARE_TSC_DELTAS_APPLICABLE(pGip)); 6167 6168 /* 6169 * Carefully convert the idApic into a GIPCPU entry. 6170 */ 6171 if (RT_LIKELY(idApic < RT_ELEMENTS(pGip->aiCpuFromApicId))) 6172 { 6173 uint16_t iCpu = pGip->aiCpuFromApicId[idApic]; 6174 if (RT_LIKELY(iCpu < pGip->cCpus)) 6175 { 6176 PSUPGIPCPU pGipCpu = &pGip->aCPUs[iCpu]; 6177 6178 /* 6179 * Apply the delta if valid. 6180 */ 6181 if (RT_LIKELY(pGipCpu->i64TSCDelta != INT64_MAX)) 6182 { 6183 *puTsc -= pGipCpu->i64TSCDelta; 6184 if (pfDeltaApplied) 6185 *pfDeltaApplied = true; 6186 return VINF_SUCCESS; 6187 } 6188 6189 rc = VINF_SUCCESS; 6190 } 6191 else 6192 { 6193 AssertMsgFailed(("iCpu=%u cCpus=%u\n", iCpu, pGip->cCpus)); 6194 rc = VERR_INVALID_CPU_INDEX; 6195 } 6196 } 6197 else 6198 { 6199 AssertMsgFailed(("idApic=%u\n", idApic)); 6200 rc = VERR_INVALID_CPU_ID; 6201 } 6202 if (pfDeltaApplied) 6203 *pfDeltaApplied = false; 6204 return rc; 6205 } 6206 6207 6208 /** 6142 6209 * Measures the TSC frequency of the system. 6143 6210 * … … 6222 6289 bool fAppliedBefore; 6223 6290 bool fAppliedAfter; 6224 rc = SUPTscDeltaApply(pGip, &u64TscBefore, idApicBefore, &fAppliedBefore); AssertRCReturn(rc, rc);6225 rc = SUPTscDeltaApply(pGip, &u64TscAfter, idApicAfter, &fAppliedAfter); AssertRCReturn(rc, rc);6291 rc = supdrvTscDeltaApply(pGip, &u64TscBefore, idApicBefore, &fAppliedBefore); AssertRCReturn(rc, rc); 6292 rc = supdrvTscDeltaApply(pGip, &u64TscAfter, idApicAfter, &fAppliedAfter); AssertRCReturn(rc, rc); 6226 6293 6227 6294 if ( !fAppliedBefore … … 6296 6363 ASMSetFlags(uFlags); 6297 6364 if (GIP_ARE_TSC_DELTAS_APPLICABLE(pGip)) 6298 SUPTscDeltaApply(pGip, &u64Tsc, idApic, &fDeltaApplied);6365 supdrvTscDeltaApply(pGip, &u64Tsc, idApic, &fDeltaApplied); 6299 6366 u64DeltaNanoTS = u64NanoTS - pDevExt->u64NanoTSAnchor; 6300 6367 u64DeltaTsc = u64Tsc - pDevExt->u64TscAnchor; … … 6371 6438 ASMSetFlags(uFlags); 6372 6439 if (GIP_ARE_TSC_DELTAS_APPLICABLE(pGip)) 6373 SUPTscDeltaApply(pGip, &pDevExt->u64TscAnchor, idApic, &fDeltaApplied);6440 supdrvTscDeltaApply(pGip, &pDevExt->u64TscAnchor, idApic, &fDeltaApplied); 6374 6441 6375 6442 #ifdef SUPDRV_USE_TSC_DELTA_THREAD … … 6684 6751 */ 6685 6752 Assert(!ASMIntAreEnabled()); 6686 SUPTscDeltaApply(pGip, &u64TSC, ASMGetApicId(), NULL /* pfDeltaApplied */);6753 supdrvTscDeltaApply(pGip, &u64TSC, ASMGetApicId(), NULL /* pfDeltaApplied */); 6687 6754 } 6688 6755 … … 8077 8144 8078 8145 /** 8079 * Reads the TSC and TSC-delta atomically, applies the TSC delta. 8146 * Reads TSC with delta applied. 8147 * 8148 * Will try to resolve delta value INT64_MAX before applying it. This is the 8149 * main purpose of this function, to handle the case where the delta needs to be 8150 * determined. 8080 8151 * 8081 8152 * @returns VBox status code. 8082 8153 * @param pDevExt Pointer to the device instance data. 8154 * @param pSession The support driver session. 8083 8155 * @param pReq Pointer to the TSC-read request. 8084 8156 */ 8085 static int supdrvIOCtl_TscRead(PSUPDRVDEVEXT pDevExt, PSUPTSCREAD pReq) 8086 { 8087 uint64_t uTsc; 8088 uint16_t idApic; 8089 int16_t cTries; 8157 static int supdrvIOCtl_TscRead(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, PSUPTSCREAD pReq) 8158 { 8090 8159 PSUPGLOBALINFOPAGE pGip; 8091 8160 int rc; 8092 8161 8093 8162 /* 8094 * Validate. 8095 * /8096 AssertReturn(pDevExt, VERR_INVALID_PARAMETER);8097 Assert Return(pReq, VERR_INVALID_PARAMETER);8098 AssertReturn(pDevExt->pGip, VERR_INVALID_PARAMETER);8099 8163 * Validate. We require the client to have mapped GIP (no asserting on 8164 * ring-3 preconditions). 8165 */ 8166 AssertPtr(pDevExt); AssertPtr(pReq); AssertPtr(pSession); /* paranoia^2 */ 8167 if (pSession->GipMapObjR3 == NIL_RTR0MEMOBJ) 8168 return VERR_WRONG_ORDER; 8100 8169 pGip = pDevExt->pGip; 8101 Assert(GIP_ARE_TSC_DELTAS_APPLICABLE(pGip)); 8102 8103 cTries = 4; 8104 while (cTries-- > 0) 8105 { 8106 int rc2; 8107 uint16_t iCpu; 8108 8109 rc = SUPGetTsc(&uTsc, &idApic); 8110 if (RT_SUCCESS(rc)) 8111 { 8112 pReq->u.Out.u64AdjustedTsc = uTsc; 8113 pReq->u.Out.idApic = idApic; 8114 return VINF_SUCCESS; 8115 } 8116 8117 /* If we failed to have a TSC-delta, measurement the TSC-delta and retry. */ 8118 AssertMsgReturn(idApic < RT_ELEMENTS(pGip->aiCpuFromApicId), 8119 ("idApic=%u ArraySize=%u\n", idApic, RT_ELEMENTS(pGip->aiCpuFromApicId)), VERR_INVALID_CPU_INDEX); 8120 iCpu = pGip->aiCpuFromApicId[idApic]; 8121 AssertMsgReturn(iCpu < pGip->cCpus, ("iCpu=%u cCpus=%u\n", iCpu, pGip->cCpus), VERR_INVALID_CPU_INDEX); 8122 8123 rc2 = supdrvMeasureTscDeltaOne(pDevExt, iCpu); 8124 if (RT_SUCCESS(rc2)) 8125 AssertReturn(pGip->aCPUs[iCpu].i64TSCDelta != INT64_MAX, VERR_INTERNAL_ERROR_2); 8170 AssertReturn(pGip, VERR_INTERNAL_ERROR_2); 8171 8172 /* 8173 * We're usually here because we need to apply delta, but we shouldn't be 8174 * upset if the GIP is some different mode. 8175 */ 8176 if (GIP_ARE_TSC_DELTAS_APPLICABLE(pGip)) 8177 { 8178 uint32_t cTries = 0; 8179 for (;;) 8180 { 8181 /* 8182 * Start by gathering the data, using CLI for disabling preemption 8183 * while we do that. 8184 */ 8185 RTCCUINTREG uFlags = ASMIntDisableFlags(); 8186 int iCpuSet = RTMpCpuIdToSetIndex(RTMpCpuId()); 8187 int iGipCpu; 8188 if (RT_LIKELY( (unsigned)iCpuSet < RT_ELEMENTS(pGip->aiCpuFromCpuSetIdx) 8189 && (iGipCpu = pGip->aiCpuFromCpuSetIdx[iCpuSet]) < pGip->cCpus )) 8190 { 8191 int64_t i64Delta = pGip->aCPUs[iGipCpu].i64TSCDelta; 8192 pReq->u.Out.idApic = pGip->aCPUs[iGipCpu].idApic; 8193 pReq->u.Out.u64AdjustedTsc = ASMReadTSC(); 8194 ASMSetFlags(uFlags); 8195 8196 /* 8197 * If we're lucky we've got a delta, but no predicitions here 8198 * as this I/O control is normally only used when the TSC delta 8199 * is set to INT64_MAX. 8200 */ 8201 if (i64Delta != INT64_MAX) 8202 { 8203 pReq->u.Out.u64AdjustedTsc -= i64Delta; 8204 rc = VINF_SUCCESS; 8205 break; 8206 } 8207 8208 /* Give up after a few times. */ 8209 if (cTries >= 4) 8210 { 8211 rc = VERR_INTERNAL_ERROR_3; /** @todo change to warning. */ 8212 break; 8213 } 8214 8215 /* Need to measure the delta an try again. */ 8216 rc = supdrvMeasureTscDeltaOne(pDevExt, iGipCpu); 8217 Assert(pGip->aCPUs[iGipCpu].i64TSCDelta != INT64_MAX || RT_FAILURE_NP(rc)); 8218 } 8219 else 8220 { 8221 /* This really shouldn't happen. */ 8222 AssertMsgFailed(("idCpu=%#x iCpuSet=%#x (%d)\n", RTMpCpuId(), iCpuSet, iCpuSet)); 8223 pReq->u.Out.idApic = ASMGetApicId(); 8224 pReq->u.Out.u64AdjustedTsc = ASMReadTSC(); 8225 ASMSetFlags(uFlags); 8226 rc = VERR_INTERNAL_ERROR_5; /** @todo change to warning. */ 8227 break; 8228 } 8229 } 8230 } 8231 else 8232 { 8233 /* 8234 * No delta to apply. Easy. Deal with preemption the lazy way. 8235 */ 8236 RTCCUINTREG uFlags = ASMIntDisableFlags(); 8237 int iCpuSet = RTMpCpuIdToSetIndex(RTMpCpuId()); 8238 int iGipCpu; 8239 if (RT_LIKELY( (unsigned)iCpuSet < RT_ELEMENTS(pGip->aiCpuFromCpuSetIdx) 8240 && (iGipCpu = pGip->aiCpuFromCpuSetIdx[iCpuSet]) < pGip->cCpus )) 8241 pReq->u.Out.idApic = pGip->aCPUs[iGipCpu].idApic; 8242 else 8243 pReq->u.Out.idApic = ASMGetApicId(); 8244 pReq->u.Out.u64AdjustedTsc = ASMReadTSC(); 8245 ASMSetFlags(uFlags); 8246 rc = VINF_SUCCESS; 8126 8247 } 8127 8248 -
trunk/src/VBox/HostDrivers/Support/SUPDrvIOC.h
r54208 r54224 5 5 6 6 /* 7 * Copyright (C) 2006-201 4Oracle Corporation7 * Copyright (C) 2006-2015 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 213 213 * 214 214 * @todo Pending work on next major version change: 215 * - (none).215 * - Fix SUPTSCREAD padding (#if 0 -> #if 1). 216 216 */ 217 217 #define SUPDRV_IOC_VERSION 0x001e0000 … … 1520 1520 1521 1521 /** @name SUP_IOCTL_TSC_READ 1522 * Reads the TSC and TSC-delta atomically and returns the delta-adjusted TSC 1523 * value. 1522 * Reads the TSC and apply TSC-delta if applicable, determining the delta if 1523 * necessary (i64TSCDelta = INT64_MAX). 1524 * 1525 * This latter function is the primary use case of this I/O control. To call 1526 * this I/O control, the client must first have mapped the GIP. 1524 1527 * 1525 1528 * @{ … … 1544 1547 uint16_t idApic; 1545 1548 /** Padding for future. */ 1549 #if 0 /* Not correct for 32-bit gcc. */ 1550 uint16_t auPadding[3 + 3*4]; 1551 #else 1546 1552 uint64_t auPadding[3]; 1553 #endif 1547 1554 } Out; 1548 1555 } u; 1549 1556 } SUPTSCREAD, *PSUPTSCREAD; 1550 1557 AssertCompileMemberAlignment(SUPTSCREAD, u, 8); 1558 #if 0 /* Not correct for 32-bit gcc. */ 1559 AssertCompileSize(SUPTSCREAD, 6*4 + 5*8); 1560 #endif 1551 1561 /** @} */ 1552 1562 -
trunk/src/VBox/HostDrivers/Support/freebsd/Makefile
r43435 r54224 5 5 6 6 # 7 # 8 # Copyright (C) 2006-2012 Oracle Corporation 7 # Copyright (C) 2006-2015 Oracle Corporation 9 8 # 10 9 # This file is part of VirtualBox Open Source Edition (OSE), as … … 40 39 SUPDrvSem.c \ 41 40 SUPDrvTracer.c \ 41 SUPLibAll.c \ 42 42 43 43 # Include needed interface headers so they are created during build -
trunk/src/VBox/HostDrivers/Support/freebsd/files_vboxdrv
r53480 r54224 6 6 7 7 # 8 # Copyright (C) 2007-201 0Oracle Corporation8 # Copyright (C) 2007-2015 Oracle Corporation 9 9 # 10 10 # This file is part of VirtualBox Open Source Edition (OSE), as … … 92 92 ${PATH_ROOT}/src/VBox/HostDrivers/Support/SUPDrvIOC.h=>SUPDrvIOC.h \ 93 93 ${PATH_ROOT}/src/VBox/HostDrivers/Support/SUPDrvInternal.h=>SUPDrvInternal.h \ 94 ${PATH_ROOT}/src/VBox/HostDrivers/Support/SUPLibAll.cpp=>SUPLibAll.c \ 94 95 ${PATH_ROOT}/src/VBox/Runtime/common/alloc/heapsimple.cpp=>alloc/heapsimple.c \ 95 96 ${PATH_ROOT}/src/VBox/Runtime/common/alloc/alloc.cpp=>alloc/alloc.c \ -
trunk/src/VBox/HostDrivers/Support/linux/files_vboxdrv
r53476 r54224 6 6 7 7 # 8 # Copyright (C) 2007-201 2Oracle Corporation8 # Copyright (C) 2007-2015 Oracle Corporation 9 9 # 10 10 # This file is part of VirtualBox Open Source Edition (OSE), as … … 87 87 ${PATH_ROOT}/src/VBox/HostDrivers/Support/SUPDrvIOC.h=>SUPDrvIOC.h \ 88 88 ${PATH_ROOT}/src/VBox/HostDrivers/Support/SUPDrvInternal.h=>SUPDrvInternal.h \ 89 ${PATH_ROOT}/src/VBox/HostDrivers/Support/SUPLibAll.cpp=>SUPLibAll.c \ 89 90 ${PATH_ROOT}/src/VBox/Runtime/common/alloc/alloc.cpp=>common/alloc/alloc.c \ 90 91 ${PATH_ROOT}/src/VBox/Runtime/common/alloc/heapsimple.cpp=>common/alloc/heapsimple.c \
Note:
See TracChangeset
for help on using the changeset viewer.