test: i386/flushtb.c File Reference

Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

# flushtb.c File Reference

`#include "ki.h"`

Go to the source code of this file.

## Functions

VOID | KiFlushTargetEntireTb (IN PKIPI_CONTEXT SignalDone, IN PVOID Invalid, IN PVOID Parameter2, IN PVOID Parameter3)
VOID | KiFlushTargetMultipleTb (IN PKIPI_CONTEXT SignalDone, IN PVOID Parameter1, IN PVOID Parameter2, IN PVOID Parameter3)
VOID | KiFlushTargetSingleTb (IN PKIPI_CONTEXT SignalDone, IN PVOID Parameter1, IN PVOID Parameter2, IN PVOID Parameter3)
HARDWARE_PTE | KiFlushSingleTbSynchronous (IN PVOID Virtual, IN BOOLEAN Invalid, IN BOOLEAN AllProcessors, IN PHARDWARE_PTE PtePointer, IN HARDWARE_PTE PteValue)
VOID | KiFlushTargetSingleTbSynchronous (IN PKIPI_CONTEXT SignalDone, IN PVOID Parameter1, IN PVOID Parameter2, IN PVOID Parameter3)
VOID | Ki386UseSynchronousTbFlush (IN volatile PLONG Number)
VOID | KeFlushEntireTb (IN BOOLEAN Invalid, IN BOOLEAN AllProcessors)
VOID | KeFlushMultipleTb (IN ULONG Number, IN PVOID *Virtual, IN BOOLEAN Invalid, IN BOOLEAN AllProcessors, IN PHARDWARE_PTE *PtePointer OPTIONAL, IN HARDWARE_PTE PteValue)
HARDWARE_PTE | KeFlushSingleTb (IN PVOID Virtual, IN BOOLEAN Invalid, IN BOOLEAN AllProcessors, IN PHARDWARE_PTE PtePointer, IN HARDWARE_PTE PteValue)

## Function Documentation

VOID KeFlushEntireTb | ( | IN BOOLEAN | Invalid,
|  | IN BOOLEAN | AllProcessors
| ) |

Definition at line 94 of file i386/flushtb.c.

References _KPROCESS::ActiveProcessors, FALSE, IPI_INSTRUMENT_COUNT, KeActiveProcessors, KeFlushCurrentTb(), KeGetCurrentPrcb, KeLowerIrql(), KiFlushTargetEntireTb(), KiIpiSendPacket(), KiIpiStallOnPacketTargets(), KiLockContextSwap, KiUnlockContextSwap, and NULL.

    00101                    :
    00102
    00103     This function flushes the entire translation buffer (TB) on all processors
    00104     that are currently running threads which are child of the current process
    00105     or flushes the entire translation buffer on all processors in the host
    00106     configuration.
    00107
    00108 Arguments:
    00109
    00110     Invalid - Supplies a boolean value that specifies the reason for flushing
    00111         the translation buffer.
    00112
    00113     AllProcessors - Supplies a boolean value that determines which translation
    00114         buffers are to be flushed.
    00115
    00116 Return Value:
    00117
    00118     None.
    00119
    00120 --*/
    00121
    00122 {
    00123
    00124     KIRQL OldIrql;
    00125     PKPRCB Prcb;
    00126     PKPROCESS Process;
    00127     KAFFINITY TargetProcessors;
    00128
    00129     //
    00130     // Compute the target set of processors, disable context switching,
    00131     // and send the flush entire parameters to the target processors,
    00132     // if any, for execution.
    00133     //
    00134
    00135 #if defined(NT_UP)
    00136
    00137     OldIrql = KeRaiseIrqlToSynchLevel();
    00138
    00139 #else
    00140
    00141     if (AllProcessors != FALSE) {
    00142         OldIrql = KeRaiseIrqlToSynchLevel();
    00143         Prcb = KeGetCurrentPrcb();
    00144         TargetProcessors = KeActiveProcessors;
    00145
    00146     } else {
    00147         KiLockContextSwap(&OldIrql);
    00148         Prcb = KeGetCurrentPrcb();
    00149         Process = Prcb->CurrentThread->ApcState.Process;
    00150         TargetProcessors = Process->ActiveProcessors;
    00151     }
    00152
    00153     TargetProcessors &= ~Prcb->SetMember;
    00154     if (TargetProcessors != 0) {
    00155         KiIpiSendPacket(TargetProcessors,
    00156                         KiFlushTargetEntireTb,
    00157                         NULL,
    00158                         NULL,
    00159                         NULL);
    00160
    00161         IPI_INSTRUMENT_COUNT (Prcb->Number, FlushEntireTb);
    00162     }
    00163
    00164 #endif
    00165
    00166     //
    00167     // Flush TB on current processor.
    00168     //
    00169
    00170     KeFlushCurrentTb();
    00171
    00172     //
    00173     // Wait until all target processors have finished and complete packet.
    00174     //
    00175
    00176 #if defined(NT_UP)
    00177
    00178     KeLowerIrql(OldIrql);
    00179
    00180 #else
    00181
    00182     if (TargetProcessors != 0) {
    00183         KiIpiStallOnPacketTargets(TargetProcessors);
    00184     }
    00185
    00186     if (AllProcessors != FALSE) {
    00187         KeLowerIrql(OldIrql);
    00188
    00189     } else {
    00190         KiUnlockContextSwap(OldIrql);
    00191     }
    00192
    00193 #endif
    00194
    00195     return;
    00196 }

