Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

630 lines
13 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Copyright (c) 1990 Microsoft Corporation
  4. Module Name:
  5. tbflush.c
  6. Abstract:
  7. This module implements machine dependent functions to flush
  8. the translation buffers in an Intel x86 system.
  9. N.B. This module contains only MP versions of the TB flush routines.
  10. The UP versions are macros in ke.h
  11. KeFlushEntireTb remains a routine for the UP system since it is
  12. exported from the kernel for backwards compatibility.
  13. Author:
  14. David N. Cutler (davec) 13-May-1989
  15. Environment:
  16. Kernel mode only.
  17. --*/
  18. #include "ki.h"
  19. VOID
  20. KiFlushTargetEntireTb (
  21. IN PKIPI_CONTEXT SignalDone,
  22. IN PVOID Parameter1,
  23. IN PVOID Parameter2,
  24. IN PVOID Parameter3
  25. );
  26. VOID
  27. KiFlushTargetProcessTb (
  28. IN PKIPI_CONTEXT SignalDone,
  29. IN PVOID Parameter1,
  30. IN PVOID Parameter2,
  31. IN PVOID Parameter3
  32. );
  33. VOID
  34. KiFlushTargetMultipleTb (
  35. IN PKIPI_CONTEXT SignalDone,
  36. IN PVOID Parameter1,
  37. IN PVOID Parameter2,
  38. IN PVOID Parameter3
  39. );
  40. VOID
  41. KiFlushTargetSingleTb (
  42. IN PKIPI_CONTEXT SignalDone,
  43. IN PVOID Parameter1,
  44. IN PVOID Parameter2,
  45. IN PVOID Parameter3
  46. );
  47. VOID
  48. KeFlushEntireTb (
  49. IN BOOLEAN Invalid,
  50. IN BOOLEAN AllProcessors
  51. )
  52. /*++
  53. Routine Description:
  54. This function flushes the entire translation buffer on all processors.
  55. Arguments:
  56. Invalid - Not used.
  57. AllProcessors - Not used.
  58. Return Value:
  59. None.
  60. --*/
  61. {
  62. KIRQL OldIrql;
  63. #if !defined(NT_UP)
  64. PKPRCB Prcb;
  65. KAFFINITY TargetProcessors;
  66. #endif
  67. UNREFERENCED_PARAMETER(Invalid);
  68. UNREFERENCED_PARAMETER(AllProcessors);
  69. //
  70. // Compute the target set of processors and send the flush entire
  71. // parameters to the target processors, if any, for execution.
  72. //
  73. OldIrql = KeRaiseIrqlToSynchLevel();
  74. KiSetTbFlushTimeStampBusy();
  75. #if !defined(NT_UP)
  76. Prcb = KeGetCurrentPrcb();
  77. TargetProcessors = KeActiveProcessors & ~Prcb->SetMember;
  78. //
  79. // Send packet to target processors.
  80. //
  81. if (TargetProcessors != 0) {
  82. KiIpiSendPacket(TargetProcessors,
  83. KiFlushTargetEntireTb,
  84. NULL,
  85. NULL,
  86. NULL);
  87. IPI_INSTRUMENT_COUNT (Prcb->Number, FlushEntireTb);
  88. }
  89. #endif
  90. //
  91. // Flush TB on current processor.
  92. //
  93. KeFlushCurrentTb();
  94. //
  95. // Wait until all target processors have finished and complete packet.
  96. //
  97. #if !defined(NT_UP)
  98. if (TargetProcessors != 0) {
  99. KiIpiStallOnPacketTargets(TargetProcessors);
  100. }
  101. #endif
  102. //
  103. // Clear the TB time stamp busy.
  104. //
  105. KiClearTbFlushTimeStampBusy();
  106. //
  107. // Lower IRQL to previous level.
  108. //
  109. KeLowerIrql(OldIrql);
  110. return;
  111. }
  112. #if !defined(NT_UP)
  113. VOID
  114. KiFlushTargetEntireTb (
  115. IN PKIPI_CONTEXT SignalDone,
  116. IN PVOID Parameter1,
  117. IN PVOID Parameter2,
  118. IN PVOID Parameter3
  119. )
  120. /*++
  121. Routine Description:
  122. This is the target function for flushing the entire TB.
  123. Arguments:
  124. SignalDone - Supplies a pointer to a variable that is cleared when the
  125. requested operation has been performed.
  126. Parameter1 - Parameter3 - Not used.
  127. Return Value:
  128. None.
  129. --*/
  130. {
  131. UNREFERENCED_PARAMETER(Parameter1);
  132. UNREFERENCED_PARAMETER(Parameter2);
  133. UNREFERENCED_PARAMETER(Parameter3);
  134. //
  135. // Flush the entire TB on the current processor.
  136. //
  137. KiIpiSignalPacketDone(SignalDone);
  138. KeFlushCurrentTb();
  139. return;
  140. }
  141. VOID
  142. KeFlushProcessTb (
  143. IN BOOLEAN AllProcessors
  144. )
  145. /*++
  146. Routine Description:
  147. This function flushes the non-global translation buffer on all processors
  148. that are currently running threads which are child of the current process
  149. or flushes the non-global translation buffer on all processors in the host
  150. configuration.
  151. Arguments:
  152. AllProcessors - Supplies a boolean value that determines which translation
  153. buffers are to be flushed.
  154. Return Value:
  155. None.
  156. --*/
  157. {
  158. KIRQL OldIrql;
  159. PKPRCB Prcb;
  160. PKPROCESS Process;
  161. KAFFINITY TargetProcessors;
  162. //
  163. // Compute the target set of processors, disable context switching,
  164. // and send the flush entire parameters to the target processors,
  165. // if any, for execution.
  166. //
  167. OldIrql = KeRaiseIrqlToSynchLevel();
  168. Prcb = KeGetCurrentPrcb();
  169. if (AllProcessors != FALSE) {
  170. TargetProcessors = KeActiveProcessors;
  171. } else {
  172. Process = Prcb->CurrentThread->ApcState.Process;
  173. TargetProcessors = Process->ActiveProcessors;
  174. }
  175. TargetProcessors &= ~Prcb->SetMember;
  176. //
  177. // Send packet to target processors.
  178. //
  179. if (TargetProcessors != 0) {
  180. KiIpiSendPacket(TargetProcessors,
  181. KiFlushTargetProcessTb,
  182. NULL,
  183. NULL,
  184. NULL);
  185. IPI_INSTRUMENT_COUNT (Prcb->Number, FlushEntireTb);
  186. }
  187. //
  188. // Flush TB on current processor.
  189. //
  190. KiFlushProcessTb();
  191. //
  192. // Wait until all target processors have finished and complete packet.
  193. //
  194. if (TargetProcessors != 0) {
  195. KiIpiStallOnPacketTargets(TargetProcessors);
  196. }
  197. //
  198. // Lower IRQL and unlock as appropriate.
  199. //
  200. KeLowerIrql(OldIrql);
  201. return;
  202. }
  203. VOID
  204. KiFlushTargetProcessTb (
  205. IN PKIPI_CONTEXT SignalDone,
  206. IN PVOID Parameter1,
  207. IN PVOID Parameter2,
  208. IN PVOID Parameter3
  209. )
  210. /*++
  211. Routine Description:
  212. This is the target function for flushing the non-global TB.
  213. Arguments:
  214. SignalDone - Supplies a pointer to a variable that is cleared when the
  215. requested operation has been performed.
  216. Parameter1 - Parameter3 - Not used.
  217. Return Value:
  218. None.
  219. --*/
  220. {
  221. UNREFERENCED_PARAMETER(Parameter1);
  222. UNREFERENCED_PARAMETER(Parameter2);
  223. UNREFERENCED_PARAMETER(Parameter3);
  224. //
  225. // Flush the non-global TB on the current processor.
  226. //
  227. KiIpiSignalPacketDone(SignalDone);
  228. KiFlushProcessTb();
  229. return;
  230. }
  231. VOID
  232. KeFlushMultipleTb (
  233. IN ULONG Number,
  234. IN PVOID *Virtual,
  235. IN BOOLEAN AllProcessors
  236. )
  237. /*++
  238. Routine Description:
  239. This function flushes multiple entries from the translation buffer
  240. on all processors that are currently running threads which are
  241. children of the current process or flushes a multiple entries from
  242. the translation buffer on all processors in the host configuration.
  243. Arguments:
  244. Number - Supplies the number of TB entries to flush.
  245. Virtual - Supplies a pointer to an array of virtual addresses that
  246. are within the pages whose translation buffer entries are to be
  247. flushed.
  248. AllProcessors - Supplies a boolean value that determines which
  249. translation buffers are to be flushed.
  250. Return Value:
  251. The previous contents of the specified page table entry is returned
  252. as the function value.
  253. --*/
  254. {
  255. PVOID *End;
  256. KIRQL OldIrql;
  257. PKPRCB Prcb;
  258. PKPROCESS Process;
  259. KAFFINITY TargetProcessors;
  260. ASSERT(Number != 0);
  261. End = Virtual + Number;
  262. //
  263. // Compute target set of processors.
  264. //
  265. OldIrql = KeRaiseIrqlToSynchLevel();
  266. Prcb = KeGetCurrentPrcb();
  267. if (AllProcessors != FALSE) {
  268. TargetProcessors = KeActiveProcessors;
  269. } else {
  270. Process = Prcb->CurrentThread->ApcState.Process;
  271. TargetProcessors = Process->ActiveProcessors;
  272. }
  273. TargetProcessors &= ~Prcb->SetMember;
  274. //
  275. // If any target processors are specified, then send a flush multiple
  276. // packet to the target set of processors.
  277. //
  278. if (TargetProcessors != 0) {
  279. KiIpiSendPacket(TargetProcessors,
  280. KiFlushTargetMultipleTb,
  281. NULL,
  282. (PVOID)End,
  283. (PVOID)Virtual);
  284. IPI_INSTRUMENT_COUNT (Prcb->Number, FlushMultipleTb);
  285. }
  286. //
  287. // Flush the specified entries from the TB on the current processor.
  288. //
  289. do {
  290. KiFlushSingleTb(*Virtual);
  291. Virtual += 1;
  292. } while (Virtual < End);
  293. //
  294. // Wait until all target processors have finished and complete packet.
  295. //
  296. if (TargetProcessors != 0) {
  297. KiIpiStallOnPacketTargets(TargetProcessors);
  298. }
  299. //
  300. // Lower IRQL to its previous level.
  301. //
  302. KeLowerIrql(OldIrql);
  303. return;
  304. }
  305. VOID
  306. KiFlushTargetMultipleTb (
  307. IN PKIPI_CONTEXT SignalDone,
  308. IN PVOID Parameter1,
  309. IN PVOID End,
  310. IN PVOID Virtual
  311. )
  312. /*++
  313. Routine Description:
  314. This is the target function for flushing multiple TB entries.
  315. Arguments:
  316. SignalDone - Supplies a pointer to a variable that is cleared when the
  317. requested operation has been performed.
  318. Parameter1 - Not used.
  319. End - Supplies the a pointer to the ending address of the virtual
  320. address array.
  321. Virtual - Supplies a pointer to an array of virtual addresses that
  322. are within the pages whose translation buffer entries are to be
  323. flushed.
  324. Return Value:
  325. None.
  326. --*/
  327. {
  328. PVOID *xEnd;
  329. PVOID *xVirtual;
  330. UNREFERENCED_PARAMETER(Parameter1);
  331. //
  332. // Flush the specified entries from the TB on the current processor and
  333. // signal pack done.
  334. //
  335. xEnd = (PVOID *)End;
  336. xVirtual = (PVOID *)Virtual;
  337. do {
  338. KiFlushSingleTb(*xVirtual);
  339. xVirtual += 1;
  340. } while (xVirtual < xEnd);
  341. KiIpiSignalPacketDone(SignalDone);
  342. return;
  343. }
  344. VOID
  345. FASTCALL
  346. KeFlushSingleTb (
  347. IN PVOID Virtual,
  348. IN BOOLEAN AllProcessors
  349. )
  350. /*++
  351. Routine Description:
  352. This function flushes a single entry from translation buffer (TB) on all
  353. processors that are currently running threads which are child of the current
  354. process or flushes the entire translation buffer on all processors in the
  355. host configuration.
  356. Arguments:
  357. Virtual - Supplies a virtual address that is within the page whose
  358. translation buffer entry is to be flushed.
  359. AllProcessors - Supplies a boolean value that determines which translation
  360. buffers are to be flushed.
  361. Return Value:
  362. Returns the contents of the PtePointer before the new value
  363. is stored.
  364. --*/
  365. {
  366. KIRQL OldIrql;
  367. PKPRCB Prcb;
  368. PKPROCESS Process;
  369. KAFFINITY TargetProcessors;
  370. //
  371. // Compute target set of processors.
  372. //
  373. OldIrql = KeRaiseIrqlToSynchLevel();
  374. Prcb = KeGetCurrentPrcb();
  375. if (AllProcessors != FALSE) {
  376. TargetProcessors = KeActiveProcessors;
  377. } else {
  378. Process = Prcb->CurrentThread->ApcState.Process;
  379. TargetProcessors = Process->ActiveProcessors;
  380. }
  381. TargetProcessors &= ~Prcb->SetMember;
  382. //
  383. // If any target processors are specified, then send a flush single
  384. // packet to the target set of processors.
  385. //
  386. if (TargetProcessors != 0) {
  387. KiIpiSendPacket(TargetProcessors,
  388. KiFlushTargetSingleTb,
  389. NULL,
  390. (PVOID)Virtual,
  391. NULL);
  392. IPI_INSTRUMENT_COUNT(Prcb->Number, FlushSingleTb);
  393. }
  394. //
  395. // Flush the specified entry from the TB on the current processor.
  396. //
  397. KiFlushSingleTb(Virtual);
  398. //
  399. // Wait until all target processors have finished and complete packet.
  400. //
  401. if (TargetProcessors != 0) {
  402. KiIpiStallOnPacketTargets(TargetProcessors);
  403. }
  404. //
  405. // Lower IRQL to its previous level.
  406. //
  407. KeLowerIrql(OldIrql);
  408. return;
  409. }
  410. VOID
  411. KiFlushTargetSingleTb (
  412. IN PKIPI_CONTEXT SignalDone,
  413. IN PVOID Parameter1,
  414. IN PVOID VirtualAddress,
  415. IN PVOID Parameter3
  416. )
  417. /*++
  418. Routine Description:
  419. This is the target function for flushing a single TB entry.
  420. Arguments:
  421. SignalDone Supplies a pointer to a variable that is cleared when the
  422. requested operation has been performed.
  423. Parameter1 - Not used.
  424. Virtual - Supplies a virtual address that is within the page whose
  425. translation buffer entry is to be flushed.
  426. Parameter3 - Not used.
  427. Return Value:
  428. None.
  429. --*/
  430. {
  431. UNREFERENCED_PARAMETER(Parameter1);
  432. UNREFERENCED_PARAMETER(Parameter3);
  433. //
  434. // Flush a single entry from the TB on the current processor.
  435. //
  436. KiIpiSignalPacketDone(SignalDone);
  437. KiFlushSingleTb(VirtualAddress);
  438. }
  439. #endif