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.

629 lines
13 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. flushtb.c
  5. Abstract:
  6. This module implements machine dependent functions to flush the TB
  7. for an AMD64 system.
  8. N.B. This module contains only MP versions of the TB flush routines.
  9. Author:
  10. David N. Cutler (davec) 22-April-2000
  11. Environment:
  12. Kernel mode only.
  13. --*/
  14. #include "ki.h"
  15. //
  16. // Define prototypes for forward referenced functions.
  17. //
  18. VOID
  19. KiFlushTargetEntireTb (
  20. IN PKIPI_CONTEXT SignalDone,
  21. IN PVOID Parameter1,
  22. IN PVOID Parameter2,
  23. IN PVOID Parameter3
  24. );
  25. VOID
  26. KiFlushTargetProcessTb (
  27. IN PKIPI_CONTEXT SignalDone,
  28. IN PVOID Parameter1,
  29. IN PVOID Parameter2,
  30. IN PVOID Parameter3
  31. );
  32. VOID
  33. KiFlushTargetMultipleTb (
  34. IN PKIPI_CONTEXT SignalDone,
  35. IN PVOID Parameter1,
  36. IN PVOID Parameter2,
  37. IN PVOID Parameter3
  38. );
  39. VOID
  40. KiFlushTargetSingleTb (
  41. IN PKIPI_CONTEXT SignalDone,
  42. IN PVOID Parameter1,
  43. IN PVOID Parameter2,
  44. IN PVOID Parameter3
  45. );
  46. VOID
  47. KeFlushEntireTb (
  48. IN BOOLEAN Invalid,
  49. IN BOOLEAN AllProcessors
  50. )
  51. /*++
  52. Routine Description:
  53. This function flushes the entire translation buffer (TB) on all
  54. processors in the host configuration.
  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->NotSetMember;
  78. //
  79. // Send packet to target processors.
  80. //
  81. if (TargetProcessors != 0) {
  82. KiIpiSendPacket(TargetProcessors,
  83. KiFlushTargetEntireTb,
  84. NULL,
  85. NULL,
  86. NULL);
  87. }
  88. IPI_INSTRUMENT_COUNT(Prcb->Number, FlushEntireTb);
  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 flush time stamp busy.
  104. //
  105. KiClearTbFlushTimeStampBusy();
  106. //
  107. // Lower IRQL to its previous value.
  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 to its previous value.
  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. //
  262. // Compute target set of processors.
  263. //
  264. OldIrql = KeRaiseIrqlToSynchLevel();
  265. Prcb = KeGetCurrentPrcb();
  266. if (AllProcessors != FALSE) {
  267. TargetProcessors = KeActiveProcessors;
  268. } else {
  269. Process = Prcb->CurrentThread->ApcState.Process;
  270. TargetProcessors = Process->ActiveProcessors;
  271. }
  272. //
  273. // If any target processors are specified, then send a flush multiple
  274. // packet to the target set of processors.
  275. //
  276. End = Virtual + Number;
  277. TargetProcessors &= Prcb->NotSetMember;
  278. if (TargetProcessors != 0) {
  279. KiIpiSendPacket(TargetProcessors,
  280. KiFlushTargetMultipleTb,
  281. NULL,
  282. (PVOID)End,
  283. (PVOID)Virtual);
  284. }
  285. IPI_INSTRUMENT_COUNT (Prcb->Number, FlushMultipleTb);
  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 value.
  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)
  353. on all processors that are currently running threads which are
  354. children of the current process.
  355. Arguments:
  356. Virtual - Supplies a virtual address that is within the page whose
  357. translation buffer entry is to be flushed.
  358. AllProcessors - Supplies a boolean value that determines which
  359. translation buffers are to be flushed.
  360. Return Value:
  361. The previous contents of the specified page table entry is returned
  362. as the function value.
  363. --*/
  364. {
  365. KIRQL OldIrql;
  366. PKPRCB Prcb;
  367. PKPROCESS Process;
  368. KAFFINITY TargetProcessors;
  369. //
  370. // Compute the target set of processors and send the flush single
  371. // parameters to the target processors, if any, for execution.
  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. //
  382. // If any target processors are specified, then send a flush single
  383. // packet to the target set of processors.
  384. //
  385. TargetProcessors &= Prcb->NotSetMember;
  386. if (TargetProcessors != 0) {
  387. KiIpiSendPacket(TargetProcessors,
  388. KiFlushTargetSingleTb,
  389. NULL,
  390. (PVOID)Virtual,
  391. NULL);
  392. }
  393. IPI_INSTRUMENT_COUNT(Prcb->Number, FlushSingleTb);
  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 value.
  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