VOID KeFlushMultipleTb | ( | IN ULONG | Number,
|  | IN PVOID * | Virtual,
|  | IN BOOLEAN | Invalid,
|  | IN BOOLEAN | AllProcessors,
|  | IN PHARDWARE_PTE *PtePointer | OPTIONAL,
|  | IN HARDWARE_PTE | PteValue
| ) |

Definition at line 240 of file i386/flushtb.c.

References _KPROCESS::ActiveProcessors, FALSE, Index, IPI_INSTRUMENT_COUNT, KeActiveProcessors, KeGetCurrentPrcb, KeLowerIrql(), KiFlushSingleTb(), KiFlushTargetMultipleTb(), KiIpiSendPacket(), KiIpiStallOnPacketTargets(), KiLockContextSwap, KiUnlockContextSwap, and Virtual.

    00251                    :
    00252
    00253     This function flushes multiple entries from the translation buffer
    00254     on all processors that are currently running threads which are
    00255     children of the current process or flushes a multiple entries from
    00256     the translation buffer on all processors in the host configuration.
    00257
    00258 Arguments:
    00259
    00260     Number - Supplies the number of TB entries to flush.
    00261
    00262     Virtual - Supplies a pointer to an array of virtual addresses that
    00263         are within the pages whose translation buffer entries are to be
    00264         flushed.
    00265
    00266     Invalid - Supplies a boolean value that specifies the reason for
    00267         flushing the translation buffer.
    00268
    00269     AllProcessors - Supplies a boolean value that determines which
    00270         translation buffers are to be flushed.
    00271
    00272     PtePointer - Supplies an optional pointer to an array of pointers to
    00273        page table entries that receive the specified page table entry
    00274        value.
    00275
    00276     PteValue - Supplies the the new page table entry value.
    00277
    00278 Return Value:
    00279
    00280     The previous contents of the specified page table entry is returned
    00281     as the function value.
    00282
    00283 --*/
    00284
    00285 {
    00286
    00287     ULONG Index;
    00288     KIRQL OldIrql;
    00289     PKPRCB Prcb;
    00290     PKPROCESS Process;
    00291     KAFFINITY TargetProcessors;
    00292
    00293     //
    00294     // Compute target set of processors.
    00295     //
    00296
    00297     if (AllProcessors != FALSE) {
    00298         OldIrql = KeRaiseIrqlToSynchLevel();
    00299         Prcb = KeGetCurrentPrcb();
    00300         TargetProcessors = KeActiveProcessors;
    00301
    00302     } else {
    00303         KiLockContextSwap(&OldIrql);
    00304         Prcb = KeGetCurrentPrcb();
    00305         Process = Prcb->CurrentThread->ApcState.Process;
    00306         TargetProcessors = Process->ActiveProcessors;
    00307     }
    00308
    00309     TargetProcessors &= ~Prcb->SetMember;
    00310
    00311     //
    00312     // If a page table entry address array is specified, then set the
    00313     // specified page table entries to the specific value.
    00314     //
    00315
    00316     if (ARGUMENT_PRESENT(PtePointer)) {
    00317         for (Index = 0; Index < Number; Index += 1) {
    00318             KI_FILL_PTE(PtePointer[Index], PteValue);
    00319         }
    00320     }
    00321
    00322     //
    00323     // If any target processors are specified, then send a flush multiple
    00324     // packet to the target set of processors.
    00325     //
    00326
    00327     if (TargetProcessors != 0) {
    00328         KiIpiSendPacket(TargetProcessors,
    00329                         KiFlushTargetMultipleTb,
    00330                         (PVOID)Invalid,
    00331                         (PVOID)Number,
    00332                         (PVOID)Virtual);
    00333
    00334         IPI_INSTRUMENT_COUNT (Prcb->Number, FlushMultipleTb);
    00335     }
    00336
    00337     //
    00338     // Flush the specified entries from the TB on the current processor.
    00339     //
    00340
    00341     for (Index = 0; Index < Number; Index += 1) {
    00342         KiFlushSingleTb(Invalid, Virtual[Index]);
    00343     }
    00344
    00345     //
    00346     // Wait until all target processors have finished and complete packet.
    00347     //
    00348
    00349     if (TargetProcessors != 0) {
    00350         KiIpiStallOnPacketTargets(TargetProcessors);
    00351     }
    00352
    00353     //
    00354     // Release the context swap lock.
    00355     //
    00356
    00357     if (AllProcessors != FALSE) {
    00358         KeLowerIrql(OldIrql);
    00359
    00360     } else {
    00361         KiUnlockContextSwap(OldIrql);
    00362     }
    00363
    00364     return;
    00365 }

