test: i386/iopm.c File Reference

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

# iopm.c File Reference

`#include "ki.h"`

Go to the source code of this file.

## Defines

#define | ALIGN_DOWN(address, amt) ((ULONG)(address) & ~(( amt ) - 1))
#define | ALIGN_UP(address, amt) (ALIGN_DOWN( (address + (amt) - 1), (amt) ))

## Functions

VOID | KiSetIoMap (IN PKIPI_CONTEXT SignalDone, IN PVOID MapSource, IN PVOID MapNumber, IN PVOID Parameter3)
VOID | KiLoadIopmOffset (IN PKIPI_CONTEXT SignalDone, IN PVOID Parameter1, IN PVOID Parameter2, IN PVOID Parameter3)
BOOLEAN | Ke386SetIoAccessMap (ULONG MapNumber, PKIO_ACCESS_MAP IoAccessMap)
BOOLEAN | Ke386QueryIoAccessMap (ULONG MapNumber, PKIO_ACCESS_MAP IoAccessMap)
BOOLEAN | Ke386IoSetAccessProcess (PKPROCESS Process, ULONG MapNumber)
VOID | Ke386SetIOPL (IN PKPROCESS Process)

## Define Documentation

#define ALIGN_DOWN | ( | address,
|  | amt |  | ) | ((ULONG)(address) & ~(( amt ) - 1))

| Definition at line 36 of file i386/iopm.c.

#define ALIGN_UP | ( | address,
|  | amt |  | ) | (ALIGN_DOWN( (address + (amt) - 1), (amt) ))

| Definition at line 37 of file i386/iopm.c.

## Function Documentation

BOOLEAN Ke386IoSetAccessProcess | ( | PKPROCESS | Process,
|  | ULONG | MapNumber
| ) |

Definition at line 318 of file i386/iopm.c.

References _KPROCESS::ActiveProcessors, FALSE, KeGetCurrentPrcb, KiIpiSendPacket(), KiIpiStallOnPacketTargets(), KiLoadIopmOffset(), KiLockContextSwap, KiPcr, KiUnlockContextSwap, NULL, TRUE, and USHORT.

    00324                    :
    00325
    00326     Set the i/o access map which controls user mode i/o access
    00327     for a particular process.
    00328
    00329 Arguments:
    00330
    00331     Process - Pointer to kernel process object describing the
    00332     process which for which a map is to be set.
    00333
    00334     MapNumber - Number of the map to set.  Value of map is
    00335     defined by Ke386IoSetAccessProcess.  Setting MapNumber
    00336     to IO_ACCESS_MAP_NONE will disallow any user mode i/o
    00337     access from the process.
    00338
    00339 Return Value:
    00340
    00341     TRUE if success, FALSE if failure (illegal MapNumber)
    00342
    00343 --*/
    00344
    00345 {
    00346
    00347     USHORT MapOffset;
    00348     KIRQL OldIrql;
    00349     PKPRCB Prcb;
    00350     KAFFINITY TargetProcessors;
    00351
    00352     //
    00353     // Reject illegal requests
    00354     //
    00355
    00356     if (MapNumber > IOPM_COUNT) {
    00357         return FALSE;
    00358     }
    00359
    00360     MapOffset = KiComputeIopmOffset(MapNumber);
    00361
    00362     //
    00363     // Acquire the context swap lock so a context switch will not occur.
    00364     //
    00365
    00366     KiLockContextSwap(&OldIrql);
    00367
    00368     //
    00369     // Store new offset in process object,  compute current set of
    00370     // active processors for process, if this cpu is one, set IOPM.
    00371     //
    00372
    00373     Process->IopmOffset = MapOffset;
    00374
    00375     TargetProcessors = Process->ActiveProcessors;
    00376     Prcb = KeGetCurrentPrcb();
    00377     if (TargetProcessors & Prcb->SetMember) {
    00378         KiPcr()->TSS->IoMapBase = MapOffset;
    00379     }
    00380
    00381     //
    00382     // Compute set of active processors other than this one, if non-empty
    00383     // IPI them to load their IOPMs, wait for them.
    00384     //
    00385
    00386 #if !defined(NT_UP)
    00387
    00388     TargetProcessors = TargetProcessors & ~Prcb->SetMember;
    00389     if (TargetProcessors != 0) {
    00390         KiIpiSendPacket(TargetProcessors,
    00391                         KiLoadIopmOffset,
    00392                         NULL,
    00393                         NULL,
    00394                         NULL);
    00395
    00396         KiIpiStallOnPacketTargets(TargetProcessors);
    00397     }
    00398
    00399 #endif
    00400
    00401     //
    00402     // Restore IRQL and unlock the context swap lock.
    00403     //
    00404
    00405     KiUnlockContextSwap(OldIrql);
    00406     return TRUE;
    00407 }

