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

/*++
Copyright (c) 1989 Microsoft Corporation
Copyright (c) 1990 Microsoft Corporation
Module Name:
tbflush.c
Abstract:
This module implements machine dependent functions to flush
the translation buffers in an Intel x86 system.
N.B. This module contains only MP versions of the TB flush routines.
The UP versions are macros in ke.h
KeFlushEntireTb remains a routine for the UP system since it is
exported from the kernel for backwards compatibility.
Author:
David N. Cutler (davec) 13-May-1989
Environment:
Kernel mode only.
--*/
#include "ki.h"
VOID
KiFlushTargetEntireTb (
IN PKIPI_CONTEXT SignalDone,
IN PVOID Parameter1,
IN PVOID Parameter2,
IN PVOID Parameter3
);
VOID
KiFlushTargetProcessTb (
IN PKIPI_CONTEXT SignalDone,
IN PVOID Parameter1,
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
);
VOID
KeFlushEntireTb (
IN BOOLEAN Invalid,
IN BOOLEAN AllProcessors
)
/*++
Routine Description:
This function flushes the entire translation buffer on all processors.
Arguments:
Invalid - Not used.
AllProcessors - Not used.
Return Value:
None.
--*/
{
KIRQL OldIrql;
#if !defined(NT_UP)
PKPRCB Prcb;
KAFFINITY TargetProcessors;
#endif
UNREFERENCED_PARAMETER(Invalid);
UNREFERENCED_PARAMETER(AllProcessors);
//
// Compute the target set of processors and send the flush entire
// parameters to the target processors, if any, for execution.
//
OldIrql = KeRaiseIrqlToSynchLevel();
KiSetTbFlushTimeStampBusy();
#if !defined(NT_UP)
Prcb = KeGetCurrentPrcb();
TargetProcessors = KeActiveProcessors & ~Prcb->SetMember;
//
// Send packet to target processors.
//
if (TargetProcessors != 0) {
KiIpiSendPacket(TargetProcessors,
KiFlushTargetEntireTb,
NULL,
NULL,
NULL);
IPI_INSTRUMENT_COUNT (Prcb->Number, FlushEntireTb);
}
#endif
//
// Flush TB on current processor.
//
KeFlushCurrentTb();
//
// Wait until all target processors have finished and complete packet.
//
#if !defined(NT_UP)
if (TargetProcessors != 0) {
KiIpiStallOnPacketTargets(TargetProcessors);
}
#endif
//
// Clear the TB time stamp busy.
//
KiClearTbFlushTimeStampBusy();
//
// Lower IRQL to previous level.
//
KeLowerIrql(OldIrql);
return;
}
#if !defined(NT_UP)
VOID
KiFlushTargetEntireTb (
IN PKIPI_CONTEXT SignalDone,
IN PVOID Parameter1,
IN PVOID Parameter2,
IN PVOID Parameter3
)
/*++
Routine Description:
This is the target function for flushing the entire TB.
Arguments:
SignalDone - Supplies a pointer to a variable that is cleared when the
requested operation has been performed.
Parameter1 - Parameter3 - Not used.
Return Value:
None.
--*/
{
UNREFERENCED_PARAMETER(Parameter1);
UNREFERENCED_PARAMETER(Parameter2);
UNREFERENCED_PARAMETER(Parameter3);
//
// Flush the entire TB on the current processor.
//
KiIpiSignalPacketDone(SignalDone);
KeFlushCurrentTb();
return;
}
VOID
KeFlushProcessTb (
IN BOOLEAN AllProcessors
)
/*++
Routine Description:
This function flushes the non-global translation buffer on all processors
that are currently running threads which are child of the current process
or flushes the non-global translation buffer on all processors in the host
configuration.
Arguments:
AllProcessors - Supplies a boolean value that determines which translation
buffers are to be flushed.
Return Value:
None.
--*/
{
KIRQL OldIrql;
PKPRCB Prcb;
PKPROCESS Process;
KAFFINITY TargetProcessors;
//
// Compute the target set of processors, disable context switching,
// and send the flush entire parameters to the target processors,
// if any, for execution.
//
OldIrql = KeRaiseIrqlToSynchLevel();
Prcb = KeGetCurrentPrcb();
if (AllProcessors != FALSE) {
TargetProcessors = KeActiveProcessors;
} else {
Process = Prcb->CurrentThread->ApcState.Process;
TargetProcessors = Process->ActiveProcessors;
}
TargetProcessors &= ~Prcb->SetMember;
//
// Send packet to target processors.
//
if (TargetProcessors != 0) {
KiIpiSendPacket(TargetProcessors,
KiFlushTargetProcessTb,
NULL,
NULL,
NULL);
IPI_INSTRUMENT_COUNT (Prcb->Number, FlushEntireTb);
}
//
// Flush TB on current processor.
//
KiFlushProcessTb();
//
// Wait until all target processors have finished and complete packet.
//
if (TargetProcessors != 0) {
KiIpiStallOnPacketTargets(TargetProcessors);
}
//
// Lower IRQL and unlock as appropriate.
//
KeLowerIrql(OldIrql);
return;
}
VOID
KiFlushTargetProcessTb (
IN PKIPI_CONTEXT SignalDone,
IN PVOID Parameter1,
IN PVOID Parameter2,
IN PVOID Parameter3
)
/*++
Routine Description:
This is the target function for flushing the non-global TB.
Arguments:
SignalDone - Supplies a pointer to a variable that is cleared when the
requested operation has been performed.
Parameter1 - Parameter3 - Not used.
Return Value:
None.
--*/
{
UNREFERENCED_PARAMETER(Parameter1);
UNREFERENCED_PARAMETER(Parameter2);
UNREFERENCED_PARAMETER(Parameter3);
//
// Flush the non-global TB on the current processor.
//
KiIpiSignalPacketDone(SignalDone);
KiFlushProcessTb();
return;
}
VOID
KeFlushMultipleTb (
IN ULONG Number,
IN PVOID *Virtual,
IN BOOLEAN AllProcessors
)
/*++
Routine Description:
This function flushes multiple entries from the translation buffer
on all processors that are currently running threads which are
children of the current process or flushes a multiple entries from
the translation buffer on all processors in the host configuration.
Arguments:
Number - Supplies the number of TB entries to flush.
Virtual - Supplies a pointer to an array of virtual addresses that
are within the pages whose translation buffer entries are to be
flushed.
AllProcessors - Supplies a boolean value that determines which
translation buffers are to be flushed.
Return Value:
The previous contents of the specified page table entry is returned
as the function value.
--*/
{
PVOID *End;
KIRQL OldIrql;
PKPRCB Prcb;
PKPROCESS Process;
KAFFINITY TargetProcessors;
ASSERT(Number != 0);
End = Virtual + Number;
//
// Compute target set of processors.
//
OldIrql = KeRaiseIrqlToSynchLevel();
Prcb = KeGetCurrentPrcb();
if (AllProcessors != FALSE) {
TargetProcessors = KeActiveProcessors;
} else {
Process = Prcb->CurrentThread->ApcState.Process;
TargetProcessors = Process->ActiveProcessors;
}
TargetProcessors &= ~Prcb->SetMember;
//
// If any target processors are specified, then send a flush multiple
// packet to the target set of processors.
//
if (TargetProcessors != 0) {
KiIpiSendPacket(TargetProcessors,
KiFlushTargetMultipleTb,
NULL,
(PVOID)End,
(PVOID)Virtual);
IPI_INSTRUMENT_COUNT (Prcb->Number, FlushMultipleTb);
}
//
// Flush the specified entries from the TB on the current processor.
//
do {
KiFlushSingleTb(*Virtual);
Virtual += 1;
} while (Virtual < End);
//
// Wait until all target processors have finished and complete packet.
//
if (TargetProcessors != 0) {
KiIpiStallOnPacketTargets(TargetProcessors);
}
//
// Lower IRQL to its previous level.
//
KeLowerIrql(OldIrql);
return;
}
VOID
KiFlushTargetMultipleTb (
IN PKIPI_CONTEXT SignalDone,
IN PVOID Parameter1,
IN PVOID End,
IN PVOID Virtual
)
/*++
Routine Description:
This is the target function for flushing multiple TB entries.
Arguments:
SignalDone - Supplies a pointer to a variable that is cleared when the
requested operation has been performed.
Parameter1 - Not used.
End - Supplies the a pointer to the ending address of the virtual
address array.
Virtual - Supplies a pointer to an array of virtual addresses that
are within the pages whose translation buffer entries are to be
flushed.
Return Value:
None.
--*/
{
PVOID *xEnd;
PVOID *xVirtual;
UNREFERENCED_PARAMETER(Parameter1);
//
// Flush the specified entries from the TB on the current processor and
// signal pack done.
//
xEnd = (PVOID *)End;
xVirtual = (PVOID *)Virtual;
do {
KiFlushSingleTb(*xVirtual);
xVirtual += 1;
} while (xVirtual < xEnd);
KiIpiSignalPacketDone(SignalDone);
return;
}
VOID
FASTCALL
KeFlushSingleTb (
IN PVOID Virtual,
IN BOOLEAN AllProcessors
)
/*++
Routine Description:
This function flushes a single entry from translation buffer (TB) on all
processors that are currently running threads which are child of the current
process or flushes the entire translation buffer on all processors in the
host configuration.
Arguments:
Virtual - Supplies a virtual address that is within the page whose
translation buffer entry is to be flushed.
AllProcessors - Supplies a boolean value that determines which translation
buffers are to be flushed.
Return Value:
Returns the contents of the PtePointer before the new value
is stored.
--*/
{
KIRQL OldIrql;
PKPRCB Prcb;
PKPROCESS Process;
KAFFINITY TargetProcessors;
//
// Compute target set of processors.
//
OldIrql = KeRaiseIrqlToSynchLevel();
Prcb = KeGetCurrentPrcb();
if (AllProcessors != FALSE) {
TargetProcessors = KeActiveProcessors;
} else {
Process = Prcb->CurrentThread->ApcState.Process;
TargetProcessors = Process->ActiveProcessors;
}
TargetProcessors &= ~Prcb->SetMember;
//
// If any target processors are specified, then send a flush single
// packet to the target set of processors.
//
if (TargetProcessors != 0) {
KiIpiSendPacket(TargetProcessors,
KiFlushTargetSingleTb,
NULL,
(PVOID)Virtual,
NULL);
IPI_INSTRUMENT_COUNT(Prcb->Number, FlushSingleTb);
}
//
// Flush the specified entry from the TB on the current processor.
//
KiFlushSingleTb(Virtual);
//
// Wait until all target processors have finished and complete packet.
//
if (TargetProcessors != 0) {
KiIpiStallOnPacketTargets(TargetProcessors);
}
//
// Lower IRQL to its previous level.
//
KeLowerIrql(OldIrql);
return;
}
VOID
KiFlushTargetSingleTb (
IN PKIPI_CONTEXT SignalDone,
IN PVOID Parameter1,
IN PVOID VirtualAddress,
IN PVOID Parameter3
)
/*++
Routine Description:
This is the target function for flushing a single TB entry.
Arguments:
SignalDone Supplies a pointer to a variable that is cleared when the
requested operation has been performed.
Parameter1 - Not used.
Virtual - Supplies a virtual address that is within the page whose
translation buffer entry is to be flushed.
Parameter3 - Not used.
Return Value:
None.
--*/
{
UNREFERENCED_PARAMETER(Parameter1);
UNREFERENCED_PARAMETER(Parameter3);
//
// Flush a single entry from the TB on the current processor.
//
KiIpiSignalPacketDone(SignalDone);
KiFlushSingleTb(VirtualAddress);
}
#endif