HARDWARE_PTE KeFlushSingleTb | ( | IN PVOID | Virtual,
|  | IN BOOLEAN | Invalid,
|  | IN BOOLEAN | AllProcessors,
|  | IN PHARDWARE_PTE | PtePointer,
|  | IN HARDWARE_PTE | PteValue
| ) |

Definition at line 428 of file i386/flushtb.c.

References _KPROCESS::ActiveProcessors, FALSE, IPI_INSTRUMENT_COUNT, KeActiveProcessors, KeGetCurrentPrcb, KeLowerIrql(), KiFlushSingleTb(), KiFlushTargetSingleTb(), KiIpiSendPacket(), KiIpiStallOnPacketTargets(), KiLockContextSwap, KiUnlockContextSwap, NULL, and Virtual.

    00438                    :
    00439
    00440     This function flushes a single entry from translation buffer (TB) on all
    00441     processors that are currently running threads which are child of the current
    00442     process or flushes the entire translation buffer on all processors in the
    00443     host configuration.
    00444
    00445 Arguments:
    00446
    00447     Virtual - Supplies a virtual address that is within the page whose
    00448         translation buffer entry is to be flushed.
    00449
    00450     Invalid - Supplies a boolean value that specifies the reason for flushing
    00451         the translation buffer.
    00452
    00453     AllProcessors - Supplies a boolean value that determines which translation
    00454         buffers are to be flushed.
    00455
    00456     PtePointer - Address of Pte to update with new value.
    00457
    00458     PteValue - New value to put in the Pte.  Will simply be assigned to
    00459         *PtePointer, in a fashion correct for the hardware.
    00460
    00461 Return Value:
    00462
    00463     Returns the contents of the PtePointer before the new value
    00464     is stored.
    00465
    00466 --*/
    00467
    00468 {
    00469
    00470     KIRQL OldIrql;
    00471     PKPRCB Prcb;
    00472     PKPROCESS Process;
    00473     HARDWARE_PTE OldPteValue;
    00474     KAFFINITY TargetProcessors;
    00475
    00476     //
    00477     // Compute target set of processors.
    00478     //
    00479
    00480     if (AllProcessors != FALSE) {
    00481         OldIrql = KeRaiseIrqlToSynchLevel();
    00482         Prcb = KeGetCurrentPrcb();
    00483         TargetProcessors = KeActiveProcessors;
    00484
    00485     } else {
    00486         KiLockContextSwap(&OldIrql);
    00487         Prcb = KeGetCurrentPrcb();
    00488         Process = Prcb->CurrentThread->ApcState.Process;
    00489         TargetProcessors = Process->ActiveProcessors;
    00490     }
    00491
    00492     TargetProcessors &= ~Prcb->SetMember;
    00493
    00494     //
    00495     // Capture the previous contents of the page table entry and set the
    00496     // page table entry to the new value.
    00497     //
    00498
    00499     KI_SWAP_PTE(PtePointer, PteValue, OldPteValue);
    00500
    00501     //
    00502     // If any target processors are specified, then send a flush single
    00503     // packet to the target set of processors.
    00504     //
    00505
    00506     if (TargetProcessors != 0) {
    00507         KiIpiSendPacket(TargetProcessors,
    00508                         KiFlushTargetSingleTb,
    00509                         (PVOID)Invalid,
    00510                         (PVOID)Virtual,
    00511                         NULL);
    00512
    00513         IPI_INSTRUMENT_COUNT(Prcb->Number, FlushSingleTb);
    00514     }
    00515
    00516
    00517     //
    00518     // Flush the specified entry from the TB on the current processor.
    00519     //
    00520
    00521     KiFlushSingleTb(Invalid, Virtual);
    00522
    00523     //
    00524     // Wait until all target processors have finished and complete packet.
    00525     //
    00526
    00527     if (TargetProcessors != 0) {
    00528         KiIpiStallOnPacketTargets(TargetProcessors);
    00529     }
    00530
    00531     //
    00532     // Release the context swap lock.
    00533     //
    00534
    00535     if (AllProcessors != FALSE) {
    00536         KeLowerIrql(OldIrql);
    00537
    00538     } else {
    00539         KiUnlockContextSwap(OldIrql);
    00540     }
    00541
    00542     return(OldPteValue);
    00543 }