BOOLEAN Ke386QueryIoAccessMap | ( | ULONG | MapNumber,
|  | PKIO_ACCESS_MAP | IoAccessMap
| ) |

Definition at line 235 of file i386/iopm.c.

References FALSE, KiLockContextSwap, KiPcr, KiUnlockContextSwap, and TRUE.

    00242                    :
    00243
    00244     The specified i/o access map will be dumped into the buffer.
    00245     map 0 is a constant, but will be dumped anyway.
    00246
    00247 Arguments:
    00248
    00249     MapNumber - Number of access map to set.  map 0 is fixed.
    00250
    00251     IoAccessMap - Pointer to buffer (64K bits, 8K bytes) which
    00252            is to receive the definition of the access map.
    00253            Must be in non-paged pool.
    00254
    00255 Return Value:
    00256
    00257     TRUE if successful.  FALSE if failure (attempt to query a map
    00258     which does not exist)
    00259
    00260 --*/
    00261
    00262 {
    00263
    00264     ULONG i;
    00265     PVOID Map;
    00266     KIRQL OldIrql;
    00267     PUCHAR p;
    00268
    00269     //
    00270     // Reject illegal requests
    00271     //
    00272
    00273     if (MapNumber > IOPM_COUNT) {
    00274         return FALSE;
    00275     }
    00276
    00277     //
    00278     // Acquire the context swap lock so a context switch will not occur.
    00279     //
    00280
    00281     KiLockContextSwap(&OldIrql);
    00282
    00283     //
    00284     // Copy out the map
    00285     //
    00286
    00287     if (MapNumber == IO_ACCESS_MAP_NONE) {
    00288
    00289         //
    00290         // no access case, simply return a map of all 1s
    00291         //
    00292
    00293         p = (PUCHAR)IoAccessMap;
    00294         for (i = 0; i < IOPM_SIZE; i++) {
    00295             p[i] = (UCHAR)-1;
    00296         }
    00297
    00298     } else {
    00299
    00300         //
    00301         // normal case, just copy the bits
    00302         //
    00303
    00304         Map = (PVOID)&(KiPcr()->TSS->IoMaps[MapNumber-1].IoMap);
    00305         RtlMoveMemory((PVOID)IoAccessMap, Map, IOPM_SIZE);
    00306     }
    00307
    00308     //
    00309     // Restore IRQL and unlock the context swap lock.
    00310     //
    00311
    00312     KiUnlockContextSwap(OldIrql);
    00313     return TRUE;
    00314 }

BOOLEAN Ke386SetIoAccessMap | ( | ULONG | MapNumber,
|  | PKIO_ACCESS_MAP | IoAccessMap
| ) |

Definition at line 80 of file i386/iopm.c.

