353 lines
6 KiB
C
353 lines
6 KiB
C
|
/*++
|
||
|
|
||
|
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
|