VOID Ki386UseSynchronousTbFlush | ( | IN volatile PLONG | Number | ) |

Definition at line 747 of file i386/flushtb.c.

References KeFlushSingleTb(), KeGetCurrentPrcb, and KiFlushSingleTbSynchronous().

Referenced by KiInitMachineDependent().

    00750 {
    00751     PKPRCB              Prcb;
    00752     volatile PUCHAR     Patch;
    00753
    00754     Prcb = KeGetCurrentPrcb();
    00755     Patch = (PUCHAR) KeFlushSingleTb;
    00756
    00757     //
    00758     // Signal we're here and wait for others
    00759     //
    00760
    00761     InterlockedDecrement (Number);
    00762     while (*Number) ;
    00763
    00764     //
    00765     // If this is processor 0 apply the patch
    00766     //
    00767
    00768     if (Prcb->Number == 0) {
    00769         *((PULONG) &Patch[1]) = ((ULONG) &KiFlushSingleTbSynchronous) - ((ULONG) Patch) - 5;
    00770         Patch[0] = 0xe9;
    00771     }
    00772
    00773     //
    00774     // Wait for processor 0 to complete installation of handler
    00775     //
    00776
    00777     while (Patch[0] != 0xe9) ;
    00778 }

HARDWARE_PTE KiFlushSingleTbSynchronous | ( | IN PVOID | Virtual,
|  | IN BOOLEAN | Invalid,
|  | IN BOOLEAN | AllProcessors,
|  | IN PHARDWARE_PTE | PtePointer,
|  | IN HARDWARE_PTE | PteValue
| ) |

Definition at line 589 of file i386/flushtb.c.

References _KPROCESS::ActiveProcessors, FALSE, IPI_INSTRUMENT_COUNT, KeActiveProcessors, KeGetCurrentPrcb, KiFlushSingleTb(), KiFlushTargetSingleTbSynchronous(), KiIpiStallOnPacketTargets(), KiLockContextSwap, KiUnlockContextSwap, and Virtual.