References FALSE, KeActiveProcessors, KeGetCurrentPrcb, KiIpiSendPacket(), KiIpiStallOnPacketTargets(), KiLockContextSwap, KiPcr, KiSetIoMap(), KiUnlockContextSwap, NULL, and TRUE.

    00087                    :
    00088
    00089     The specified i/o access map will be set to match the
    00090     definition specified by IoAccessMap (i.e. enable/disable
    00091     those ports) before the call returns.  The change will take
    00092     effect on all processors.
    00093
    00094     Ke386SetIoAccessMap does not give any process enhanced I/O
    00095     access, it merely defines a particular access map.
    00096
    00097 Arguments:
    00098
    00099     MapNumber - Number of access map to set.  Map 0 is fixed.
    00100
    00101     IoAccessMap - Pointer to bitvector (64K bits, 8K bytes) which
    00102            defines the specified access map.  Must be in
    00103            non-paged pool.
    00104
    00105 Return Value:
    00106
    00107     TRUE if successful.  FALSE if failure (attempt to set a map
    00108     which does not exist, attempt to set map 0)
    00109
    00110 --*/
    00111
    00112 {
    00113
    00114     PKPROCESS CurrentProcess;
    00115     KIRQL OldIrql;
    00116     PKPRCB Prcb;
    00117     PVOID pt;
    00118     KAFFINITY TargetProcessors;
    00119
    00120     //
    00121     // Reject illegal requests
    00122     //
    00123
    00124     if ((MapNumber > IOPM_COUNT) || (MapNumber == IO_ACCESS_MAP_NONE)) {
    00125         return FALSE;
    00126     }
    00127
    00128     //
    00129     // Acquire the context swap lock so a context switch will not occur.
    00130     //
    00131
    00132     KiLockContextSwap(&OldIrql);
    00133
    00134     //
    00135     // Compute set of active processors other than this one, if non-empty
    00136     // IPI them to set their maps.
    00137     //
    00138
    00139     Prcb = KeGetCurrentPrcb();
    00140
    00141 #if !defined(NT_UP)
    00142
    00143     TargetProcessors = KeActiveProcessors & ~Prcb->SetMember;
    00144     if (TargetProcessors != 0) {
    00145         KiIpiSendPacket(TargetProcessors,
    00146                         KiSetIoMap,
    00147                         IoAccessMap,
    00148                         (PVOID)MapNumber,
    00149                         NULL);
    00150     }
    00151
    00152 #endif
    00153
    00154     //
    00155     // Copy the IOPM map and load the map for the current process.
    00156     //
    00157
    00158     pt = &(KiPcr()->TSS->IoMaps[MapNumber-1].IoMap);
    00159     RtlMoveMemory(pt, (PVOID)IoAccessMap, IOPM_SIZE);
    00160     CurrentProcess = Prcb->CurrentThread->ApcState.Process;
    00161     KiPcr()->TSS->IoMapBase = CurrentProcess->IopmOffset;
    00162
    00163     //
    00164     // Wait until all of the target processors have finished copying the
    00165     // new map.
    00166     //
    00167
    00168 #if !defined(NT_UP)
    00169
    00170     if (TargetProcessors != 0) {
    00171         KiIpiStallOnPacketTargets(TargetProcessors);
    00172     }
    00173
    00174 #endif
    00175
    00176     //
    00177     // Restore IRQL and unlock the context swap lock.
    00178     //
    00179
    00180     KiUnlockContextSwap(OldIrql);
    00181     return TRUE;
    00182 }

VOID Ke386SetIOPL | ( | IN PKPROCESS | Process | ) |

Definition at line 457 of file i386/iopm.c.

References ALIGN_UP, _KTHREAD::ApcState, CONTEXT_CONTROL, _KTHREAD::InitialStack, _KTHREAD::Iopl, KeContextFromKframes(), KeContextToKframes(), KeGetCurrentThread, NULL, _KAPC_STATE::Process, and UserMode.

