Source code of Windows XP (NT5)
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.

993 lines
21 KiB

  1. /*++
  2. Copyright (c) 1992-1998 Microsoft Corporation
  3. Copyright (c) 1993 Digital Equipment Corporation
  4. Module Name:
  5. flushtb.c
  6. Abstract:
  7. This module implements machine dependent functions to flush the
  8. translation buffers and synchronize PIDs in an Alpha AXP MP 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. Joe Notarangelo 29-Nov-1993
  16. Environment:
  17. Kernel mode only.
  18. Revision History:
  19. --*/
  20. #include "ki.h"
  21. //
  22. // Define forward referenced prototypes.
  23. //
  24. VOID
  25. KiFlushEntireTbTarget (
  26. IN PKIPI_CONTEXT SignalDone,
  27. IN PVOID Parameter1,
  28. IN PVOID Parameter2,
  29. IN PVOID Parameter3
  30. );
  31. VOID
  32. KiFlushMultipleTbTarget (
  33. IN PKIPI_CONTEXT SignalDone,
  34. IN PVOID Number,
  35. IN PVOID Virtual,
  36. IN PVOID Pid
  37. );
  38. VOID
  39. KiFlushSingleTbTarget (
  40. IN PKIPI_CONTEXT SignalDone,
  41. IN PVOID Virtual,
  42. IN PVOID Pid,
  43. IN PVOID Parameter3
  44. );
  45. VOID
  46. KiFlushMultipleTbTarget64 (
  47. IN PKIPI_CONTEXT SignalDone,
  48. IN PVOID Number,
  49. IN PVOID Virtual,
  50. IN PVOID Pid
  51. );
  52. VOID
  53. KiFlushSingleTbTarget64 (
  54. IN PKIPI_CONTEXT SignalDone,
  55. IN PVOID Virtual,
  56. IN PVOID Pid,
  57. IN PVOID Parameter3
  58. );
  59. #if !defined(NT_UP)
  60. VOID
  61. KeFlushEntireTb (
  62. IN BOOLEAN Invalid,
  63. IN BOOLEAN AllProcessors
  64. )
  65. /*++
  66. Routine Description:
  67. This function flushes the entire translation buffer (TB) on all
  68. processors that are currently running threads which are children
  69. of the current process or flushes the entire translation buffer
  70. on all processors in the host configuration.
  71. Arguments:
  72. Invalid - Supplies a boolean value that specifies the reason for
  73. flushing the translation buffer.
  74. AllProcessors - Supplies a boolean value that determines which
  75. translation buffers are to be flushed.
  76. Return Value:
  77. None.
  78. --*/
  79. {
  80. KAFFINITY EntireSet;
  81. KIRQL OldIrql;
  82. PKPROCESS Process;
  83. PKTHREAD Thread;
  84. KAFFINITY TargetProcessors;
  85. //
  86. // Compute the target set of processors, disable context switching,
  87. // and send the flush entire parameters to the target processors,
  88. // if any, for execution.
  89. //
  90. if (AllProcessors != FALSE) {
  91. OldIrql = KeRaiseIrqlToSynchLevel();
  92. TargetProcessors = KeActiveProcessors;
  93. } else {
  94. KiLockContextSwap(&OldIrql);
  95. Thread = KeGetCurrentThread();
  96. Process = Thread->ApcState.Process;
  97. TargetProcessors = Process->ActiveProcessors;
  98. if (TargetProcessors != Process->RunOnProcessors) {
  99. Process->ProcessSequence = KiMasterSequence - 1;
  100. }
  101. }
  102. EntireSet = KeActiveProcessors & PCR->NotMember;
  103. TargetProcessors &= PCR->NotMember;
  104. //
  105. // If the target set fo processors is equal to the full set of processors,
  106. // then set the TB flush time stamp busy.
  107. //
  108. if (TargetProcessors == EntireSet) {
  109. KiSetTbFlushTimeStampBusy();
  110. }
  111. //
  112. // Send packet to target processors.
  113. //
  114. if (TargetProcessors != 0) {
  115. KiIpiSendPacket(TargetProcessors,
  116. KiFlushEntireTbTarget,
  117. NULL,
  118. NULL,
  119. NULL);
  120. }
  121. IPI_INSTRUMENT_COUNT(KeGetCurrentPrcb()->Number, FlushEntireTb);
  122. //
  123. // Flush TB on current processor.
  124. //
  125. // KeFlushCurrentTb();
  126. __tbia();
  127. //
  128. // Wait until all target processors have finished.
  129. //
  130. if (TargetProcessors != 0) {
  131. KiIpiStallOnPacketTargets(TargetProcessors);
  132. }
  133. //
  134. // If the target set of processors is equal to the full set of processors,
  135. // then clear the TB flush time stamp busy.
  136. //
  137. if (TargetProcessors == EntireSet) {
  138. KiClearTbFlushTimeStampBusy();
  139. }
  140. //
  141. // Lower IRQL and unlock as appropriate.
  142. //
  143. if (AllProcessors != FALSE) {
  144. KeLowerIrql(OldIrql);
  145. } else {
  146. KiUnlockContextSwap(OldIrql);
  147. }
  148. return;
  149. }
  150. VOID
  151. KiFlushEntireTbTarget (
  152. IN PKIPI_CONTEXT SignalDone,
  153. IN PVOID Parameter1,
  154. IN PVOID Parameter2,
  155. IN PVOID Parameter3
  156. )
  157. /*++
  158. Routine Description:
  159. This is the target function for flushing the entire TB.
  160. Arguments:
  161. SignalDone - Supplies a pointer to a variable that is cleared when the
  162. requested operation has been performed.
  163. Parameter1 - Parameter3 - not used
  164. Return Value:
  165. None.
  166. --*/
  167. {
  168. //
  169. // Flush the entire TB on the current processor
  170. //
  171. KiIpiSignalPacketDone(SignalDone);
  172. // KeFlushCurrentTb();
  173. __tbia();
  174. IPI_INSTRUMENT_COUNT(KeGetCurrentPrcb()->Number, FlushEntireTb);
  175. return;
  176. }
  177. VOID
  178. KeFlushMultipleTb (
  179. IN ULONG Number,
  180. IN PVOID *Virtual,
  181. IN BOOLEAN Invalid,
  182. IN BOOLEAN AllProcessors,
  183. IN PHARDWARE_PTE *PtePointer OPTIONAL,
  184. IN HARDWARE_PTE PteValue
  185. )
  186. /*++
  187. Routine Description:
  188. This function flushes multiple entries from the translation buffer
  189. on all processors that are currently running threads which are
  190. children of the current process or flushes a multiple entries from
  191. the translation buffer on all processors in the host configuration.
  192. Arguments:
  193. Number - Supplies the number of TB entries to flush.
  194. Virtual - Supplies a pointer to an array of virtual addresses that
  195. are within the pages whose translation buffer entries are to be
  196. flushed.
  197. Invalid - Supplies a boolean value that specifies the reason for
  198. flushing the translation buffer.
  199. AllProcessors - Supplies a boolean value that determines which
  200. translation buffers are to be flushed.
  201. PtePointer - Supplies an optional pointer to an array of pointers to
  202. page table entries that receive the specified page table entry
  203. value.
  204. PteValue - Supplies the the new page table entry value.
  205. Return Value:
  206. The previous contents of the specified page table entry is returned
  207. as the function value.
  208. --*/
  209. {
  210. ULONG Index;
  211. KIRQL OldIrql;
  212. PKPROCESS Process;
  213. KAFFINITY TargetProcessors;
  214. PKTHREAD Thread;
  215. //
  216. // Compute the target set of processors and send the flush multiple
  217. // parameters to the target processors, if any, for execution.
  218. //
  219. if (AllProcessors != FALSE) {
  220. OldIrql = KeRaiseIrqlToSynchLevel();
  221. TargetProcessors = KeActiveProcessors;
  222. } else {
  223. KiLockContextSwap(&OldIrql);
  224. Thread = KeGetCurrentThread();
  225. Process = Thread->ApcState.Process;
  226. TargetProcessors = Process->ActiveProcessors;
  227. if (TargetProcessors != Process->RunOnProcessors) {
  228. Process->ProcessSequence = KiMasterSequence - 1;
  229. }
  230. }
  231. //
  232. // If a page table entry address address is specified, then set the
  233. // specified page table entries to the specific value.
  234. //
  235. if (ARGUMENT_PRESENT(PtePointer)) {
  236. for (Index = 0; Index < Number; Index += 1) {
  237. *PtePointer[Index] = PteValue;
  238. }
  239. }
  240. TargetProcessors &= PCR->NotMember;
  241. if (TargetProcessors != 0) {
  242. KiIpiSendPacket(TargetProcessors,
  243. KiFlushMultipleTbTarget,
  244. ULongToPtr(Number),
  245. (PVOID)Virtual,
  246. NULL);
  247. }
  248. IPI_INSTRUMENT_COUNT(KeGetCurrentPrcb()->Number, FlushMultipleTb);
  249. //
  250. // Flush the specified entries from the TB on the current processor.
  251. //
  252. KiFlushMultipleTb(Invalid, &Virtual[0], Number);
  253. //
  254. // Wait until all target processors have finished.
  255. //
  256. if (TargetProcessors != 0) {
  257. KiIpiStallOnPacketTargets(TargetProcessors);
  258. }
  259. //
  260. // If the context swap lock was acquired, release it.
  261. //
  262. if (AllProcessors != FALSE) {
  263. KeLowerIrql(OldIrql);
  264. } else {
  265. KiUnlockContextSwap(OldIrql);
  266. }
  267. return;
  268. }
  269. VOID
  270. KiFlushMultipleTbTarget (
  271. IN PKIPI_CONTEXT SignalDone,
  272. IN PVOID Number,
  273. IN PVOID Virtual,
  274. IN PVOID Pid
  275. )
  276. /*++
  277. Routine Description:
  278. This is the target function for flushing multiple TB entries.
  279. Arguments:
  280. SignalDone Supplies a pointer to a variable that is cleared when the
  281. requested operation has been performed.
  282. Number - Supplies the number of TB entries to flush.
  283. Virtual - Supplies a pointer to an array of virtual addresses that
  284. are within the pages whose translation buffer entries are to be
  285. flushed.
  286. Pid - Supplies the PID of the TB entries to flush.
  287. Return Value:
  288. None.
  289. --*/
  290. {
  291. ULONG Index;
  292. ULONG Limit;
  293. PVOID Array[FLUSH_MULTIPLE_MAXIMUM];
  294. //
  295. // Flush multiple entries from the TB on the current processor
  296. //
  297. //
  298. // Capture the virtual addresses that are to be flushed from the TB
  299. // on the current processor and clear the packet address.
  300. //
  301. Limit = (ULONG)((ULONG_PTR)Number);
  302. for (Index = 0; Index < Limit; Index += 1) {
  303. Array[Index] = ((PVOID *)(Virtual))[Index];
  304. }
  305. KiIpiSignalPacketDone(SignalDone);
  306. //
  307. // Flush the specified virtual addresses from the TB on the current
  308. // processor.
  309. //
  310. KiFlushMultipleTb(TRUE, &Array[0], Limit);
  311. IPI_INSTRUMENT_COUNT(KeGetCurrentPrcb()->Number, FlushMultipleTb);
  312. return;
  313. }
  314. HARDWARE_PTE
  315. KeFlushSingleTb (
  316. IN PVOID Virtual,
  317. IN BOOLEAN Invalid,
  318. IN BOOLEAN AllProcessors,
  319. IN PHARDWARE_PTE PtePointer,
  320. IN HARDWARE_PTE PteValue
  321. )
  322. /*++
  323. Routine Description:
  324. This function flushes a single entry from the translation buffer
  325. on all processors that are currently running threads which are
  326. children of the current process or flushes a single entry from
  327. the translation buffer on all processors in the host configuration.
  328. Arguments:
  329. Virtual - Supplies a virtual address that is within the page whose
  330. translation buffer entry is to be flushed.
  331. Invalid - Supplies a boolean value that specifies the reason for
  332. flushing the translation buffer.
  333. AllProcessors - Supplies a boolean value that determines which
  334. translation buffers are to be flushed.
  335. PtePointer - Supplies a pointer to the page table entry which
  336. receives the specified value.
  337. PteValue - Supplies the the new page table entry value.
  338. Return Value:
  339. The previous contents of the specified page table entry is returned
  340. as the function value.
  341. --*/
  342. {
  343. KIRQL OldIrql;
  344. HARDWARE_PTE OldPte;
  345. PKPROCESS Process;
  346. KAFFINITY TargetProcessors;
  347. PKTHREAD Thread;
  348. //
  349. // Compute the target set of processors and send the flush single
  350. // paramters to the target processors, if any, for execution.
  351. //
  352. if (AllProcessors != FALSE) {
  353. OldIrql = KeRaiseIrqlToSynchLevel();
  354. TargetProcessors = KeActiveProcessors;
  355. } else {
  356. KiLockContextSwap(&OldIrql);
  357. Thread = KeGetCurrentThread();
  358. Process = Thread->ApcState.Process;
  359. TargetProcessors = Process->ActiveProcessors;
  360. if (TargetProcessors != Process->RunOnProcessors) {
  361. Process->ProcessSequence = KiMasterSequence - 1;
  362. }
  363. }
  364. //
  365. // Capture the previous contents of the page table entry and set the
  366. // page table entry to the new value.
  367. //
  368. OldPte = *PtePointer;
  369. *PtePointer = PteValue;
  370. TargetProcessors &= PCR->NotMember;
  371. if (TargetProcessors != 0) {
  372. KiIpiSendPacket(TargetProcessors,
  373. KiFlushSingleTbTarget,
  374. (PVOID)Virtual,
  375. NULL,
  376. NULL);
  377. }
  378. IPI_INSTRUMENT_COUNT(KeGetCurrentPrcb()->Number, FlushSingleTb);
  379. //
  380. // Flush the specified entry from the TB on the current processor.
  381. //
  382. // KiFlushSingleTb(Invalid, Virtual);
  383. __tbis(Virtual);
  384. //
  385. // Wait until all target processors have finished.
  386. //
  387. if (TargetProcessors != 0) {
  388. KiIpiStallOnPacketTargets(TargetProcessors);
  389. }
  390. if (AllProcessors != FALSE) {
  391. KeLowerIrql(OldIrql);
  392. } else {
  393. KiUnlockContextSwap(OldIrql);
  394. }
  395. //
  396. // return the previous page table entry value.
  397. //
  398. return OldPte;
  399. }
  400. VOID
  401. KiFlushSingleTbTarget (
  402. IN PKIPI_CONTEXT SignalDone,
  403. IN PVOID Virtual,
  404. IN PVOID Pid,
  405. IN PVOID Parameter3
  406. )
  407. /*++
  408. Routine Description:
  409. This is the target function for flushing a single TB entry.
  410. Arguments:
  411. SignalDone Supplies a pointer to a variable that is cleared when the
  412. requested operation has been performed.
  413. Virtual - Supplies a virtual address that is within the page whose
  414. translation buffer entry is to be flushed.
  415. RequestPacket - Supplies a pointer to a flush single TB packet address.
  416. Pid - Supplies the PID of the TB entries to flush.
  417. Parameter3 - Not used.
  418. Return Value:
  419. None.
  420. --*/
  421. {
  422. //
  423. // Flush a single entry form the TB on the current processor.
  424. //
  425. KiIpiSignalPacketDone(SignalDone);
  426. // KiFlushSingleTb(TRUE, Virtual);
  427. __tbis(Virtual);
  428. IPI_INSTRUMENT_COUNT(KeGetCurrentPrcb()->Number, FlushSingleTb);
  429. return;
  430. }
  431. #endif // !defined(NT_UP)
  432. VOID
  433. KeFlushMultipleTb64 (
  434. IN ULONG Number,
  435. IN PULONG_PTR Virtual,
  436. IN BOOLEAN Invalid,
  437. IN BOOLEAN AllProcessors,
  438. IN PHARDWARE_PTE *PtePointer OPTIONAL,
  439. IN HARDWARE_PTE PteValue
  440. )
  441. /*++
  442. Routine Description:
  443. This function flushes multiple entries from the translation buffer
  444. on all processors that are currently running threads which are
  445. children of the current process or flushes a multiple entries from
  446. the translation buffer on all processors in the host configuration.
  447. Arguments:
  448. Number - Supplies the number of TB entries to flush.
  449. Virtual - Supplies a pointer to an array of virtual page numbers that
  450. are flushed from the TB.
  451. Invalid - Supplies a boolean value that specifies the reason for
  452. flushing the translation buffer.
  453. AllProcessors - Supplies a boolean value that determines which
  454. translation buffers are to be flushed.
  455. PtePointer - Supplies an optional pointer to an array of pointers to
  456. page table entries that receive the specified page table entry
  457. value.
  458. PteValue - Supplies the the new page table entry value.
  459. Return Value:
  460. The previous contents of the specified page table entry is returned
  461. as the function value.
  462. --*/
  463. {
  464. ULONG Index;
  465. KIRQL OldIrql;
  466. PKPROCESS Process;
  467. KAFFINITY TargetProcessors;
  468. PKTHREAD Thread;
  469. ASSERT(Number <= FLUSH_MULTIPLE_MAXIMUM);
  470. //
  471. // Compute the target set of processors.
  472. //
  473. #if defined(NT_UP)
  474. OldIrql = KeRaiseIrqlToSynchLevel();
  475. #else
  476. if (AllProcessors != FALSE) {
  477. OldIrql = KeRaiseIrqlToSynchLevel();
  478. TargetProcessors = KeActiveProcessors;
  479. } else {
  480. KiLockContextSwap(&OldIrql);
  481. Thread = KeGetCurrentThread();
  482. Process = Thread->ApcState.Process;
  483. TargetProcessors = Process->ActiveProcessors;
  484. if (TargetProcessors != Process->RunOnProcessors) {
  485. Process->ProcessSequence = KiMasterSequence - 1;
  486. }
  487. }
  488. TargetProcessors &= PCR->NotMember;
  489. #endif
  490. //
  491. // If a page table entry address array is specified, then set the
  492. // specified page table entries to the specific value.
  493. //
  494. if (ARGUMENT_PRESENT(PtePointer)) {
  495. for (Index = 0; Index < Number; Index += 1) {
  496. *PtePointer[Index] = PteValue;
  497. }
  498. }
  499. //
  500. // If any target processors are specified, then send a flush multiple
  501. // packet to the target set of processor.
  502. //
  503. #if !defined(NT_UP)
  504. if (TargetProcessors != 0) {
  505. KiIpiSendPacket(TargetProcessors,
  506. KiFlushMultipleTbTarget64,
  507. ULongToPtr(Number),
  508. (PVOID)Virtual,
  509. NULL);
  510. }
  511. #endif
  512. //
  513. // Flush the specified entries from the TB on the current processor.
  514. //
  515. KiFlushMultipleTb64(Invalid, &Virtual[0], Number);
  516. //
  517. // Wait until all target processors have finished.
  518. //
  519. #if defined(NT_UP)
  520. KeLowerIrql(OldIrql);
  521. #else
  522. if (TargetProcessors != 0) {
  523. KiIpiStallOnPacketTargets(TargetProcessors);
  524. }
  525. if (AllProcessors != FALSE) {
  526. KeLowerIrql(OldIrql);
  527. } else {
  528. KiUnlockContextSwap(OldIrql);
  529. }
  530. #endif
  531. return;
  532. }
  533. #if !defined(NT_UP)
  534. VOID
  535. KiFlushMultipleTbTarget64 (
  536. IN PKIPI_CONTEXT SignalDone,
  537. IN PVOID Number,
  538. IN PVOID Virtual,
  539. IN PVOID Pid
  540. )
  541. /*++
  542. Routine Description:
  543. This is the target function for flushing multiple TB entries.
  544. Arguments:
  545. SignalDone Supplies a pointer to a variable that is cleared when the
  546. requested operation has been performed.
  547. Number - Supplies the number of TB entries to flush.
  548. Virtual - Supplies a pointer to an array of virtual page numbers that
  549. are flushed from the TB.
  550. Pid - Supplies the PID of the TB entries to flush.
  551. Return Value:
  552. None.
  553. --*/
  554. {
  555. ULONG Index;
  556. ULONG Limit;
  557. ULONG_PTR Array[FLUSH_MULTIPLE_MAXIMUM];
  558. ASSERT((ULONG_PTR)Number <= FLUSH_MULTIPLE_MAXIMUM);
  559. //
  560. // Capture the virtual addresses that are to be flushed from the TB
  561. // on the current processor and clear the packet address.
  562. //
  563. Limit = (ULONG)((ULONG_PTR)Number);
  564. for (Index = 0; Index < Limit; Index += 1) {
  565. Array[Index] = ((PULONG_PTR)(Virtual))[Index];
  566. }
  567. KiIpiSignalPacketDone(SignalDone);
  568. //
  569. // Flush the specified virtual addresses from the TB on the current
  570. // processor.
  571. //
  572. KiFlushMultipleTb64(TRUE, &Array[0], Limit);
  573. return;
  574. }
  575. #endif
  576. HARDWARE_PTE
  577. KeFlushSingleTb64 (
  578. IN ULONG_PTR Virtual,
  579. IN BOOLEAN Invalid,
  580. IN BOOLEAN AllProcessors,
  581. IN PHARDWARE_PTE PtePointer,
  582. IN HARDWARE_PTE PteValue
  583. )
  584. /*++
  585. Routine Description:
  586. This function flushes a single entry from the translation buffer
  587. on all processors that are currently running threads which are
  588. children of the current process or flushes a single entry from
  589. the translation buffer on all processors in the host configuration.
  590. Arguments:
  591. Virtual - Supplies a virtual page number that is flushed from the TB.
  592. Invalid - Supplies a boolean value that specifies the reason for
  593. flushing the translation buffer.
  594. AllProcessors - Supplies a boolean value that determines which
  595. translation buffers are to be flushed.
  596. PtePointer - Supplies a pointer to the page table entry which
  597. receives the specified value.
  598. PteValue - Supplies the the new page table entry value.
  599. Return Value:
  600. The previous contents of the specified page table entry is returned
  601. as the function value.
  602. --*/
  603. {
  604. KIRQL OldIrql;
  605. HARDWARE_PTE OldPte;
  606. PKPROCESS Process;
  607. KAFFINITY TargetProcessors;
  608. PKTHREAD Thread;
  609. //
  610. // Compute the target set of processors.
  611. //
  612. #if defined(NT_UP)
  613. OldIrql = KeRaiseIrqlToSynchLevel();
  614. #else
  615. if (AllProcessors != FALSE) {
  616. OldIrql = KeRaiseIrqlToSynchLevel();
  617. TargetProcessors = KeActiveProcessors;
  618. } else {
  619. KiLockContextSwap(&OldIrql);
  620. Thread = KeGetCurrentThread();
  621. Process = Thread->ApcState.Process;
  622. TargetProcessors = Process->ActiveProcessors;
  623. if (TargetProcessors != Process->RunOnProcessors) {
  624. Process->ProcessSequence = KiMasterSequence - 1;
  625. }
  626. }
  627. TargetProcessors &= PCR->NotMember;
  628. #endif
  629. //
  630. // Capture the previous contents of the page table entry and set the
  631. // page table entry to the new value.
  632. //
  633. OldPte = *PtePointer;
  634. *PtePointer = PteValue;
  635. //
  636. // If any target processors are specified, then send a flush single
  637. // packet to the target set of processors.
  638. #if !defined(NT_UP)
  639. if (TargetProcessors != 0) {
  640. KiIpiSendPacket(TargetProcessors,
  641. KiFlushSingleTbTarget64,
  642. (PVOID)Virtual,
  643. NULL,
  644. NULL);
  645. }
  646. #endif
  647. //
  648. // Flush the specified entry from the TB on the current processor.
  649. //
  650. KiFlushSingleTb64(Invalid, Virtual);
  651. //
  652. // Wait until all target processors have finished.
  653. //
  654. #if defined(NT_UP)
  655. KeLowerIrql(OldIrql);
  656. #else
  657. if (TargetProcessors != 0) {
  658. KiIpiStallOnPacketTargets(TargetProcessors);
  659. }
  660. if (AllProcessors != FALSE) {
  661. KeLowerIrql(OldIrql);
  662. } else {
  663. KiUnlockContextSwap(OldIrql);
  664. }
  665. #endif
  666. return OldPte;
  667. }
  668. #if !defined(NT_UP)
  669. VOID
  670. KiFlushSingleTbTarget64 (
  671. IN PKIPI_CONTEXT SignalDone,
  672. IN PVOID Virtual,
  673. IN PVOID Pid,
  674. IN PVOID Parameter3
  675. )
  676. /*++
  677. Routine Description:
  678. This is the target function for flushing a single TB entry.
  679. Arguments:
  680. SignalDone Supplies a pointer to a variable that is cleared when the
  681. requested operation has been performed.
  682. Virtual - Supplies a virtual page number that is flushed from the TB.
  683. RequestPacket - Supplies a pointer to a flush single TB packet address.
  684. Pid - Not used.
  685. Parameter3 - Not used.
  686. Return Value:
  687. None.
  688. --*/
  689. {
  690. //
  691. // Flush a single entry form the TB on the current processor.
  692. //
  693. KiIpiSignalPacketDone(SignalDone);
  694. KiFlushSingleTb64(TRUE, (ULONG_PTR)Virtual);
  695. return;
  696. }
  697. #endif