Referenced by Ki386UseSynchronousTbFlush().

    00599                    :
    00600
    00601     This function is a slow synchronous version of KeFlushSingleTb.  We need
    00602     this function as many P6's don't actually know how to deal with PTEs in
    00603     an MP safe manner.
    00604
    00605 Arguments:
    00606
    00607     See KeFlushSingleTb
    00608
    00609 Return Value:
    00610
    00611     See KeFlushSingleTb
    00612
    00613 --*/
    00614 {
    00615
    00616     KIRQL OldIrql;
    00617     PKPRCB Prcb;
    00618     PKPROCESS Process;
    00619     HARDWARE_PTE OldPteValue;
    00620     KAFFINITY TargetProcessors;
    00621
    00622     //
    00623     // Synchronize will all other single flush calls (and other
    00624     // IPIs which use reverse stalls)
    00625     //
    00626
    00627     KiLockContextSwap(&OldIrql);
    00628
    00629     //
    00630     // Compute target set of processors.
    00631     //
    00632
    00633     Prcb = KeGetCurrentPrcb();
    00634     if (AllProcessors != FALSE) {
    00635         TargetProcessors = KeActiveProcessors;
    00636     } else {
    00637         Process = Prcb->CurrentThread->ApcState.Process;
    00638         TargetProcessors = Process->ActiveProcessors;
    00639     }
    00640
    00641     TargetProcessors &= ~Prcb->SetMember;
    00642
    00643     //
    00644     // If any target processors are specified, then send a flush single
    00645     // packet to the target set of processors.
    00646     //
    00647
    00648     if (TargetProcessors != 0) {
    00649         KiIpiSendSynchronousPacket(Prcb,
    00650                                    TargetProcessors,
    00651                                    KiFlushTargetSingleTbSynchronous,
    00652                                    (PVOID)Invalid,
    00653                                    (PVOID)Virtual,
    00654                                    (PVOID)&Prcb->ReverseStall
    00655                                    );
    00656
    00657         IPI_INSTRUMENT_COUNT(Prcb->Number, FlushSingleTb);
    00658
    00659         //
    00660         // Wait for the target processors to stall
    00661         //
    00662
    00663         KiIpiStallOnPacketTargets(TargetProcessors);
    00664
    00665         //
    00666         // Capture the previous contents of the page table entry and set the
    00667         // page table entry to the new value.
    00668         //
    00669
    00670         KI_SWAP_PTE(PtePointer, PteValue, OldPteValue);
    00671
    00672         //
    00673         // Notify all prcessors it's time to go
    00674         //
    00675
    00676         Prcb->ReverseStall += 1;
    00677
    00678     } else {
    00679
    00680         //
    00681         // Capture the previous contents of the page table entry and set the
    00682         // page table entry to the new value.
    00683         //
    00684
    00685         KI_SWAP_PTE(PtePointer, PteValue, OldPteValue);
    00686     }
    00687
    00688     //
    00689     // Flush the specified entry from the TB on the current processor.
    00690     //
    00691
    00692     KiFlushSingleTb(Invalid, Virtual);
    00693
    00694     //
    00695     // Done
    00696     //
    00697
    00698     KiUnlockContextSwap(OldIrql);
    00699     return(OldPteValue);
    00700 }

VOID KiFlushTargetEntireTb | ( | IN PKIPI_CONTEXT | SignalDone,
|  | IN PVOID | Invalid,
|  | IN PVOID | Parameter2,
|  | IN PVOID | Parameter3
| ) |

Definition at line 202 of file i386/flushtb.c.

References KeFlushCurrentTb(), and KiIpiSignalPacketDone().

Referenced by KeFlushEntireTb().

    00211                    :
    00212
    00213     This is the target function for flushing the entire TB.
    00214
    00215 Arguments:
    00216
    00217     SignalDone - Supplies a pointer to a variable that is cleared when the
    00218         requested operation has been performed.
    00219
    00220     Parameter1 - Parameter3 - Not used.
    00221
    00222 Return Value:
    00223
    00224     None.
    00225
    00226 --*/
    00227
    00228 {
    00229
    00230     //
    00231     // Flush the entire TB on the current processor.
    00232     //
    00233
    00234     KiIpiSignalPacketDone(SignalDone);
    00235     KeFlushCurrentTb();
    00236     return;
    00237 }

VOID KiFlushTargetMultipleTb | ( | IN PKIPI_CONTEXT | SignalDone,
|  | IN PVOID | Parameter1,
|  | IN PVOID | Parameter2,
|  | IN PVOID | Parameter3
| ) |

Definition at line 368 of file i386/flushtb.c.

References Index, KiFlushSingleTb(), KiIpiSignalPacketDone(), and Virtual.

