Changeset 10248 in vbox for trunk/src/VBox/HostDrivers
- Timestamp:
- Jul 4, 2008 8:02:38 PM (16 years ago)
- Location:
- trunk/src/VBox/HostDrivers/Support
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostDrivers/Support/SUPDRV.h
r9978 r10248 609 609 /** Spinlock protecting the bundles and the GIP members. */ 610 610 RTSPINLOCK Spinlock; 611 #ifdef USE_NEW_OS_INTERFACE_FOR_GIP612 611 /** The ring-3 mapping of the GIP (readonly). */ 613 612 RTR0MEMOBJ GipMapObjR3; 614 #else615 /** The read-only usermode mapping address of the GID.616 * This is NULL if the GIP hasn't been mapped. */617 PSUPGLOBALINFOPAGE pGip;618 #endif619 613 /** Set if the session is using the GIP. */ 620 614 uint32_t fGipReferenced; … … 698 692 * (The updates are suspend while cGipUsers is 0.)*/ 699 693 uint32_t volatile cGipUsers; 700 #ifdef USE_NEW_OS_INTERFACE_FOR_GIP701 694 /** The ring-0 memory object handle for the GIP page. */ 702 695 RTR0MEMOBJ GipMemObj; … … 708 701 * This CPU is responsible for the updating the common GIP data. */ 709 702 RTCPUID volatile idGipMaster; 710 #else711 # ifdef RT_OS_WINDOWS712 /** The GIP timer object. */713 KTIMER GipTimer;714 /** The GIP DPC object associated with GipTimer. */715 KDPC GipDpc;716 /** The GIP DPC objects for updating per-cpu data. */717 KDPC aGipCpuDpcs[MAXIMUM_PROCESSORS];718 /** Pointer to the MDL for the pGip page. */719 PMDL pGipMdl;720 /** GIP timer interval (ms). */721 ULONG ulGipTimerInterval;722 /** Current CPU affinity mask. */723 KAFFINITY uAffinityMask;724 # endif725 # ifdef RT_OS_LINUX726 /** The last jiffies. */727 unsigned long ulLastJiffies;728 /** The last mono time stamp. */729 uint64_t volatile u64LastMonotime;730 /** Set when GIP is suspended to prevent the timers from re-registering themselves). */731 uint8_t volatile fGIPSuspended;732 # ifdef CONFIG_SMP733 /** Array of per CPU data for SUPGIPMODE_ASYNC_TSC. */734 struct LINUXCPU735 {736 /** The last mono time stamp. */737 uint64_t volatile u64LastMonotime;738 /** The last jiffies. */739 unsigned long ulLastJiffies;740 /** The Linux Process ID. */741 unsigned iSmpProcessorId;742 /** The per cpu timer. */743 VBOXKTIMER Timer;744 } aCPUs[256];745 # endif746 # endif /* LINUX */747 #endif /* !USE_NEW_OS_INTERFACE_FOR_GIP */748 703 } SUPDRVDEVEXT; 749 704 … … 767 722 void VBOXCALL supdrvOSMemFreeOne(PSUPDRVMEMREF pMem); 768 723 #endif 769 #ifndef USE_NEW_OS_INTERFACE_FOR_GIP770 int VBOXCALL supdrvOSGipMap(PSUPDRVDEVEXT pDevExt, PSUPGLOBALINFOPAGE *ppGip);771 int VBOXCALL supdrvOSGipUnmap(PSUPDRVDEVEXT pDevExt, PSUPGLOBALINFOPAGE pGip);772 void VBOXCALL supdrvOSGipResume(PSUPDRVDEVEXT pDevExt);773 void VBOXCALL supdrvOSGipSuspend(PSUPDRVDEVEXT pDevExt);774 #endif775 #ifdef RT_OS_WINDOWS /** @todo remove when RTMpGetCount() has been fixed. */776 unsigned VBOXCALL supdrvOSGetCPUCount(PSUPDRVDEVEXT pDevExt);777 #endif778 724 bool VBOXCALL supdrvOSGetForcedAsyncTscMode(PSUPDRVDEVEXT pDevExt); 779 725 -
trunk/src/VBox/HostDrivers/Support/SUPDRVShared.c
r9960 r10248 249 249 static int supdrvPageGetPhys(PSUPDRVSESSION pSession, RTR3PTR pvR3, uint32_t cPages, PRTHCPHYS paPages); 250 250 static bool supdrvPageWasLockedByPageAlloc(PSUPDRVSESSION pSession, RTR3PTR pvR3); 251 #endif 252 #ifdef USE_NEW_OS_INTERFACE_FOR_GIP 251 #endif /* RT_OS_WINDOWS */ 253 252 static int supdrvGipCreate(PSUPDRVDEVEXT pDevExt); 254 253 static void supdrvGipDestroy(PSUPDRVDEVEXT pDevExt); … … 256 255 static DECLCALLBACK(void) supdrvGipAsyncTimer(PRTTIMER pTimer, void *pvUser, uint64_t iTick); 257 256 static DECLCALLBACK(void) supdrvGipMpEvent(RTMPEVENT enmEvent, RTCPUID idCpu, void *pvUser); 258 #endif259 257 260 258 … … 281 279 if (!rc) 282 280 { 283 #ifdef USE_NEW_OS_INTERFACE_FOR_GIP284 281 rc = supdrvGipCreate(pDevExt); 285 282 if (RT_SUCCESS(rc)) … … 288 285 return VINF_SUCCESS; 289 286 } 290 #else 291 pDevExt->u32Cookie = BIRD; 292 return VINF_SUCCESS; 293 #endif 287 288 RTSemFastMutexDestroy(pDevExt->mtxGip); 289 pDevExt->mtxGip = NIL_RTSEMFASTMUTEX; 294 290 } 295 291 RTSemFastMutexDestroy(pDevExt->mtxLdr); … … 365 361 } 366 362 367 #ifdef USE_NEW_OS_INTERFACE_FOR_GIP368 363 /* kill the GIP */ 369 364 supdrvGipDestroy(pDevExt); 370 #endif371 365 } 372 366 … … 603 597 */ 604 598 Log2(("umapping GIP:\n")); 605 #ifdef USE_NEW_OS_INTERFACE_FOR_GIP606 599 if (pSession->GipMapObjR3 != NIL_RTR0MEMOBJ) 607 #else608 if (pSession->pGip)609 #endif610 600 { 611 601 SUPR0GipUnmap(pSession); 612 #ifndef USE_NEW_OS_INTERFACE_FOR_GIP613 pSession->pGip = NULL;614 #endif615 602 pSession->fGipReferenced = 0; 616 603 } … … 2097 2084 if (ppGipR3) 2098 2085 { 2099 #ifdef USE_NEW_OS_INTERFACE_FOR_GIP2100 2086 if (pSession->GipMapObjR3 == NIL_RTR0MEMOBJ) 2101 2087 rc = RTR0MemObjMapUser(&pSession->GipMapObjR3, pDevExt->GipMemObj, (RTR3PTR)-1, 0, … … 2106 2092 rc = VINF_SUCCESS; /** @todo remove this and replace the !rc below with RT_SUCCESS(rc). */ 2107 2093 } 2108 #else /* !USE_NEW_OS_INTERFACE_FOR_GIP */2109 if (!pSession->pGip)2110 rc = supdrvOSGipMap(pSession->pDevExt, &pSession->pGip);2111 if (!rc)2112 pGip = (RTR3PTR)pSession->pGip;2113 #endif /* !USE_NEW_OS_INTERFACE_FOR_GIP */2114 2094 } 2115 2095 … … 2138 2118 ASMAtomicXchgU64(&pGip->u64NanoTSLastUpdateHz, 0); 2139 2119 2140 #ifdef USE_NEW_OS_INTERFACE_FOR_GIP2141 2120 rc = RTTimerStart(pDevExt->pGipTimer, 0); 2142 2121 AssertRC(rc); rc = VINF_SUCCESS; 2143 #else2144 supdrvOSGipResume(pDevExt);2145 #endif2146 2122 } 2147 2123 } … … 2197 2173 * Unmap anything? 2198 2174 */ 2199 #ifdef USE_NEW_OS_INTERFACE_FOR_GIP2200 2175 if (pSession->GipMapObjR3 != NIL_RTR0MEMOBJ) 2201 2176 { … … 2205 2180 pSession->GipMapObjR3 = NIL_RTR0MEMOBJ; 2206 2181 } 2207 #else2208 if (pSession->pGip)2209 {2210 rc = supdrvOSGipUnmap(pDevExt, pSession->pGip);2211 if (!rc)2212 pSession->pGip = NULL;2213 }2214 #endif2215 2182 2216 2183 /* … … 2224 2191 { 2225 2192 LogFlow(("SUPR0GipUnmap: Suspends GIP updating\n")); 2226 #ifdef USE_NEW_OS_INTERFACE_FOR_GIP2227 2193 rc = RTTimerStop(pDevExt->pGipTimer); AssertRC(rc); rc = 0; 2228 #else2229 supdrvOSGipSuspend(pDevExt);2230 #endif2231 2194 } 2232 2195 } … … 3697 3660 3698 3661 3699 #ifdef USE_NEW_OS_INTERFACE_FOR_GIP3700 3662 /** 3701 3663 * Creates the GIP. … … 3731 3693 HCPhysGip = RTR0MemObjGetPagePhysAddr(pDevExt->GipMemObj, 0); Assert(HCPhysGip != NIL_RTHCPHYS); 3732 3694 3733 #if 0 /** @todo Disabled this as we didn't used to do it before and causes unnecessary stress on laptops. 3695 #if 0 /** @todo Disabled this as we didn't used to do it before and causes unnecessary stress on laptops. 3734 3696 * It only applies to Windows and should probably revisited later, if possible made part of the 3735 3697 * timer code (return min granularity in RTTimerGetSystemGranularity and set it in RTTimerStart). */ … … 3931 3893 } 3932 3894 } 3933 3934 #endif /* USE_NEW_OS_INTERFACE_FOR_GIP */3935 3895 3936 3896 -
trunk/src/VBox/HostDrivers/Support/linux/SUPDrv-linux.c
r9621 r10248 201 201 202 202 /******************************************************************************* 203 * Structures and Typedefs *204 *******************************************************************************/205 #ifndef USE_NEW_OS_INTERFACE_FOR_GIP206 # ifdef VBOX_HRTIMER207 typedef enum hrtimer_restart (*PFNVBOXKTIMER)(struct hrtimer *);208 # else209 typedef void (*PFNVBOXKTIMER)(unsigned long);210 # endif211 #endif212 213 214 /*******************************************************************************215 203 * Global Variables * 216 204 *******************************************************************************/ … … 219 207 */ 220 208 static SUPDRVDEVEXT g_DevExt; 221 222 #ifndef USE_NEW_OS_INTERFACE_FOR_GIP223 /** Timer structure for the GIP update. */224 static VBOXKTIMER g_GipTimer;225 /** Pointer to the page structure for the GIP. */226 struct page *g_pGipPage;227 #endif /* !USE_NEW_OS_INTERFACE_FOR_GIP */228 209 229 210 /** Registered devfs device handle. */ … … 279 260 #endif 280 261 static int VBoxDrvLinuxIOCtlSlow(struct file *pFilp, unsigned int uCmd, unsigned long ulArg); 281 #ifndef USE_NEW_OS_INTERFACE_FOR_GIP282 static int VBoxDrvLinuxInitGip(PSUPDRVDEVEXT pDevExt);283 static int VBoxDrvLinuxTermGip(PSUPDRVDEVEXT pDevExt);284 # ifdef VBOX_HRTIMER285 static enum hrtimer_restart VBoxDrvLinuxGipTimer(struct hrtimer *pTimer);286 # else287 static void VBoxDrvLinuxGipTimer(unsigned long ulUser);288 # endif289 # ifdef CONFIG_SMP290 # ifdef VBOX_HRTIMER291 static enum hrtimer_restart VBoxDrvLinuxGipTimerPerCpu(struct hrtimer *pTimer);292 # else293 static void VBoxDrvLinuxGipTimerPerCpu(unsigned long ulUser);294 # endif295 static void VBoxDrvLinuxGipResumePerCpu(void *pvUser);296 # endif /* CONFIG_SMP */297 #endif /* !USE_NEW_OS_INTERFACE_FOR_GIP */298 262 static int VBoxDrvLinuxErr2LinuxErr(int); 299 263 … … 327 291 328 292 329 #ifndef USE_NEW_OS_INTERFACE_FOR_GIP330 331 static inline void vbox_ktimer_init(PVBOXKTIMER pTimer, PFNVBOXKTIMER pfnFunction, unsigned long ulData)332 {333 #ifdef VBOX_HRTIMER334 hrtimer_init(pTimer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);335 pTimer->function = pfnFunction;336 #else337 init_timer(pTimer);338 pTimer->data = ulData;339 pTimer->function = pfnFunction;340 pTimer->expires = jiffies;341 #endif342 }343 344 static inline void vbox_ktimer_start(PVBOXKTIMER pTimer)345 {346 #ifdef VBOX_HRTIMER347 hrtimer_start(pTimer, ktime_add_ns(ktime_get(), 1000000), HRTIMER_MODE_ABS);348 #else349 mod_timer(pTimer, jiffies);350 #endif351 }352 353 static inline void vbox_ktimer_stop(PVBOXKTIMER pTimer)354 {355 #ifdef VBOX_HRTIMER356 hrtimer_cancel(pTimer);357 #else358 if (timer_pending(pTimer))359 del_timer_sync(pTimer);360 #endif361 }362 363 #endif /* !USE_NEW_OS_INTERFACE_FOR_GIP */364 293 365 294 … … 660 589 if (!rc) 661 590 { 662 #ifndef USE_NEW_OS_INTERFACE_FOR_GIP 663 /* 664 * Create the GIP page. 665 */ 666 rc = VBoxDrvLinuxInitGip(&g_DevExt); 667 if (!rc) 668 #endif /* !USE_NEW_OS_INTERFACE_FOR_GIP */ 669 { 670 printk(KERN_INFO DEVICE_NAME ": TSC mode is %s, kernel timer mode is " 591 printk(KERN_INFO DEVICE_NAME ": TSC mode is %s, kernel timer mode is " 671 592 #ifdef VBOX_HRTIMER 672 593 "'high-res'" 673 594 #else 674 "'normal'" 675 #endif 676 ".\n", 677 g_DevExt.pGip->u32Mode == SUPGIPMODE_SYNC_TSC ? "'synchronous'" : "'asynchronous'"); 678 LogFlow(("VBoxDrv::ModuleInit returning %#x\n", rc)); 679 printk(KERN_DEBUG DEVICE_NAME ": Successfully loaded version " 680 VBOX_VERSION_STRING " (interface " xstr(SUPDRVIOC_VERSION) ").\n"); 681 return rc; 682 } 683 684 supdrvDeleteDevExt(&g_DevExt); 595 "'normal'" 596 #endif 597 ".\n", 598 g_DevExt.pGip->u32Mode == SUPGIPMODE_SYNC_TSC ? "'synchronous'" : "'asynchronous'"); 599 LogFlow(("VBoxDrv::ModuleInit returning %#x\n", rc)); 600 printk(KERN_DEBUG DEVICE_NAME ": Successfully loaded version " 601 VBOX_VERSION_STRING " (interface " xstr(SUPDRVIOC_VERSION) ").\n"); 602 return rc; 685 603 } 686 else 687 604 605 rc = -EINVAL; 688 606 RTR0Term(); 689 607 } … … 741 659 * Destroy GIP, delete the device extension and terminate IPRT. 742 660 */ 743 #ifndef USE_NEW_OS_INTERFACE_FOR_GIP744 VBoxDrvLinuxTermGip(&g_DevExt);745 #endif /* !USE_NEW_OS_INTERFACE_FOR_GIP */746 661 supdrvDeleteDevExt(&g_DevExt); 747 662 RTR0Term(); … … 961 876 962 877 963 #ifndef USE_NEW_OS_INTERFACE_FOR_GIP964 965 /**966 * Initializes the GIP.967 *968 * @returns negative errno.969 * @param pDevExt Instance data. GIP stuff may be updated.970 */971 static int VBoxDrvLinuxInitGip(PSUPDRVDEVEXT pDevExt)972 {973 struct page *pPage;974 dma_addr_t HCPhys;975 PSUPGLOBALINFOPAGE pGip;976 #ifdef CONFIG_SMP977 unsigned i;978 #endif979 LogFlow(("VBoxDrvLinuxInitGip:\n"));980 981 /*982 * Allocate the page.983 */984 pPage = alloc_pages(GFP_USER, 0);985 if (!pPage)986 {987 Log(("VBoxDrvLinuxInitGip: failed to allocate the GIP page\n"));988 return -ENOMEM;989 }990 991 /*992 * Lock the page.993 */994 SetPageReserved(pPage);995 g_pGipPage = pPage;996 997 /*998 * Call common initialization routine.999 */1000 HCPhys = page_to_phys(pPage);1001 pGip = (PSUPGLOBALINFOPAGE)page_address(pPage);1002 pDevExt->ulLastJiffies = jiffies;1003 pDevExt->u64LastMonotime = (uint64_t)pDevExt->ulLastJiffies * TICK_NSEC;1004 Log(("VBoxDrvInitGIP: TICK_NSEC=%ld HZ=%d jiffies=%ld now=%lld\n",1005 TICK_NSEC, HZ, pDevExt->ulLastJiffies, pDevExt->u64LastMonotime));1006 supdrvGipInit(pDevExt, pGip, HCPhys, pDevExt->u64LastMonotime,1007 HZ <= 1000 ? HZ : 1000);1008 1009 /*1010 * Initialize the timer.1011 */1012 vbox_ktimer_init(&g_GipTimer, VBoxDrvLinuxGipTimer, (unsigned long)pDevExt);1013 #ifdef CONFIG_SMP1014 for (i = 0; i < RT_ELEMENTS(pDevExt->aCPUs); i++)1015 {1016 pDevExt->aCPUs[i].u64LastMonotime = pDevExt->u64LastMonotime;1017 pDevExt->aCPUs[i].ulLastJiffies = pDevExt->ulLastJiffies;1018 pDevExt->aCPUs[i].iSmpProcessorId = -512;1019 vbox_ktimer_init(&pDevExt->aCPUs[i].Timer, VBoxDrvLinuxGipTimerPerCpu, i);1020 }1021 #endif1022 1023 return 0;1024 }1025 1026 1027 /**1028 * Terminates the GIP.1029 *1030 * @returns negative errno.1031 * @param pDevExt Instance data. GIP stuff may be updated.1032 */1033 static int VBoxDrvLinuxTermGip(PSUPDRVDEVEXT pDevExt)1034 {1035 struct page *pPage;1036 PSUPGLOBALINFOPAGE pGip;1037 #ifdef CONFIG_SMP1038 unsigned i;1039 #endif1040 LogFlow(("VBoxDrvLinuxTermGip:\n"));1041 1042 /*1043 * Delete the timer if it's pending.1044 */1045 vbox_ktimer_stop(&g_GipTimer);1046 #ifdef CONFIG_SMP1047 for (i = 0; i < RT_ELEMENTS(pDevExt->aCPUs); i++)1048 vbox_ktimer_stop(&pDevExt->aCPUs[i].Timer);1049 #endif1050 1051 /*1052 * Uninitialize the content.1053 */1054 pGip = pDevExt->pGip;1055 pDevExt->pGip = NULL;1056 if (pGip)1057 supdrvGipTerm(pGip);1058 1059 /*1060 * Free the page.1061 */1062 pPage = g_pGipPage;1063 g_pGipPage = NULL;1064 if (pPage)1065 {1066 ClearPageReserved(pPage);1067 __free_pages(pPage, 0);1068 }1069 1070 return 0;1071 }1072 1073 /**1074 * Timer callback function.1075 *1076 * In ASYNC TSC mode this is called on the primary CPU, and we're1077 * assuming that the CPU remains online.1078 *1079 * @param ulUser The device extension pointer.1080 */1081 #ifdef VBOX_HRTIMER1082 static enum hrtimer_restart VBoxDrvLinuxGipTimer(struct hrtimer *pTimer)1083 #else1084 static void VBoxDrvLinuxGipTimer(unsigned long ulUser)1085 #endif1086 {1087 PSUPDRVDEVEXT pDevExt;1088 PSUPGLOBALINFOPAGE pGip;1089 unsigned long ulNow;1090 unsigned long ulDiff;1091 uint64_t u64Monotime;1092 unsigned long SavedFlags;1093 #ifdef VBOX_HRTIMER1094 ktime_t KtNow;1095 #endif1096 1097 local_irq_save(SavedFlags);1098 1099 ulNow = jiffies;1100 #ifdef VBOX_HRTIMER1101 KtNow = ktime_get();1102 pDevExt = &g_DevExt;1103 #else1104 pDevExt = (PSUPDRVDEVEXT)ulUser;1105 #endif1106 pGip = pDevExt->pGip;1107 1108 #ifdef CONFIG_SMP1109 if (pGip && pGip->u32Mode == SUPGIPMODE_ASYNC_TSC)1110 {1111 uint8_t iCPU = ASMGetApicId();1112 ulDiff = ulNow - pDevExt->aCPUs[iCPU].ulLastJiffies;1113 pDevExt->aCPUs[iCPU].ulLastJiffies = ulNow;1114 u64Monotime = pDevExt->aCPUs[iCPU].u64LastMonotime + ulDiff * TICK_NSEC;1115 pDevExt->aCPUs[iCPU].u64LastMonotime = u64Monotime;1116 }1117 else1118 #endif /* CONFIG_SMP */1119 {1120 ulDiff = ulNow - pDevExt->ulLastJiffies;1121 pDevExt->ulLastJiffies = ulNow;1122 u64Monotime = pDevExt->u64LastMonotime + ulDiff * TICK_NSEC;1123 pDevExt->u64LastMonotime = u64Monotime;1124 }1125 if (RT_LIKELY(pGip))1126 supdrvGipUpdate(pDevExt->pGip, u64Monotime);1127 if (RT_LIKELY(!pDevExt->fGIPSuspended))1128 {1129 #ifdef VBOX_HRTIMER1130 hrtimer_forward(&g_GipTimer, KtNow, ktime_set(0, 1000000));1131 #else1132 mod_timer(&g_GipTimer, ulNow + ONE_MSEC_IN_JIFFIES);1133 #endif1134 }1135 1136 local_irq_restore(SavedFlags);1137 1138 #ifdef VBOX_HRTIMER1139 return pDevExt->fGIPSuspended ? HRTIMER_NORESTART : HRTIMER_RESTART;1140 #endif1141 }1142 1143 1144 #ifdef CONFIG_SMP1145 /**1146 * Timer callback function for the other CPUs.1147 *1148 * @param iTimerCPU The APIC ID of this timer.1149 */1150 #ifdef VBOX_HRTIMER1151 static enum hrtimer_restart VBoxDrvLinuxGipTimerPerCpu(struct hrtimer *pTimer)1152 #else1153 static void VBoxDrvLinuxGipTimerPerCpu(unsigned long iTimerCPU)1154 #endif1155 {1156 PSUPDRVDEVEXT pDevExt;1157 PSUPGLOBALINFOPAGE pGip;1158 uint8_t iCPU;1159 uint64_t u64Monotime;1160 unsigned long SavedFlags;1161 unsigned long ulNow;1162 # ifdef VBOX_HRTIMER1163 unsigned long iTimerCPU;1164 ktime_t KtNow;1165 # endif1166 1167 local_irq_save(SavedFlags);1168 1169 ulNow = jiffies;1170 pDevExt = &g_DevExt;1171 pGip = pDevExt->pGip;1172 iCPU = ASMGetApicId();1173 # ifdef VBOX_HRTIMER1174 iTimerCPU = iCPU; /* XXX hrtimer does not support a 'data' field */1175 KtNow = ktime_get();1176 # endif1177 1178 if (RT_LIKELY(iCPU < RT_ELEMENTS(pGip->aCPUs)))1179 {1180 if (RT_LIKELY(iTimerCPU == iCPU))1181 {1182 unsigned long ulDiff = ulNow - pDevExt->aCPUs[iCPU].ulLastJiffies;1183 pDevExt->aCPUs[iCPU].ulLastJiffies = ulNow;1184 u64Monotime = pDevExt->aCPUs[iCPU].u64LastMonotime + ulDiff * TICK_NSEC;1185 pDevExt->aCPUs[iCPU].u64LastMonotime = u64Monotime;1186 if (RT_LIKELY(pGip))1187 supdrvGipUpdatePerCpu(pGip, u64Monotime, iCPU);1188 if (RT_LIKELY(!pDevExt->fGIPSuspended))1189 {1190 # ifdef VBOX_HRTIMER1191 hrtimer_forward(&pDevExt->aCPUs[iCPU].Timer, KtNow, ktime_set(0, 1000000));1192 # else1193 mod_timer(&pDevExt->aCPUs[iCPU].Timer, ulNow + ONE_MSEC_IN_JIFFIES);1194 # endif1195 }1196 }1197 else1198 printk("vboxdrv: error: GIP CPU update timer executing on the wrong CPU: apicid=%d != timer-apicid=%ld (cpuid=%d !=? timer-cpuid=%d)\n",1199 iCPU, iTimerCPU, smp_processor_id(), pDevExt->aCPUs[iTimerCPU].iSmpProcessorId);1200 }1201 else1202 printk("vboxdrv: error: APIC ID is bogus (GIP CPU update): apicid=%d max=%lu cpuid=%d\n",1203 iCPU, (unsigned long)RT_ELEMENTS(pGip->aCPUs), smp_processor_id());1204 1205 local_irq_restore(SavedFlags);1206 1207 # ifdef VBOX_HRTIMER1208 return pDevExt->fGIPSuspended ? HRTIMER_NORESTART : HRTIMER_RESTART;1209 # endif1210 }1211 #endif /* CONFIG_SMP */1212 1213 1214 /**1215 * Maps the GIP into user space.1216 *1217 * @returns negative errno.1218 * @param pDevExt Instance data.1219 */1220 int VBOXCALL supdrvOSGipMap(PSUPDRVDEVEXT pDevExt, PSUPGLOBALINFOPAGE *ppGip)1221 {1222 int rc = 0;1223 unsigned long ulAddr;1224 unsigned long HCPhys = pDevExt->HCPhysGip;1225 pgprot_t pgFlags;1226 pgprot_val(pgFlags) = _PAGE_PRESENT | _PAGE_USER;1227 LogFlow(("supdrvOSGipMap: ppGip=%p\n", ppGip));1228 1229 /*1230 * Allocate user space mapping and put the physical pages into it.1231 */1232 down_write(¤t->mm->mmap_sem);1233 ulAddr = do_mmap(NULL, 0, PAGE_SIZE, PROT_READ, MAP_SHARED | MAP_ANONYMOUS, 0);1234 if (!(ulAddr & ~PAGE_MASK))1235 {1236 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) && !defined(HAVE_26_STYLE_REMAP_PAGE_RANGE)1237 int rc2 = remap_page_range(ulAddr, HCPhys, PAGE_SIZE, pgFlags);1238 #else1239 int rc2 = 0;1240 struct vm_area_struct *vma = find_vma(current->mm, ulAddr);1241 if (vma)1242 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 11)1243 rc2 = remap_page_range(vma, ulAddr, HCPhys, PAGE_SIZE, pgFlags);1244 #else1245 rc2 = remap_pfn_range(vma, ulAddr, HCPhys >> PAGE_SHIFT, PAGE_SIZE, pgFlags);1246 #endif1247 else1248 {1249 rc = SUPDRV_ERR_NO_MEMORY;1250 Log(("supdrvOSGipMap: no vma found for ulAddr=%#lx!\n", ulAddr));1251 }1252 #endif1253 if (rc2)1254 {1255 rc = SUPDRV_ERR_NO_MEMORY;1256 Log(("supdrvOSGipMap: remap_page_range failed rc2=%d\n", rc2));1257 }1258 }1259 else1260 {1261 Log(("supdrvOSGipMap: do_mmap failed ulAddr=%#lx\n", ulAddr));1262 rc = SUPDRV_ERR_NO_MEMORY;1263 }1264 up_write(¤t->mm->mmap_sem); /* not quite sure when to give this up. */1265 1266 /*1267 * Success?1268 */1269 if (!rc)1270 {1271 *ppGip = (PSUPGLOBALINFOPAGE)ulAddr;1272 LogFlow(("supdrvOSGipMap: ppGip=%p\n", *ppGip));1273 return 0;1274 }1275 1276 /*1277 * Failure, cleanup and be gone.1278 */1279 if (ulAddr & ~PAGE_MASK)1280 {1281 down_write(¤t->mm->mmap_sem);1282 MY_DO_MUNMAP(current->mm, ulAddr, PAGE_SIZE);1283 up_write(¤t->mm->mmap_sem);1284 }1285 1286 LogFlow(("supdrvOSGipMap: returns %d\n", rc));1287 return rc;1288 }1289 1290 1291 /**1292 * Maps the GIP into user space.1293 *1294 * @returns negative errno.1295 * @param pDevExt Instance data.1296 */1297 int VBOXCALL supdrvOSGipUnmap(PSUPDRVDEVEXT pDevExt, PSUPGLOBALINFOPAGE pGip)1298 {1299 LogFlow(("supdrvOSGipUnmap: pGip=%p\n", pGip));1300 if (current->mm)1301 {1302 down_write(¤t->mm->mmap_sem);1303 MY_DO_MUNMAP(current->mm, (unsigned long)pGip, PAGE_SIZE);1304 up_write(¤t->mm->mmap_sem);1305 }1306 LogFlow(("supdrvOSGipUnmap: returns 0\n"));1307 return 0;1308 }1309 1310 1311 /**1312 * Resumes the GIP updating.1313 *1314 * @param pDevExt Instance data.1315 */1316 void VBOXCALL supdrvOSGipResume(PSUPDRVDEVEXT pDevExt)1317 {1318 LogFlow(("supdrvOSGipResume:\n"));1319 ASMAtomicXchgU8(&pDevExt->fGIPSuspended, false);1320 #ifdef CONFIG_SMP1321 if (pDevExt->pGip->u32Mode != SUPGIPMODE_ASYNC_TSC)1322 {1323 #endif1324 vbox_ktimer_start(&g_GipTimer);1325 #ifdef CONFIG_SMP1326 }1327 else1328 {1329 vbox_ktimer_start(&g_GipTimer);1330 smp_call_function(VBoxDrvLinuxGipResumePerCpu, pDevExt, 0 /* retry */, 1 /* wait */);1331 }1332 #endif1333 }1334 1335 1336 #ifdef CONFIG_SMP1337 /**1338 * Callback for resuming GIP updating on the other CPUs.1339 *1340 * This is only used when the GIP is in async tsc mode.1341 *1342 * @param pvUser Pointer to the device instance.1343 */1344 static void VBoxDrvLinuxGipResumePerCpu(void *pvUser)1345 {1346 PSUPDRVDEVEXT pDevExt = (PSUPDRVDEVEXT)pvUser;1347 uint8_t iCPU = ASMGetApicId();1348 1349 if (RT_UNLIKELY(iCPU >= RT_ELEMENTS(pDevExt->pGip->aCPUs)))1350 {1351 printk("vboxdrv: error: apicid=%d max=%lu cpuid=%d\n",1352 iCPU, (unsigned long)RT_ELEMENTS(pDevExt->pGip->aCPUs), smp_processor_id());1353 return;1354 }1355 1356 pDevExt->aCPUs[iCPU].iSmpProcessorId = smp_processor_id();1357 vbox_ktimer_start(&pDevExt->aCPUs[iCPU].Timer);1358 }1359 #endif /* CONFIG_SMP */1360 1361 1362 /**1363 * Suspends the GIP updating.1364 *1365 * @param pDevExt Instance data.1366 */1367 void VBOXCALL supdrvOSGipSuspend(PSUPDRVDEVEXT pDevExt)1368 {1369 #ifdef CONFIG_SMP1370 unsigned i;1371 #endif1372 LogFlow(("supdrvOSGipSuspend:\n"));1373 ASMAtomicXchgU8(&pDevExt->fGIPSuspended, true);1374 1375 vbox_ktimer_stop(&g_GipTimer);1376 #ifdef CONFIG_SMP1377 for (i = 0; i < RT_ELEMENTS(pDevExt->aCPUs); i++)1378 vbox_ktimer_stop(&pDevExt->aCPUs[i].Timer);1379 #endif1380 }1381 1382 #endif /* !USE_NEW_OS_INTERFACE_FOR_GIP */1383 1384 1385 878 bool VBOXCALL supdrvOSGetForcedAsyncTscMode(PSUPDRVDEVEXT pDevExt) 1386 879 { … … 1438 931 1439 932 1440 /** Runtime assert implementation for Linux Ring-0.*/933 /** @todo move to IPRT! */ 1441 934 RTDECL(bool) RTAssertDoBreakpoint(void) 1442 935 { … … 1445 938 1446 939 1447 /** Runtime assert implementation for Linux Ring-0.*/940 /** @todo move to IPRT! */ 1448 941 RTDECL(void) AssertMsg1(const char *pszExpr, unsigned uLine, const char *pszFile, const char *pszFunction) 1449 942 { … … 1455 948 1456 949 1457 /** Runtime assert implementation for Linux Ring-0.*/950 /** @todo move to IPRT! */ 1458 951 RTDECL(void) AssertMsg2(const char *pszFormat, ...) 1459 952 { /* forwarder. */ … … 1469 962 1470 963 1471 /* GCC C++ hack. (shouldn't be necessary ...) */964 /* GCC C++ hack. (shouldn't be necessary with the right exception flags...) */ 1472 965 unsigned __gxx_personality_v0 = 0xcccccccc; 1473 966 -
trunk/src/VBox/HostDrivers/Support/win/SUPDrv-win.cpp
r9621 r10248 79 79 static NTSTATUS _stdcall VBoxDrvNtNotSupportedStub(PDEVICE_OBJECT pDevObj, PIRP pIrp); 80 80 static NTSTATUS VBoxDrvNtErr2NtStatus(int rc); 81 #ifndef USE_NEW_OS_INTERFACE_FOR_GIP82 static NTSTATUS VBoxDrvNtGipInit(PSUPDRVDEVEXT pDevExt);83 static void VBoxDrvNtGipTerm(PSUPDRVDEVEXT pDevExt);84 static void _stdcall VBoxDrvNtGipTimer(IN PKDPC pDpc, IN PVOID pvUser, IN PVOID SystemArgument1, IN PVOID SystemArgument2);85 static void _stdcall VBoxDrvNtGipPerCpuDpc(IN PKDPC pDpc, IN PVOID pvUser, IN PVOID SystemArgument1, IN PVOID SystemArgument2);86 #endif87 81 88 82 … … 135 129 if (!vrc) 136 130 { 137 #ifndef USE_NEW_OS_INTERFACE_FOR_GIP138 131 /* 139 * Inititalize the GIP.132 * Setup the driver entry points in pDrvObj. 140 133 */ 141 rc = VBoxDrvNtGipInit(pDevExt); 142 if (NT_SUCCESS(rc)) 143 #endif 144 { 145 /* 146 * Setup the driver entry points in pDrvObj. 147 */ 148 pDrvObj->DriverUnload = VBoxDrvNtUnload; 149 pDrvObj->MajorFunction[IRP_MJ_CREATE] = VBoxDrvNtCreate; 150 pDrvObj->MajorFunction[IRP_MJ_CLOSE] = VBoxDrvNtClose; 151 pDrvObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = VBoxDrvNtDeviceControl; 152 pDrvObj->MajorFunction[IRP_MJ_READ] = VBoxDrvNtNotSupportedStub; 153 pDrvObj->MajorFunction[IRP_MJ_WRITE] = VBoxDrvNtNotSupportedStub; 154 /* more? */ 155 dprintf(("VBoxDrv::DriverEntry returning STATUS_SUCCESS\n")); 156 return STATUS_SUCCESS; 157 } 158 #ifndef USE_NEW_OS_INTERFACE_FOR_GIP 159 dprintf(("VBoxDrvNtGipInit failed with rc=%#x!\n", rc)); 160 161 supdrvDeleteDevExt(pDevExt); 162 #endif 134 pDrvObj->DriverUnload = VBoxDrvNtUnload; 135 pDrvObj->MajorFunction[IRP_MJ_CREATE] = VBoxDrvNtCreate; 136 pDrvObj->MajorFunction[IRP_MJ_CLOSE] = VBoxDrvNtClose; 137 pDrvObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = VBoxDrvNtDeviceControl; 138 pDrvObj->MajorFunction[IRP_MJ_READ] = VBoxDrvNtNotSupportedStub; 139 pDrvObj->MajorFunction[IRP_MJ_WRITE] = VBoxDrvNtNotSupportedStub; 140 /* more? */ 141 dprintf(("VBoxDrv::DriverEntry returning STATUS_SUCCESS\n")); 142 return STATUS_SUCCESS; 163 143 } 164 else 165 { 166 dprintf(("supdrvInitDevExit failed with vrc=%d!\n", vrc)); 167 rc = VBoxDrvNtErr2NtStatus(vrc); 168 } 144 145 dprintf(("supdrvInitDevExit failed with vrc=%d!\n", vrc)); 146 rc = VBoxDrvNtErr2NtStatus(vrc); 169 147 170 148 IoDeleteSymbolicLink(&DosName); … … 214 192 * Terminate the GIP page and delete the device extension. 215 193 */ 216 #ifndef USE_NEW_OS_INTERFACE_FOR_GIP217 VBoxDrvNtGipTerm(pDevExt);218 #endif219 194 supdrvDeleteDevExt(pDevExt); 220 195 RTR0Term(); … … 481 456 } 482 457 483 #ifndef USE_NEW_OS_INTERFACE_FOR_GIP484 485 /**486 * Gets the monotone timestamp (nano seconds).487 * @returns NanoTS.488 */489 static inline uint64_t supdrvOSMonotime(void)490 {491 return (uint64_t)KeQueryInterruptTime() * 100;492 }493 494 495 /**496 * Initializes the GIP.497 *498 * @returns NT status code.499 * @param pDevExt Instance data. GIP stuff may be updated.500 */501 static NTSTATUS VBoxDrvNtGipInit(PSUPDRVDEVEXT pDevExt)502 {503 dprintf2(("VBoxSupDrvTermGip:\n"));504 505 /*506 * Try allocate the memory.507 * Make sure it's below 4GB for 32-bit GC support508 */509 NTSTATUS rc;510 PHYSICAL_ADDRESS Phys;511 Phys.HighPart = 0;512 Phys.LowPart = ~0;513 PSUPGLOBALINFOPAGE pGip = (PSUPGLOBALINFOPAGE)MmAllocateContiguousMemory(PAGE_SIZE, Phys);514 if (pGip)515 {516 if (!((uintptr_t)pGip & (PAGE_SIZE - 1)))517 {518 pDevExt->pGipMdl = IoAllocateMdl(pGip, PAGE_SIZE, FALSE, FALSE, NULL);519 if (pDevExt->pGipMdl)520 {521 MmBuildMdlForNonPagedPool(pDevExt->pGipMdl);522 523 /*524 * Figure the timer interval and frequency.525 * It turns out trying 1023Hz doesn't work. So, we'll set the max Hz at 128 for now.526 */527 ExSetTimerResolution(156250, TRUE);528 ULONG ulClockIntervalActual = ExSetTimerResolution(0, FALSE);529 ULONG ulClockInterval = RT_MAX(ulClockIntervalActual, 78125); /* 1/128 */530 ULONG ulClockFreq = 10000000 / ulClockInterval;531 pDevExt->ulGipTimerInterval = ulClockInterval / 10000; /* ms */532 533 /* Note: We need to register a callback handler for added cpus (only available in win2k8: KeRegisterProcessorChangeCallback) */534 /* Note: We are not allowed to call KeQueryActiveProcessors at DPC_LEVEL, so we now assume cpu affinity mask does NOT change. */535 pDevExt->uAffinityMask = KeQueryActiveProcessors();536 537 /*538 * Call common initialization routine.539 */540 Phys = MmGetPhysicalAddress(pGip); /* could perhaps use the Mdl, not that it looks much better */541 supdrvGipInit(pDevExt, pGip, (RTHCPHYS)Phys.QuadPart, supdrvOSMonotime(), ulClockFreq);542 543 /*544 * Initialize the timer.545 */546 KeInitializeTimerEx(&pDevExt->GipTimer, SynchronizationTimer);547 KeInitializeDpc(&pDevExt->GipDpc, VBoxDrvNtGipTimer, pDevExt);548 549 /*550 * Initialize the DPCs we're using to update the per-cpu GIP data.551 */552 for (unsigned i = 0; i < RT_ELEMENTS(pDevExt->aGipCpuDpcs); i++)553 {554 KeInitializeDpc(&pDevExt->aGipCpuDpcs[i], VBoxDrvNtGipPerCpuDpc, pGip);555 KeSetImportanceDpc(&pDevExt->aGipCpuDpcs[i], HighImportance);556 KeSetTargetProcessorDpc(&pDevExt->aGipCpuDpcs[i], i);557 }558 559 dprintf(("VBoxDrvNtGipInit: ulClockFreq=%ld ulClockInterval=%ld ulClockIntervalActual=%ld Phys=%x%08x\n",560 ulClockFreq, ulClockInterval, ulClockIntervalActual, Phys.HighPart, Phys.LowPart));561 return STATUS_SUCCESS;562 }563 564 dprintf(("VBoxSupDrvInitGip: IoAllocateMdl failed for %p/PAGE_SIZE\n", pGip));565 rc = STATUS_NO_MEMORY;566 }567 else568 {569 dprintf(("VBoxSupDrvInitGip: GIP memory is not page aligned! pGip=%p\n", pGip));570 rc = STATUS_INVALID_ADDRESS;571 }572 MmFreeContiguousMemory(pGip);573 }574 else575 {576 dprintf(("VBoxSupDrvInitGip: no cont memory.\n"));577 rc = STATUS_NO_MEMORY;578 }579 return rc;580 }581 582 583 /**584 * Terminates the GIP.585 *586 * @returns negative errno.587 * @param pDevExt Instance data. GIP stuff may be updated.588 */589 static void VBoxDrvNtGipTerm(PSUPDRVDEVEXT pDevExt)590 {591 dprintf(("VBoxSupDrvTermGip:\n"));592 PSUPGLOBALINFOPAGE pGip;593 594 /*595 * Cancel the timer and wait on DPCs if it was still pending.596 */597 if (KeCancelTimer(&pDevExt->GipTimer))598 {599 UNICODE_STRING RoutineName;600 RtlInitUnicodeString(&RoutineName, L"KeFlushQueuedDpcs");601 VOID (*pfnKeFlushQueuedDpcs)(VOID) = (VOID (*)(VOID))MmGetSystemRoutineAddress(&RoutineName);602 if (pfnKeFlushQueuedDpcs)603 {604 /* KeFlushQueuedDpcs must be run at IRQL PASSIVE_LEVEL */605 AssertMsg(KeGetCurrentIrql() == PASSIVE_LEVEL, ("%d != %d (PASSIVE_LEVEL)\n", KeGetCurrentIrql(), PASSIVE_LEVEL));606 pfnKeFlushQueuedDpcs();607 }608 }609 610 /*611 * Uninitialize the content.612 */613 pGip = pDevExt->pGip;614 pDevExt->pGip = NULL;615 if (pGip)616 {617 supdrvGipTerm(pGip);618 619 /*620 * Free the page.621 */622 if (pDevExt->pGipMdl)623 {624 IoFreeMdl(pDevExt->pGipMdl);625 pDevExt->pGipMdl = NULL;626 }627 MmFreeContiguousMemory(pGip);628 }629 }630 631 632 /**633 * Timer callback function.634 * The pvUser parameter is the pDevExt pointer.635 */636 static void _stdcall VBoxDrvNtGipTimer(IN PKDPC pDpc, IN PVOID pvUser, IN PVOID SystemArgument1, IN PVOID SystemArgument2)637 {638 PSUPDRVDEVEXT pDevExt = (PSUPDRVDEVEXT)pvUser;639 PSUPGLOBALINFOPAGE pGip = pDevExt->pGip;640 if (pGip)641 {642 if (pGip->u32Mode != SUPGIPMODE_ASYNC_TSC)643 supdrvGipUpdate(pGip, supdrvOSMonotime());644 else645 {646 KIRQL oldIrql;647 648 KAFFINITY Mask = pDevExt->uAffinityMask;649 650 /* Raise the IRQL to DISPATCH_LEVEL so we can't be rescheduled to another cpu */651 KeRaiseIrql(DISPATCH_LEVEL, &oldIrql);652 653 /*654 * We cannot do other than assume a 1:1 relationship between the655 * affinity mask and the process despite the warnings in the docs.656 * If someone knows a better way to get this done, please let bird know.657 */658 unsigned iSelf = KeGetCurrentProcessorNumber();659 660 for (unsigned i = 0; i < RT_ELEMENTS(pDevExt->aGipCpuDpcs); i++)661 {662 if ( i != iSelf663 && (Mask & RT_BIT_64(i)))664 KeInsertQueueDpc(&pDevExt->aGipCpuDpcs[i], 0, 0);665 }666 667 /* Run the normal update. */668 supdrvGipUpdate(pGip, supdrvOSMonotime());669 670 KeLowerIrql(oldIrql);671 }672 }673 }674 675 676 /**677 * Per cpu callback callback function.678 * The pvUser parameter is the pGip pointer.679 */680 static void _stdcall VBoxDrvNtGipPerCpuDpc(IN PKDPC pDpc, IN PVOID pvUser, IN PVOID SystemArgument1, IN PVOID SystemArgument2)681 {682 PSUPGLOBALINFOPAGE pGip = (PSUPGLOBALINFOPAGE)pvUser;683 supdrvGipUpdatePerCpu(pGip, supdrvOSMonotime(), ASMGetApicId());684 }685 686 687 /**688 * Maps the GIP into user space.689 *690 * @returns negative errno.691 * @param pDevExt Instance data.692 */693 int VBOXCALL supdrvOSGipMap(PSUPDRVDEVEXT pDevExt, PSUPGLOBALINFOPAGE *ppGip)694 {695 dprintf2(("supdrvOSGipMap: ppGip=%p (pDevExt->pGipMdl=%p)\n", ppGip, pDevExt->pGipMdl));696 697 /*698 * Map into user space.699 */700 int rc = 0;701 void *pv = NULL;702 __try703 {704 *ppGip = (PSUPGLOBALINFOPAGE)MmMapLockedPagesSpecifyCache(pDevExt->pGipMdl, UserMode, MmCached, NULL, FALSE, NormalPagePriority);705 }706 __except(EXCEPTION_EXECUTE_HANDLER)707 {708 NTSTATUS rcNt = GetExceptionCode();709 dprintf(("supdrvOsGipMap: Exception Code %#x\n", rcNt));710 rc = SUPDRV_ERR_LOCK_FAILED;711 }712 713 dprintf2(("supdrvOSGipMap: returns %d, *ppGip=%p\n", rc, *ppGip));714 return 0;715 }716 717 718 /**719 * Maps the GIP into user space.720 *721 * @returns negative errno.722 * @param pDevExt Instance data.723 */724 int VBOXCALL supdrvOSGipUnmap(PSUPDRVDEVEXT pDevExt, PSUPGLOBALINFOPAGE pGip)725 {726 dprintf2(("supdrvOSGipUnmap: pGip=%p (pGipMdl=%p)\n", pGip, pDevExt->pGipMdl));727 728 int rc = 0;729 __try730 {731 MmUnmapLockedPages((void *)pGip, pDevExt->pGipMdl);732 }733 __except(EXCEPTION_EXECUTE_HANDLER)734 {735 NTSTATUS rcNt = GetExceptionCode();736 dprintf(("supdrvOSGipUnmap: Exception Code %#x\n", rcNt));737 rc = SUPDRV_ERR_GENERAL_FAILURE;738 }739 dprintf2(("supdrvOSGipUnmap: returns %d\n", rc));740 return rc;741 }742 743 744 /**745 * Resumes the GIP updating.746 *747 * @param pDevExt Instance data.748 */749 void VBOXCALL supdrvOSGipResume(PSUPDRVDEVEXT pDevExt)750 {751 dprintf2(("supdrvOSGipResume:\n"));752 LARGE_INTEGER DueTime;753 DueTime.QuadPart = -10000; /* 1ms, relative */754 KeSetTimerEx(&pDevExt->GipTimer, DueTime, pDevExt->ulGipTimerInterval, &pDevExt->GipDpc);755 }756 757 758 /**759 * Suspends the GIP updating.760 *761 * @param pDevExt Instance data.762 */763 void VBOXCALL supdrvOSGipSuspend(PSUPDRVDEVEXT pDevExt)764 {765 dprintf2(("supdrvOSGipSuspend:\n"));766 KeCancelTimer(&pDevExt->GipTimer);767 #ifdef RT_ARCH_AMD64768 ExSetTimerResolution(0, FALSE); /* why did we (I?) do this? */769 #endif770 }771 772 773 /**774 * Get the current CPU count.775 * @returns Number of cpus.776 *777 * @param pDevExt Instance data.778 */779 unsigned VBOXCALL supdrvOSGetCPUCount(PSUPDRVDEVEXT pDevExt)780 {781 KAFFINITY Mask = pDevExt->uAffinityMask;782 unsigned cCpus = 0;783 unsigned iBit;784 for (iBit = 0; iBit < sizeof(Mask) * 8; iBit++)785 if (Mask & RT_BIT_64(iBit))786 cCpus++;787 if (cCpus == 0) /* paranoia */788 cCpus = 1;789 return cCpus;790 }791 #endif /* ! USE_NEW_OS_INTERFACE_FOR_GIP */792 793 458 794 459 /** … … 827 492 828 493 829 /** Runtime assert implementation for Native Win32 Ring-0. */ 494 495 /** @todo move this to IPRT */ 830 496 RTDECL(void) AssertMsg1(const char *pszExpr, unsigned uLine, const char *pszFile, const char *pszFunction) 831 497 { … … 836 502 } 837 503 504 /** @todo use the nocrt stuff? */ 838 505 int VBOXCALL mymemcmp(const void *pv1, const void *pv2, size_t cb) 839 506 {
Note:
See TracChangeset
for help on using the changeset viewer.