Source code of Windows XP (NT5)
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.

352 lines
6.0 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. iopm.c
  5. Abstract:
  6. This module implements interfaces that support manipulation of I/O
  7. Permission Maps (IOPMs).
  8. Author:
  9. David N. Cutler (davec) 4-May-2000
  10. Environment:
  11. Kernel mode only.
  12. Revision History:
  13. --*/
  14. #include "ki.h"
  15. //
  16. // Define forward referenced function prototypes.
  17. //
  18. VOID
  19. KiSetIoAccessMap (
  20. IN PKIPI_CONTEXT SignalDone,
  21. IN PVOID MapSource,
  22. IN PVOID Parameter2,
  23. IN PVOID Parameter3
  24. );
  25. VOID
  26. KiSetIoAccessProcess (
  27. IN PKIPI_CONTEXT SignalDone,
  28. IN PVOID MapOffset,
  29. IN PVOID Parameter2,
  30. IN PVOID Parameter3
  31. );
  32. VOID
  33. KeQueryIoAccessMap (
  34. PKIO_ACCESS_MAP IoAccessMap
  35. )
  36. /*++
  37. Routine Description:
  38. This function queries the current I/O Permissions Map and copies it
  39. to the specified buffer.
  40. Arguments:
  41. IoAccessMap - Supplies a pointer to an I/O Permissions Map that will
  42. receive the current I/O Permissions Map.
  43. Return Value:
  44. None.
  45. --*/
  46. {
  47. KIRQL OldIrql;
  48. //
  49. // Raise IRQL and acquire the context swap lock..
  50. //
  51. KiLockContextSwap(&OldIrql);
  52. //
  53. // Copy the current I/O Permissions Map to the specified buffer.
  54. //
  55. RtlCopyMemory(IoAccessMap, &KeGetPcr()->TssBase->IoMap[0], IOPM_SIZE);
  56. //
  57. // Release the context swap lock and lower IRQL.
  58. //
  59. KiUnlockContextSwap(OldIrql);
  60. return;
  61. }
  62. VOID
  63. KeSetIoAccessMap (
  64. PKIO_ACCESS_MAP IoAccessMap
  65. )
  66. /*++
  67. Routine Description:
  68. This funtion copies the specified I/O Permission Map to the current
  69. I/O Permissions Map on all processors in the host configuration.
  70. Arguments:
  71. IoAccessMap - Supplies a pointer to the new I/O Permissions Map.
  72. Return Value:
  73. None.
  74. --*/
  75. {
  76. KIRQL OldIrql;
  77. PKPRCB Prcb;
  78. KAFFINITY TargetProcessors;
  79. //
  80. // Raise IRQL and acquire the context swap lock.
  81. //
  82. KiLockContextSwap(&OldIrql);
  83. //
  84. // Compute the target set of processors and send a message to copy
  85. // the new I/O Permissions Map.
  86. //
  87. #if !defined(NT_UP)
  88. Prcb = KeGetCurrentPrcb();
  89. TargetProcessors = KeActiveProcessors & Prcb->NotSetMember;
  90. if (TargetProcessors != 0) {
  91. KiIpiSendPacket(TargetProcessors,
  92. KiSetIoAccessMap,
  93. IoAccessMap,
  94. NULL,
  95. NULL);
  96. }
  97. #endif
  98. //
  99. // Copy the I/O Permissions Map into the current map.
  100. //
  101. RtlCopyMemory(&KeGetPcr()->TssBase->IoMap[0], IoAccessMap, IOPM_SIZE);
  102. //
  103. // Wait until all of the target processors have finished copying the
  104. // new map.
  105. //
  106. #if !defined(NT_UP)
  107. if (TargetProcessors != 0) {
  108. KiIpiStallOnPacketTargets(TargetProcessors);
  109. }
  110. #endif
  111. //
  112. // Release the context swap lock and lower IRQL.
  113. //
  114. KiUnlockContextSwap(OldIrql);
  115. return;
  116. }
  117. #if !defined(NT_UP)
  118. VOID
  119. KiSetIoAccessMap (
  120. IN PKIPI_CONTEXT SignalDone,
  121. IN PVOID MapSource,
  122. IN PVOID Parameter2,
  123. IN PVOID Parameter3
  124. )
  125. /*++
  126. Routine Description:
  127. This is the target function for copying the new I/O Permissions Map.
  128. Arguments:
  129. MapSource - Supplies a pointer to the new I/O Permission Map.
  130. Parameter2 - Parameter3 - Not used.
  131. Return Value:
  132. None.
  133. --*/
  134. {
  135. //
  136. // Copy the specified I/O Permissions map into the current map.
  137. //
  138. RtlCopyMemory(&KeGetPcr()->TssBase->IoMap[0], MapSource, IOPM_SIZE);
  139. KiIpiSignalPacketDone(SignalDone);
  140. return;
  141. }
  142. #endif
  143. VOID
  144. KeSetIoAccessProcess (
  145. PKPROCESS Process,
  146. BOOLEAN Enable
  147. )
  148. /*++
  149. Routine Description:
  150. This function enables or disables use of the I/O Permissions Map by
  151. the specified process.
  152. Arguments:
  153. Process - Supplies a pointer to a process object.
  154. Enable - Supplies a value that determines whether the current I/O
  155. Permissions Map is enabled (TRUE) or disabled (FALSE) for the
  156. specified process.
  157. Return Value:
  158. None.
  159. --*/
  160. {
  161. USHORT MapOffset;
  162. KIRQL OldIrql;
  163. PKPRCB Prcb;
  164. KAFFINITY TargetProcessors;
  165. //
  166. // Raise IRQL and acquire the context swap lock.
  167. //
  168. KiLockContextSwap(&OldIrql);
  169. //
  170. // Compute the new I/O Permissions Map offset and set the new offset for
  171. // the specified process.
  172. //
  173. MapOffset = KiComputeIopmOffset(Enable);
  174. Process->IopmOffset = MapOffset;
  175. //
  176. // Compute the target set of processors and send a message specifing a
  177. // new I/O Permsissions Map offset.
  178. //
  179. Prcb = KeGetCurrentPrcb();
  180. #if !defined(NT_UP)
  181. TargetProcessors = Process->ActiveProcessors & Prcb->NotSetMember;
  182. if (TargetProcessors != 0) {
  183. KiIpiSendPacket(TargetProcessors,
  184. KiSetIoAccessProcess,
  185. (PVOID)((ULONG64)MapOffset),
  186. NULL,
  187. NULL);
  188. }
  189. #endif
  190. //
  191. // If the specified process has a child thread that is running on the
  192. // current processor, then set the new I/O Permissions Map offset.
  193. //
  194. if (Process->ActiveProcessors & Prcb->SetMember) {
  195. KeGetPcr()->TssBase->IoMapBase = MapOffset;
  196. }
  197. //
  198. // Wait until all of the target processors have finished setting the new
  199. // map offset.
  200. //
  201. #if !defined(NT_UP)
  202. KiIpiStallOnPacketTargets(TargetProcessors);
  203. #endif
  204. //
  205. // Release the context swap lock and lower IRQL.
  206. //
  207. KiUnlockContextSwap(OldIrql);
  208. return;
  209. }
  210. #if !defined(NT_UP)
  211. VOID
  212. KiSetIoAccessProcess (
  213. IN PKIPI_CONTEXT SignalDone,
  214. IN PVOID MapOffset,
  215. IN PVOID Parameter2,
  216. IN PVOID Parameter3
  217. )
  218. /*++
  219. Routine Description:
  220. This is the target function to set the I/O Permissions Map offset.
  221. Arguments:
  222. MapOffset - Supplies the new I/O Permissions Map offset.
  223. Parameter2 - Parameter3 - Not Used.
  224. Return Value:
  225. None.
  226. --*/
  227. {
  228. //
  229. // Update IOPM field in TSS from current process
  230. //
  231. KeGetPcr()->TssBase->IoMapBase = (USHORT)((ULONG64)MapOffset);
  232. KiIpiSignalPacketDone(SignalDone);
  233. return;
  234. }
  235. #endif