Referenced by KeFlushMultipleTb().

    00377                    :
    00378
    00379     This is the target function for flushing multiple TB entries.
    00380
    00381 Arguments:
    00382
    00383     SignalDone - Supplies a pointer to a variable that is cleared when the
    00384         requested operation has been performed.
    00385
    00386     Invalid - Supplies a bollean value that determines whether the virtual
    00387         address is invalid.
    00388
    00389     Number - Supplies the number of TB entries to flush.
    00390
    00391     Virtual - Supplies a pointer to an array of virtual addresses that
    00392         are within the pages whose translation buffer entries are to be
    00393         flushed.
    00394
    00395 Return Value:
    00396
    00397     None.
    00398
    00399 --*/
    00400
    00401 {
    00402
    00403     ULONG Index;
    00404     PVOID VirtualAddress[FLUSH_MULTIPLE_MAXIMUM];
    00405
    00406     //
    00407     // Capture the virtual addresses that are to be flushed from the TB
    00408     // on the current processor and signal pack done.
    00409     //
    00410
    00411     for (Index = 0; Index < (ULONG) Number; Index += 1) {
    00412         VirtualAddress[Index] = ((PVOID *)(Virtual))[Index];
    00413     }
    00414
    00415     KiIpiSignalPacketDone(SignalDone);
    00416
    00417     //
    00418     // Flush the specified virtual address for the TB on the current
    00419     // processor.
    00420     //
    00421
    00422     for (Index = 0; Index < (ULONG) Number; Index += 1) {
    00423         KiFlushSingleTb((BOOLEAN)Invalid, VirtualAddress [Index]);
    00424     }
    00425 }

VOID KiFlushTargetSingleTb | ( | IN PKIPI_CONTEXT | SignalDone,
|  | IN PVOID | Parameter1,
|  | IN PVOID | Parameter2,
|  | IN PVOID | Parameter3
| ) |

Definition at line 546 of file i386/flushtb.c.

References KiFlushSingleTb(), and KiIpiSignalPacketDone().

Referenced by KeFlushSingleTb().

    00555                    :
    00556
    00557     This is the target function for flushing a single TB entry.
    00558
    00559 Arguments:
    00560
    00561     SignalDone Supplies a pointer to a variable that is cleared when the
    00562         requested operation has been performed.
    00563
    00564     Invalid - Supplies a bollean value that determines whether the virtual
    00565         address is invalid.
    00566
    00567     Virtual - Supplies a virtual address that is within the page whose
    00568         translation buffer entry is to be flushed.
    00569
    00570     Parameter3 - Not used.
    00571
    00572 Return Value:
    00573
    00574     None.
    00575
    00576 --*/
    00577
    00578 {
    00579
    00580     //
    00581     // Flush a single entry from the TB on the current processor.
    00582     //
    00583
    00584     KiIpiSignalPacketDone(SignalDone);
    00585     KiFlushSingleTb((BOOLEAN)Invalid, (PVOID)VirtualAddress);
    00586 }

VOID KiFlushTargetSingleTbSynchronous | ( | IN PKIPI_CONTEXT | SignalDone,
|  | IN PVOID | Parameter1,
|  | IN PVOID | Parameter2,
|  | IN PVOID | Parameter3
| ) |

Definition at line 703 of file i386/flushtb.c.

References KiFlushSingleTb().

Referenced by KiFlushSingleTbSynchronous().

    00712                    :
    00713
    00714     This is the target function for flushing a single TB entry synchronously.
    00715
    00716 Arguments:
    00717
    00718     SignalDone Supplies a pointer to a variable that is cleared when the
    00719         requested operation has been performed.
    00720
    00721     Invalid - Supplies a bollean value that determines whether the virtual
    00722         address is invalid.
    00723
    00724     Virtual - Supplies a virtual address that is within the page whose
    00725         translation buffer entry is to be flushed.
    00726
    00727     Parameter3 - Not used.
    00728
    00729 Return Value:
    00730
    00731     None.
    00732
    00733 --*/
    00734
    00735 {
    00736
    00737     //
    00738     // Flush a single entry from the TB on the current processor.
    00739     //
    00740
    00741     KiIpiSignalPacketDoneAndStall(SignalDone, Proceed);
    00742     KiFlushSingleTb((BOOLEAN)Invalid, (PVOID)VirtualAddress);
    00743 }