|
|
/*++
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
|