windows-nt/Source/XPSP1/NT/base/ntos/ke/amd64/iopm.c

353 lines
6 KiB
C
Raw Permalink Normal View History

2020-09-26 03:20:57 -05:00
/*++
Copyright (c) 2000 Microsoft Corporation
Module Name:
iopm.c
Abstract:
This module implements interfaces that support manipulation of I/O
Permission Maps (IOPMs).
Author:
David N. Cutler (davec) 4-May-2000
Environment:
Kernel mode only.
Revision History:
--*/
#include "ki.h"
//
// Define forward referenced function prototypes.
//
VOID
KiSetIoAccessMap (
IN PKIPI_CONTEXT SignalDone,
IN PVOID MapSource,
IN PVOID Parameter2,
IN PVOID Parameter3
);
VOID
KiSetIoAccessProcess (
IN PKIPI_CONTEXT SignalDone,
IN PVOID MapOffset,
IN PVOID Parameter2,
IN PVOID Parameter3
);
VOID
KeQueryIoAccessMap (
PKIO_ACCESS_MAP IoAccessMap
)
/*++
Routine Description:
This function queries the current I/O Permissions Map and copies it
to the specified buffer.
Arguments:
IoAccessMap - Supplies a pointer to an I/O Permissions Map that will
receive the current I/O Permissions Map.
Return Value:
None.
--*/
{
KIRQL OldIrql;
//
// Raise IRQL and acquire the context swap lock..
//
KiLockContextSwap(&OldIrql);
//
// Copy the current I/O Permissions Map to the specified buffer.
//
RtlCopyMemory(IoAccessMap, &KeGetPcr()->TssBase->IoMap[0], IOPM_SIZE);
//
// Release the context swap lock and lower IRQL.
//
KiUnlockContextSwap(OldIrql);
return;
}
VOID
KeSetIoAccessMap (
PKIO_ACCESS_MAP IoAccessMap
)
/*++
Routine Description:
This funtion copies the specified I/O Permission Map to the current
I/O Permissions Map on all processors in the host configuration.
Arguments:
IoAccessMap - Supplies a pointer to the new I/O Permissions Map.
Return Value:
None.
--*/
{
KIRQL OldIrql;
PKPRCB Prcb;
KAFFINITY TargetProcessors;
//
// Raise IRQL and acquire the context swap lock.
//
KiLockContextSwap(&OldIrql);
//
// Compute the target set of processors and send a message to copy
// the new I/O Permissions Map.
//
#if !defined(NT_UP)
Prcb = KeGetCurrentPrcb();
TargetProcessors = KeActiveProcessors & Prcb->NotSetMember;
if (TargetProcessors != 0) {
KiIpiSendPacket(TargetProcessors,
KiSetIoAccessMap,
IoAccessMap,
NULL,
NULL);
}
#endif
//
// Copy the I/O Permissions Map into the current map.
//
RtlCopyMemory(&KeGetPcr()->TssBase->IoMap[0], IoAccessMap, IOPM_SIZE);
//
// Wait until all of the target processors have finished copying the
// new map.
//
#if !defined(NT_UP)
if (TargetProcessors != 0) {
KiIpiStallOnPacketTargets(TargetProcessors);
}
#endif
//
// Release the context swap lock and lower IRQL.
//
KiUnlockContextSwap(OldIrql);
return;
}
#if !defined(NT_UP)
VOID
KiSetIoAccessMap (
IN PKIPI_CONTEXT SignalDone,
IN PVOID MapSource,
IN PVOID Parameter2,
IN PVOID Parameter3
)
/*++
Routine Description:
This is the target function for copying the new I/O Permissions Map.
Arguments:
MapSource - Supplies a pointer to the new I/O Permission Map.
Parameter2 - Parameter3 - Not used.
Return Value:
None.
--*/
{
//
// Copy the specified I/O Permissions map into the current map.
//
RtlCopyMemory(&KeGetPcr()->TssBase->IoMap[0], MapSource, IOPM_SIZE);
KiIpiSignalPacketDone(SignalDone);
return;
}
#endif
VOID
KeSetIoAccessProcess (
PKPROCESS Process,
BOOLEAN Enable
)
/*++
Routine Description:
This function enables or disables use of the I/O Permissions Map by
the specified process.
Arguments:
Process - Supplies a pointer to a process object.
Enable - Supplies a value that determines whether the current I/O
Permissions Map is enabled (TRUE) or disabled (FALSE) for the
specified process.
Return Value:
None.
--*/
{
USHORT MapOffset;
KIRQL OldIrql;
PKPRCB Prcb;
KAFFINITY TargetProcessors;
//
// Raise IRQL and acquire the context swap lock.
//
KiLockContextSwap(&OldIrql);
//
// Compute the new I/O Permissions Map offset and set the new offset for
// the specified process.
//
MapOffset = KiComputeIopmOffset(Enable);
Process->IopmOffset = MapOffset;
//
// Compute the target set of processors and send a message specifing a
// new I/O Permsissions Map offset.
//
Prcb = KeGetCurrentPrcb();
#if !defined(NT_UP)
TargetProcessors = Process->ActiveProcessors & Prcb->NotSetMember;
if (TargetProcessors != 0) {
KiIpiSendPacket(TargetProcessors,
KiSetIoAccessProcess,
(PVOID)((ULONG64)MapOffset),
NULL,
NULL);
}
#endif
//
// If the specified process has a child thread that is running on the
// current processor, then set the new I/O Permissions Map offset.
//
if (Process->ActiveProcessors & Prcb->SetMember) {
KeGetPcr()->TssBase->IoMapBase = MapOffset;
}
//
// Wait until all of the target processors have finished setting the new
// map offset.
//
#if !defined(NT_UP)
KiIpiStallOnPacketTargets(TargetProcessors);
#endif
//
// Release the context swap lock and lower IRQL.
//
KiUnlockContextSwap(OldIrql);
return;
}
#if !defined(NT_UP)
VOID
KiSetIoAccessProcess (
IN PKIPI_CONTEXT SignalDone,
IN PVOID MapOffset,
IN PVOID Parameter2,
IN PVOID Parameter3
)
/*++
Routine Description:
This is the target function to set the I/O Permissions Map offset.
Arguments:
MapOffset - Supplies the new I/O Permissions Map offset.
Parameter2 - Parameter3 - Not Used.
Return Value:
None.
--*/
{
//
// Update IOPM field in TSS from current process
//
KeGetPcr()->TssBase->IoMapBase = (USHORT)((ULONG64)MapOffset);
KiIpiSignalPacketDone(SignalDone);
return;
}
#endif