Referenced by NtSetInformationProcess().

    00463                    :
    00464
    00465     Gives IOPL to the specified process.
    00466
    00467     All threads created from this point on will get IOPL.  The current
    00468     process will get IOPL.  Must be called from context of thread and
    00469     process that are to have IOPL.
    00470
    00471     Iopl (to be made a boolean) in KPROCESS says all
    00472     new threads to get IOPL.
    00473
    00474     Iopl (to be made a boolean) in KTHREAD says given
    00475     thread to get IOPL.
    00476
    00477     N.B.    If a kernel mode only thread calls this procedure, the
    00478             result is (a) poinless and (b) will break the system.
    00479
    00480 Arguments:
    00481
    00482     Process - Pointer to the process == IGNORED!!!
    00483
    00484 Return Value:
    00485
    00486     none
    00487
    00488 --*/
    00489
    00490 {
    00491
    00492     PKTHREAD    Thread;
    00493     PKPROCESS   Process2;
    00494     PKTRAP_FRAME    TrapFrame;
    00495     CONTEXT     Context;
    00496
    00497     //
    00498     // get current thread and Process2, set flag for IOPL in both of them
    00499     //
    00500
    00501     Thread = KeGetCurrentThread();
    00502     Process2 = Thread->ApcState.Process;
    00503
    00504     Process2->Iopl = 1;
    00505     Thread->Iopl = 1;
    00506
    00507     //
    00508     // Force IOPL to be on for current thread
    00509     //
    00510
    00511     TrapFrame = (PKTRAP_FRAME)((PUCHAR)Thread->InitialStack -
    00512                 ALIGN_UP(sizeof(KTRAP_FRAME),KTRAP_FRAME_ALIGN) -
    00513                 sizeof(FX_SAVE_AREA));
    00514
    00515     Context.ContextFlags = CONTEXT_CONTROL;
    00516     KeContextFromKframes(TrapFrame,
    00517                          NULL,
    00518                          &Context);
    00519
    00520     Context.EFlags |= (EFLAGS_IOPL_MASK & -1);  // IOPL == 3
    00521
    00522     KeContextToKframes(TrapFrame,
    00523                        NULL,
    00524                        &Context,
    00525                        CONTEXT_CONTROL,
    00526                        UserMode);
    00527
    00528     return;
    00529 }
    }

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

Definition at line 413 of file i386/iopm.c.

References KeGetCurrentPrcb, KiIpiSignalPacketDone(), and KiPcr.

Referenced by Ke386IoSetAccessProcess().

    00422                    :
    00423
    00424     Edit IopmBase of Tss to match that of currently running process.
    00425
    00426 Arguments:
    00427
    00428     Argument - actually a pointer to a KIPI_LOAD_IOPM_OFFSET structure
    00429     ReadyFlag - Pointer to flag to be set once we are done
    00430
    00431 Return Value:
    00432
    00433     none
    00434
    00435 --*/
    00436
    00437 {
    00438
    00439     PKPROCESS CurrentProcess;
    00440     PKPRCB Prcb;
    00441
    00442     //
    00443     // Update IOPM field in TSS from current process
    00444     //
    00445
    00446     Prcb = KeGetCurrentPrcb();
    00447     CurrentProcess = Prcb->CurrentThread->ApcState.Process;
    00448     KiPcr()->TSS->IoMapBase = CurrentProcess->IopmOffset;
    00449     KiIpiSignalPacketDone(SignalDone);
    00450     return;
    00451 }

VOID KiSetIoMap | ( | IN PKIPI_CONTEXT | SignalDone,
|  | IN PVOID | MapSource,
|  | IN PVOID | MapNumber,
|  | IN PVOID | Parameter3
| ) |

Definition at line 188 of file i386/iopm.c.

References KeGetCurrentPrcb, KiIpiSignalPacketDone(), and KiPcr.

Referenced by Ke386SetIoAccessMap().

    00196                    :
    00197
    00198     copy the specified map into this processor's TSS.
    00199     This procedure runs at IPI level.
    00200
    00201 Arguments:
    00202
    00203     Argument - actually a pointer to a KIPI_SET_IOPM structure
    00204     ReadyFlag - pointer to flag to set once setiopm has completed
    00205
    00206 Return Value:
    00207
    00208     none
    00209
    00210 --*/
    00211
    00212 {
    00213
    00214     PKPROCESS CurrentProcess;
    00215     PKPRCB Prcb;
    00216     PVOID pt;
    00217
    00218     //
    00219     // Copy the IOPM map and load the map for the current process.
    00220     //
    00221
    00222     Prcb = KeGetCurrentPrcb();
    00223     pt = &(KiPcr()->TSS->IoMaps[((ULONG) MapNumber)-1].IoMap);
    00224     RtlMoveMemory(pt, MapSource, IOPM_SIZE);
    00225     CurrentProcess = Prcb->CurrentThread->ApcState.Process;
    00226     KiPcr()->TSS->IoMapBase = CurrentProcess->IopmOffset;
    00227     KiIpiSignalPacketDone(SignalDone);
    00228     return;
    00229 }