Leaked source code of windows server 2003
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.

1146 lines
35 KiB

  1. /*++
  2. Module Name:
  3. context.c
  4. Abstract:
  5. This module implement the code that transfer machine state between
  6. context and kernel trap/exception frames.
  7. Author:
  8. William K. Cheung (wcheung) 06-Mar-1998
  9. Environment:
  10. Kernel mode only.
  11. Revision History:
  12. --*/
  13. #include "ki.h"
  14. VOID
  15. RtlpFlushRSE (
  16. OUT PULONGLONG BackingStore,
  17. OUT PULONGLONG RNat
  18. );
  19. #define ALIGN_NATS(Result, Source, Start, AddressOffset, Mask) \
  20. if (AddressOffset == Start) { \
  21. Result = (ULONGLONG)Source; \
  22. } else if (AddressOffset < Start) { \
  23. Result = (ULONGLONG)(Source << (Start - AddressOffset)); \
  24. } else { \
  25. Result = (ULONGLONG)((Source >> (AddressOffset - Start)) | \
  26. (Source << (64 + Start - AddressOffset))); \
  27. } \
  28. Result = Result & (ULONGLONG)Mask
  29. #define EXTRACT_NATS(Result, Source, Start, AddressOffset, Mask) \
  30. Result = (ULONGLONG)(Source & (ULONGLONG)Mask); \
  31. if (AddressOffset < Start) { \
  32. Result = Result >> (Start - AddressOffset); \
  33. } else if (AddressOffset > Start) { \
  34. Result = ((Result << (AddressOffset - Start)) | \
  35. (Result >> (64 + Start - AddressOffset))); \
  36. }
  37. LONG
  38. KeFlushRseExceptionFilter (
  39. IN PEXCEPTION_POINTERS ExceptionPointer,
  40. IN NTSTATUS *Status
  41. )
  42. {
  43. *Status = ExceptionPointer->ExceptionRecord->ExceptionCode;
  44. if (*Status == STATUS_IN_PAGE_ERROR &&
  45. ExceptionPointer->ExceptionRecord->NumberParameters >= 3) {
  46. *Status = (LONG) ExceptionPointer->ExceptionRecord->ExceptionInformation[2];
  47. }
  48. DbgPrint("KeFlushRseExceptionFilter: Exception raised in krnl-to-user bstore copy. Status = %x\n", *Status);
  49. return EXCEPTION_EXECUTE_HANDLER;
  50. }
  51. VOID
  52. KiGetDebugContext (
  53. IN PKTRAP_FRAME TrapFrame,
  54. IN OUT PCONTEXT ContextFrame
  55. )
  56. /*++
  57. Routine Description:
  58. This routine moves the user mode h/w debug registers from the debug register
  59. save area in the kernel stack to the context record.
  60. Arguments:
  61. TrapFrame - Supplies a pointer to a trap frame from which volatile context
  62. should be copied into the context record.
  63. ContextFrame - Supplies a pointer to the context frame that receives the
  64. context.
  65. Return Value:
  66. None.
  67. Note:
  68. PSR.db must be set to activate the debug registers.
  69. This is used for getting user mode debug registers.
  70. --*/
  71. {
  72. PKDEBUG_REGISTERS DebugRegistersSaveArea;
  73. if (TrapFrame->PreviousMode == UserMode) {
  74. DebugRegistersSaveArea = GET_DEBUG_REGISTER_SAVEAREA();
  75. RtlCopyMemory(&ContextFrame->DbI0,
  76. (PVOID)DebugRegistersSaveArea,
  77. sizeof(KDEBUG_REGISTERS));
  78. }
  79. }
  80. VOID
  81. KiSetDebugContext (
  82. IN OUT PKTRAP_FRAME TrapFrame,
  83. IN PCONTEXT ContextFrame,
  84. IN KPROCESSOR_MODE PreviousMode
  85. )
  86. /*++
  87. Routine Description:
  88. This routine moves the debug context from the specified context frame into
  89. the debug registers save area in the kernel stack.
  90. Arguments:
  91. TrapFrame - Supplies a pointer to a trap frame.
  92. ContextFrame - Supplies a pointer to a context frame that contains the
  93. context that is to be copied.
  94. PreviousMode - Supplies the processor mode for the target context.
  95. Return Value:
  96. None.
  97. Notes:
  98. PSR.db must be set to activate the debug registers.
  99. This is used for setting up debug registers for user mode.
  100. --*/
  101. {
  102. PKDEBUG_REGISTERS DebugRegistersSaveArea; // User mode h/w debug registers
  103. UNREFERENCED_PARAMETER (TrapFrame);
  104. if (PreviousMode == UserMode) {
  105. DebugRegistersSaveArea = GET_DEBUG_REGISTER_SAVEAREA();
  106. //
  107. // Sanitize the debug control regs. Leave the addresses unchanged.
  108. //
  109. DebugRegistersSaveArea->DbI0 = ContextFrame->DbI0;
  110. DebugRegistersSaveArea->DbI1 = SANITIZE_DR(ContextFrame->DbI1,UserMode);
  111. DebugRegistersSaveArea->DbI2 = ContextFrame->DbI2;
  112. DebugRegistersSaveArea->DbI3 = SANITIZE_DR(ContextFrame->DbI3,UserMode);
  113. DebugRegistersSaveArea->DbI4 = ContextFrame->DbI4;
  114. DebugRegistersSaveArea->DbI5 = SANITIZE_DR(ContextFrame->DbI5,UserMode);
  115. DebugRegistersSaveArea->DbI6 = ContextFrame->DbI6;
  116. DebugRegistersSaveArea->DbI7 = SANITIZE_DR(ContextFrame->DbI7,UserMode);
  117. DebugRegistersSaveArea->DbD0 = ContextFrame->DbD0;
  118. DebugRegistersSaveArea->DbD1 = SANITIZE_DR(ContextFrame->DbD1,UserMode);
  119. DebugRegistersSaveArea->DbD2 = ContextFrame->DbD2;
  120. DebugRegistersSaveArea->DbD3 = SANITIZE_DR(ContextFrame->DbD3,UserMode);
  121. DebugRegistersSaveArea->DbD4 = ContextFrame->DbD4;
  122. DebugRegistersSaveArea->DbD5 = SANITIZE_DR(ContextFrame->DbD5,UserMode);
  123. DebugRegistersSaveArea->DbD6 = ContextFrame->DbD6;
  124. DebugRegistersSaveArea->DbD7 = SANITIZE_DR(ContextFrame->DbD7,UserMode);
  125. }
  126. }
  127. VOID
  128. KeContextFromKframes (
  129. IN PKTRAP_FRAME TrapFrame,
  130. IN PKEXCEPTION_FRAME ExceptionFrame,
  131. IN OUT PCONTEXT ContextFrame
  132. )
  133. /*++
  134. Routine Description:
  135. This routine moves the selected contents of the specified trap and exception
  136. frames into the specified context frame according to the specified context
  137. flags.
  138. Arguments:
  139. TrapFrame - Supplies a pointer to a trap frame from which volatile context
  140. should be copied into the context record.
  141. ExceptionFrame - Supplies a pointer to an exception frame from which context
  142. should be copied into the context record.
  143. ContextFrame - Supplies a pointer to the context frame that receives the
  144. context copied from the trap and exception frames.
  145. Return Value:
  146. None.
  147. --*/
  148. {
  149. ULONGLONG IntNats1, IntNats2;
  150. USHORT R1Offset, R4Offset;
  151. KIRQL OldIrql;
  152. //
  153. // This routine is called at both PASSIVE_LEVEL by exception dispatch
  154. // and at APC_LEVEL by NtSetContextThread. We raise to APC_LEVEL to
  155. // make the trap frame capture atomic.
  156. //
  157. OldIrql = KeGetCurrentIrql ();
  158. if (OldIrql < APC_LEVEL) {
  159. KeRaiseIrql (APC_LEVEL, &OldIrql);
  160. }
  161. //
  162. // Set control information if specified.
  163. //
  164. if ((ContextFrame->ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL) {
  165. ContextFrame->IntGp = TrapFrame->IntGp;
  166. ContextFrame->IntSp = TrapFrame->IntSp;
  167. ContextFrame->ApUNAT = TrapFrame->ApUNAT;
  168. ContextFrame->BrRp = TrapFrame->BrRp;
  169. ContextFrame->StFPSR = TrapFrame->StFPSR;
  170. ContextFrame->StIPSR = TrapFrame->StIPSR;
  171. ContextFrame->StIIP = TrapFrame->StIIP;
  172. ContextFrame->StIFS = TrapFrame->StIFS;
  173. ASSERT((TrapFrame->EOFMarker & ~0xffI64) == KTRAP_FRAME_EOF);
  174. if (TRAP_FRAME_TYPE(TrapFrame) == SYSCALL_FRAME) {
  175. ContextFrame->ApCCV = 0;
  176. ContextFrame->SegCSD = 0;
  177. } else {
  178. ContextFrame->ApCCV = TrapFrame->ApCCV;
  179. ContextFrame->SegCSD = TrapFrame->SegCSD;
  180. }
  181. //
  182. // Set RSE control states from the trap frame.
  183. //
  184. ContextFrame->RsPFS = TrapFrame->RsPFS;
  185. ContextFrame->RsBSP = RtlpRseShrinkBySOF (TrapFrame->RsBSP, TrapFrame->StIFS);
  186. ContextFrame->RsBSPSTORE = ContextFrame->RsBSP;
  187. ContextFrame->RsRSC = TrapFrame->RsRSC;
  188. ContextFrame->RsRNAT = TrapFrame->RsRNAT;
  189. #if DEBUG
  190. DbgPrint("KeContextFromKFrames: RsRNAT = 0x%I64x\n",
  191. ContextFrame->RsRNAT);
  192. #endif // DEBUG
  193. //
  194. // Set preserved applicaton registers from exception frame.
  195. //
  196. ContextFrame->ApLC = ExceptionFrame->ApLC;
  197. ContextFrame->ApEC = (ExceptionFrame->ApEC >> PFS_EC_SHIFT) & PFS_EC_MASK;
  198. //
  199. // Get iA status from the application registers
  200. //
  201. ContextFrame->StFCR = __getReg(CV_IA64_AR21);
  202. ContextFrame->Eflag = __getReg(CV_IA64_AR24);
  203. ContextFrame->SegSSD = __getReg(CV_IA64_AR26);
  204. ContextFrame->Cflag = __getReg(CV_IA64_AR27);
  205. ContextFrame->StFSR = __getReg(CV_IA64_AR28);
  206. ContextFrame->StFIR = __getReg(CV_IA64_AR29);
  207. ContextFrame->StFDR = __getReg(CV_IA64_AR30);
  208. ContextFrame->ApDCR = __getReg(CV_IA64_ApDCR);
  209. }
  210. //
  211. // Set integer register contents if specified.
  212. //
  213. if ((ContextFrame->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER) {
  214. ContextFrame->Preds = TrapFrame->Preds;
  215. ContextFrame->IntTeb = TrapFrame->IntTeb;
  216. ContextFrame->IntV0 = TrapFrame->IntV0;
  217. if (TRAP_FRAME_TYPE(TrapFrame) == SYSCALL_FRAME) {
  218. ContextFrame->IntT0 = 0;
  219. ContextFrame->IntT1 = 0;
  220. ContextFrame->IntT2 = 0;
  221. ContextFrame->IntT3 = 0;
  222. ContextFrame->IntT4 = 0;
  223. //
  224. // t5 - t22
  225. //
  226. RtlZeroMemory(&ContextFrame->IntT5, 18*sizeof(ULONGLONG));
  227. //
  228. // Set branch registers from trap frame & exception frame
  229. //
  230. ContextFrame->BrT0 = 0;
  231. ContextFrame->BrT1 = 0;
  232. } else {
  233. ContextFrame->IntT0 = TrapFrame->IntT0;
  234. ContextFrame->IntT1 = TrapFrame->IntT1;
  235. ContextFrame->IntT2 = TrapFrame->IntT2;
  236. ContextFrame->IntT3 = TrapFrame->IntT3;
  237. ContextFrame->IntT4 = TrapFrame->IntT4;
  238. //
  239. // t5 - t22
  240. //
  241. memcpy(&ContextFrame->IntT5, &TrapFrame->IntT5, 18*sizeof(ULONGLONG));
  242. //
  243. // Set branch registers from trap frame & exception frame
  244. //
  245. ContextFrame->BrT0 = TrapFrame->BrT0;
  246. ContextFrame->BrT1 = TrapFrame->BrT1;
  247. }
  248. memcpy(&ContextFrame->BrS0, &ExceptionFrame->BrS0, 5*sizeof(ULONGLONG));
  249. //
  250. // Set integer registers s0 - s3 from exception frame.
  251. //
  252. ContextFrame->IntS0 = ExceptionFrame->IntS0;
  253. ContextFrame->IntS1 = ExceptionFrame->IntS1;
  254. ContextFrame->IntS2 = ExceptionFrame->IntS2;
  255. ContextFrame->IntS3 = ExceptionFrame->IntS3;
  256. //
  257. // Set the integer nats field in the context
  258. //
  259. R1Offset = (USHORT)((ULONG_PTR)(&TrapFrame->IntGp) >> 3) & 0x3f;
  260. R4Offset = (USHORT)((ULONG_PTR)(&ExceptionFrame->IntS0) >> 3) & 0x3f;
  261. ALIGN_NATS(IntNats1, TrapFrame->IntNats, 1, R1Offset, 0xFFFFFF0E);
  262. ALIGN_NATS(IntNats2, ExceptionFrame->IntNats, 4, R4Offset, 0xF0);
  263. ContextFrame->IntNats = IntNats1 | IntNats2;
  264. #if DEBUG
  265. DbgPrint("KeContextFromKFrames: TF->IntNats = 0x%I64x, R1OffSet = 0x%x, R4Offset = 0x%x\n",
  266. TrapFrame->IntNats, R1Offset, R4Offset);
  267. DbgPrint("KeContextFromKFrames: CF->IntNats = 0x%I64x, IntNats1 = 0x%I64x, IntNats2 = 0x%I64x\n",
  268. ContextFrame->IntNats, IntNats1, IntNats2);
  269. #endif // DEBUG
  270. }
  271. //
  272. // Set lower floating register contents if specified.
  273. //
  274. if ((ContextFrame->ContextFlags & CONTEXT_LOWER_FLOATING_POINT) == CONTEXT_LOWER_FLOATING_POINT) {
  275. //
  276. // Set EM + ia32 FP status
  277. //
  278. ContextFrame->StFPSR = TrapFrame->StFPSR;
  279. //
  280. // Set floating registers fs0 - fs19 from exception frame.
  281. //
  282. RtlCopyIa64FloatRegisterContext(&ContextFrame->FltS0,
  283. &ExceptionFrame->FltS0,
  284. sizeof(FLOAT128) * (4));
  285. RtlCopyIa64FloatRegisterContext(&ContextFrame->FltS4,
  286. &ExceptionFrame->FltS4,
  287. 16*sizeof(FLOAT128));
  288. //
  289. // Set floating registers ft0 - ft9 from trap frame.
  290. //
  291. if (TRAP_FRAME_TYPE(TrapFrame) == SYSCALL_FRAME) {
  292. RtlZeroMemory(&ContextFrame->FltT0, sizeof(FLOAT128) * (10));
  293. } else {
  294. RtlCopyIa64FloatRegisterContext(&ContextFrame->FltT0,
  295. &TrapFrame->FltT0,
  296. sizeof(FLOAT128) * (10));
  297. }
  298. }
  299. if ((ContextFrame->ContextFlags & CONTEXT_HIGHER_FLOATING_POINT) == CONTEXT_HIGHER_FLOATING_POINT) {
  300. ContextFrame->StFPSR = TrapFrame->StFPSR;
  301. //
  302. // Set floating regs f32 - f127 from higher floating point save area
  303. //
  304. if (TrapFrame->PreviousMode == UserMode) {
  305. RtlCopyIa64FloatRegisterContext(
  306. &ContextFrame->FltF32,
  307. (PFLOAT128)GET_HIGH_FLOATING_POINT_REGISTER_SAVEAREA(KeGetCurrentThread()->StackBase),
  308. 96*sizeof(FLOAT128)
  309. );
  310. }
  311. }
  312. //
  313. // Get user debug registers from save area in kernel stack.
  314. // Note: PSR.db must be set to activate the debug registers.
  315. //
  316. if ((ContextFrame->ContextFlags & CONTEXT_DEBUG) == CONTEXT_DEBUG) {
  317. KiGetDebugContext(TrapFrame, ContextFrame);
  318. }
  319. //
  320. // Lower IRQL if we had to raise it
  321. //
  322. if (OldIrql < APC_LEVEL) {
  323. KeLowerIrql (OldIrql);
  324. }
  325. return;
  326. }
  327. VOID
  328. KeContextToKframes (
  329. IN OUT PKTRAP_FRAME TrapFrame,
  330. IN OUT PKEXCEPTION_FRAME ExceptionFrame,
  331. IN PCONTEXT ContextFrame,
  332. IN ULONG ContextFlags,
  333. IN KPROCESSOR_MODE PreviousMode
  334. )
  335. /*++
  336. Routine Description:
  337. This routine moves the selected contents of the specified context frame into
  338. the specified trap and exception frames according to the specified context
  339. flags.
  340. Arguments:
  341. TrapFrame - Supplies a pointer to a trap frame that receives the volatile
  342. context from the context record.
  343. ExceptionFrame - Supplies a pointer to an exception frame that receives
  344. the nonvolatile context from the context record.
  345. ContextFrame - Supplies a pointer to a context frame that contains the
  346. context that is to be copied into the trap and exception frames.
  347. ContextFlags - Supplies the set of flags that specify which parts of the
  348. context frame are to be copied into the trap and exception frames.
  349. PreviousMode - Supplies the processor mode for which the trap and exception
  350. frames are being built.
  351. Return Value:
  352. None.
  353. --*/
  354. {
  355. USHORT R1Offset, R4Offset;
  356. KIRQL OldIrql;
  357. PSR psr;
  358. //
  359. // This routine is called at both PASSIVE_LEVEL by exception dispatch
  360. // and at APC_LEVEL by NtSetContextThread. We raise to APC_LEVEL to
  361. // make the trap frame capture atomic.
  362. //
  363. OldIrql = KeGetCurrentIrql ();
  364. if (OldIrql < APC_LEVEL) {
  365. KeRaiseIrql (APC_LEVEL, &OldIrql);
  366. }
  367. //
  368. // If the trap frame is syscall then sanitize the volitile registers
  369. // that are not saved by the system call handler. This is necessary
  370. // if the user did not pass a complete context, because we are going
  371. // to later treat the frame like an exception frame.
  372. //
  373. if (TRAP_FRAME_TYPE(TrapFrame) == SYSCALL_FRAME) {
  374. TrapFrame->ApCCV = 0;
  375. TrapFrame->SegCSD = 0;
  376. TrapFrame->IntT0 = 0;
  377. TrapFrame->IntT1 = 0;
  378. TrapFrame->IntT2 = 0;
  379. TrapFrame->IntT3 = 0;
  380. TrapFrame->IntT4 = 0;
  381. //
  382. // t5 - t22
  383. //
  384. RtlZeroMemory(&TrapFrame->IntT5, 18*sizeof(ULONGLONG));
  385. //
  386. // Set branch registers from trap frame & exception frame
  387. //
  388. TrapFrame->BrT0 = 0;
  389. TrapFrame->BrT1 = 0;
  390. RtlZeroMemory(&TrapFrame->FltT0, sizeof(FLOAT128) * (10));
  391. }
  392. //
  393. // Set control information if specified.
  394. //
  395. if ((ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL) {
  396. TrapFrame->IntGp = ContextFrame->IntGp;
  397. TrapFrame->IntSp = ContextFrame->IntSp;
  398. TrapFrame->ApUNAT = ContextFrame->ApUNAT;
  399. TrapFrame->BrRp = ContextFrame->BrRp;
  400. TrapFrame->ApCCV = ContextFrame->ApCCV;
  401. TrapFrame->SegCSD = ContextFrame->SegCSD;
  402. //
  403. // Set preserved applicaton registers in exception frame.
  404. //
  405. ExceptionFrame->ApLC = ContextFrame->ApLC;
  406. ExceptionFrame->ApEC &= ~((ULONGLONG)PFS_EC_MASK << PFS_EC_SHIFT);
  407. ExceptionFrame->ApEC |= ((ContextFrame->ApEC & PFS_EC_MASK) << PFS_EC_SHIFT);
  408. //
  409. // Set RSE control states in the trap frame.
  410. //
  411. TrapFrame->RsPFS = SANITIZE_PFS(ContextFrame->RsPFS, PreviousMode);
  412. TrapFrame->RsBSP = RtlpRseGrowBySOF (ContextFrame->RsBSP, ContextFrame->StIFS);
  413. TrapFrame->RsBSPSTORE = TrapFrame->RsBSP;
  414. TrapFrame->RsRSC = SANITIZE_RSC(ContextFrame->RsRSC, PreviousMode);
  415. TrapFrame->RsRNAT = ContextFrame->RsRNAT;
  416. #if DEBUG
  417. DbgPrint("KeContextToKFrames: RsRNAT = 0x%I64x\n", TrapFrame->RsRNAT);
  418. #endif // DEBUG
  419. //
  420. // Set FPSR, IPSR, IIP, and IFS in the trap frame.
  421. //
  422. TrapFrame->StFPSR = SANITIZE_FSR(ContextFrame->StFPSR, PreviousMode);
  423. TrapFrame->StIFS = SANITIZE_IFS(ContextFrame->StIFS, PreviousMode);
  424. TrapFrame->StIIP = ContextFrame->StIIP;
  425. //
  426. // If the preivous mode is user and the mode in the StIPSR is zero, then
  427. // it is likely this context was captured from user mode using psr.um.
  428. // Copy the debugger bits from the trap frame into the context PSR so
  429. // the debugger setting remain acorss the an raise.
  430. //
  431. psr.ull = ContextFrame->StIPSR;
  432. if (PreviousMode == UserMode &&
  433. psr.sb.psr_cpl == 0 ) {
  434. PSR tpsr;
  435. tpsr.ull = TrapFrame->StIPSR;
  436. if (tpsr.sb.psr_tb || tpsr.sb.psr_ss || tpsr.sb.psr_db || tpsr.sb.psr_lp) {
  437. DbgPrint("KeContextToKFrames debug bit set in psr %I64x\n", TrapFrame->StIPSR);
  438. }
  439. psr.sb.psr_tb = tpsr.sb.psr_tb;
  440. psr.sb.psr_ss = tpsr.sb.psr_ss;
  441. psr.sb.psr_db = tpsr.sb.psr_db;
  442. psr.sb.psr_lp = tpsr.sb.psr_lp;
  443. }
  444. TrapFrame->StIPSR = SANITIZE_PSR(psr.ull, PreviousMode);
  445. if (PreviousMode == UserMode ) {
  446. //
  447. // Set and sanitize iA status
  448. //
  449. __setReg(CV_IA64_AR21, SANITIZE_AR21_FCR (ContextFrame->StFCR, UserMode));
  450. __setReg(CV_IA64_AR24, SANITIZE_AR24_EFLAGS (ContextFrame->Eflag, UserMode));
  451. __setReg(CV_IA64_AR26, ContextFrame->SegSSD);
  452. __setReg(CV_IA64_AR27, SANITIZE_AR27_CFLG (ContextFrame->Cflag, UserMode));
  453. __setReg(CV_IA64_AR28, SANITIZE_AR28_FSR (ContextFrame->StFSR, UserMode));
  454. __setReg(CV_IA64_AR29, SANITIZE_AR29_FIR (ContextFrame->StFIR, UserMode));
  455. __setReg(CV_IA64_AR30, SANITIZE_AR30_FDR (ContextFrame->StFDR, UserMode));
  456. }
  457. __setReg(CV_IA64_ApDCR, SANITIZE_DCR(ContextFrame->ApDCR, PreviousMode));
  458. }
  459. //
  460. // Set integer registers contents if specified.
  461. //
  462. if ((ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER) {
  463. TrapFrame->IntT0 = ContextFrame->IntT0;
  464. TrapFrame->IntT1 = ContextFrame->IntT1;
  465. TrapFrame->IntT2 = ContextFrame->IntT2;
  466. TrapFrame->IntT3 = ContextFrame->IntT3;
  467. TrapFrame->IntT4 = ContextFrame->IntT4;
  468. TrapFrame->IntV0 = ContextFrame->IntV0;
  469. TrapFrame->IntTeb = ContextFrame->IntTeb;
  470. TrapFrame->Preds = ContextFrame->Preds;
  471. //
  472. // t5 - t22
  473. //
  474. memcpy(&TrapFrame->IntT5, &ContextFrame->IntT5, 18*sizeof(ULONGLONG));
  475. //
  476. // Set integer registers s0 - s3 in exception frame.
  477. //
  478. ExceptionFrame->IntS0 = ContextFrame->IntS0;
  479. ExceptionFrame->IntS1 = ContextFrame->IntS1;
  480. ExceptionFrame->IntS2 = ContextFrame->IntS2;
  481. ExceptionFrame->IntS3 = ContextFrame->IntS3;
  482. //
  483. // Set the integer nats field in the trap & exception frames
  484. //
  485. R1Offset = (USHORT)((ULONG_PTR)(&TrapFrame->IntGp) >> 3) & 0x3f;
  486. R4Offset = (USHORT)((ULONG_PTR)(&ExceptionFrame->IntS0) >> 3) & 0x3f;
  487. EXTRACT_NATS(TrapFrame->IntNats, ContextFrame->IntNats,
  488. 1, R1Offset, 0xFFFFFF0E);
  489. EXTRACT_NATS(ExceptionFrame->IntNats, ContextFrame->IntNats,
  490. 4, R4Offset, 0xF0);
  491. #if DEBUG
  492. DbgPrint("KeContextToKFrames: TF->IntNats = 0x%I64x, ContestFrame->IntNats = 0x%I64x, R1OffSet = 0x%x\n",
  493. TrapFrame->IntNats, ContextFrame->IntNats, R1Offset);
  494. DbgPrint("KeContextToKFrames: EF->IntNats = 0x%I64x, R4OffSet = 0x%x\n",
  495. ExceptionFrame->IntNats, R4Offset);
  496. #endif // DEBUG
  497. //
  498. // Set other branch registers in trap and exception frames
  499. //
  500. TrapFrame->BrT0 = ContextFrame->BrT0;
  501. TrapFrame->BrT1 = ContextFrame->BrT1;
  502. memcpy(&ExceptionFrame->BrS0, &ContextFrame->BrS0, 5*sizeof(ULONGLONG));
  503. }
  504. //
  505. // Set lower floating register contents if specified.
  506. //
  507. if ((ContextFlags & CONTEXT_LOWER_FLOATING_POINT) == CONTEXT_LOWER_FLOATING_POINT) {
  508. TrapFrame->StFPSR = SANITIZE_FSR(ContextFrame->StFPSR, PreviousMode);
  509. //
  510. // Set floating registers fs0 - fs19 in exception frame.
  511. //
  512. RtlCopyIa64FloatRegisterContext(&ExceptionFrame->FltS0,
  513. &ContextFrame->FltS0,
  514. sizeof(FLOAT128) * (4));
  515. RtlCopyIa64FloatRegisterContext(&ExceptionFrame->FltS4,
  516. &ContextFrame->FltS4,
  517. 16*sizeof(FLOAT128));
  518. //
  519. // Set floating registers ft0 - ft9 in trap frame.
  520. //
  521. RtlCopyIa64FloatRegisterContext(&TrapFrame->FltT0,
  522. &ContextFrame->FltT0,
  523. sizeof(FLOAT128) * (10));
  524. }
  525. //
  526. // Set higher floating register contents if specified.
  527. //
  528. if ((ContextFlags & CONTEXT_HIGHER_FLOATING_POINT) == CONTEXT_HIGHER_FLOATING_POINT) {
  529. TrapFrame->StFPSR = SANITIZE_FSR(ContextFrame->StFPSR, PreviousMode);
  530. if (PreviousMode == UserMode) {
  531. //
  532. // Update the higher floating point save area (f32-f127) and
  533. // set the corresponding modified bit in the PSR to 1.
  534. //
  535. RtlCopyIa64FloatRegisterContext(
  536. (PFLOAT128)GET_HIGH_FLOATING_POINT_REGISTER_SAVEAREA(KeGetCurrentThread()->StackBase),
  537. &ContextFrame->FltF32,
  538. 96*sizeof(FLOAT128)
  539. );
  540. TrapFrame->StIPSR |= (1i64 << PSR_DFH);
  541. TrapFrame->StIPSR &= ~(1i64 << PSR_MFH);
  542. }
  543. }
  544. //
  545. // Set debug registers.
  546. //
  547. if ((ContextFlags & CONTEXT_DEBUG) == CONTEXT_DEBUG) {
  548. KiSetDebugContext (TrapFrame, ContextFrame, PreviousMode);
  549. }
  550. //
  551. // The trap frame now has a complete volatile context. Mark it as such so the user
  552. // debugger can get the complete context
  553. //
  554. if (TRAP_FRAME_TYPE(TrapFrame) == SYSCALL_FRAME) {
  555. TrapFrame->EOFMarker |= EXCEPTION_FRAME;
  556. }
  557. //
  558. // Lower IRQL if we had to raise it
  559. //
  560. if (OldIrql < APC_LEVEL) {
  561. KeLowerIrql (OldIrql);
  562. }
  563. return;
  564. }
  565. NTSTATUS
  566. KeFlushUserRseState (
  567. IN PKTRAP_FRAME TrapFrame
  568. )
  569. /*++
  570. Routine Description:
  571. This routine flushes the user rse state from the kernel backing store to the
  572. user backing store. The user context frame is update to reflect the new
  573. context state.
  574. Arguments:
  575. TrapFrame - Supplies a pointer to a trap frame.
  576. Return Value:
  577. None.
  578. --*/
  579. {
  580. ULONGLONG BsFrameSize;
  581. PULONGLONG RNatAddress;
  582. ULONGLONG BspStoreReal;
  583. ULONGLONG Bsp;
  584. ULONGLONG Rnat;
  585. ULONGLONG KernelInitBsp;
  586. NTSTATUS Status = STATUS_SUCCESS;
  587. USHORT TearPointOffset;
  588. //
  589. // There is nothing to copy back in the kernel mode case.
  590. // Just fix up the RNAT register.
  591. //
  592. if (TrapFrame->PreviousMode != UserMode) {
  593. RtlpFlushRSE(&Bsp, &Rnat);
  594. RNatAddress = RtlpRseRNatAddress(TrapFrame->RsBSP);
  595. if ( RNatAddress != RtlpRseRNatAddress((Bsp - 8)) ) {
  596. Rnat = *RNatAddress;
  597. }
  598. TrapFrame->RsRNAT = Rnat;
  599. return STATUS_SUCCESS;
  600. }
  601. //
  602. // Copy user stacked registers' contents to user backing store.
  603. // N.B. Stack overflow could happen.
  604. //
  605. try {
  606. //
  607. // The RsBSPSTORE value may be incorrect paritcularly if the kernel debugger
  608. // done a set context on the thread, but the dirty register count in RSE is
  609. // correct.
  610. //
  611. BsFrameSize = (SHORT) (TrapFrame->RsRSC >> RSC_MBZ1);
  612. BspStoreReal = TrapFrame->RsBSP - BsFrameSize;
  613. if (BsFrameSize) {
  614. //
  615. // Copy the dirty stacked registers back into the
  616. // user backing store
  617. //
  618. RtlpFlushRSE(&Bsp, &Rnat);
  619. TearPointOffset = (USHORT) BspStoreReal & 0x1F8;
  620. KernelInitBsp= (PCR->InitialBStore | TearPointOffset) + BsFrameSize - 8;
  621. RNatAddress = RtlpRseRNatAddress(KernelInitBsp);
  622. if ( RNatAddress != RtlpRseRNatAddress((Bsp - 8)) ) {
  623. Rnat = *RNatAddress;
  624. }
  625. ProbeForWrite((PVOID)BspStoreReal, BsFrameSize, sizeof(PVOID));
  626. RtlCopyMemory((PVOID)(BspStoreReal),
  627. (PVOID)(PCR->InitialBStore + TearPointOffset),
  628. BsFrameSize);
  629. TrapFrame->RsRNAT = Rnat;
  630. }
  631. //
  632. // Successfully copied to user backing store; set the user's
  633. // bspstore to the value of its own bsp.
  634. // And Zero the loadrs field of RsRSC.
  635. //
  636. TrapFrame->RsBSPSTORE = TrapFrame->RsBSP;
  637. TrapFrame->RsRSC = ZERO_PRELOAD_SIZE(TrapFrame->RsRSC);
  638. } except (KeFlushRseExceptionFilter(GetExceptionInformation(), &Status)) {
  639. }
  640. return Status;
  641. }
  642. VOID
  643. KeContextToKframesSpecial (
  644. IN PKTHREAD Thread,
  645. IN OUT PKTRAP_FRAME TrapFrame,
  646. IN OUT PKEXCEPTION_FRAME ExceptionFrame,
  647. IN PCONTEXT ContextFrame,
  648. IN ULONG ContextFlags
  649. )
  650. /*++
  651. Routine Description:
  652. This routine moves the selected contents of the specified context frame into
  653. the specified trap and exception frames according to the specified context
  654. flags.
  655. Arguments:
  656. TrapFrame - Supplies a pointer to a trap frame that receives the volatile
  657. context from the context record.
  658. ExceptionFrame - Supplies a pointer to an exception frame that receives
  659. the nonvolatile context from the context record.
  660. ContextFrame - Supplies a pointer to a context frame that contains the
  661. context that is to be copied into the trap and exception frames.
  662. ContextFlags - Supplies the set of flags that specify which parts of the
  663. context frame are to be copied into the trap and exception frames.
  664. PreviousMode - Supplies the processor mode for which the trap and exception
  665. frames are being built.
  666. Return Value:
  667. None.
  668. --*/
  669. {
  670. USHORT R1Offset, R4Offset;
  671. //
  672. // Set control information if specified.
  673. //
  674. if ((ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL) {
  675. TrapFrame->IntGp = ContextFrame->IntGp;
  676. TrapFrame->IntSp = ContextFrame->IntSp;
  677. TrapFrame->ApUNAT = ContextFrame->ApUNAT;
  678. TrapFrame->BrRp = ContextFrame->BrRp;
  679. TrapFrame->ApCCV = ContextFrame->ApCCV;
  680. TrapFrame->SegCSD = ContextFrame->SegCSD;
  681. //
  682. // Set preserved applicaton registers in exception frame.
  683. //
  684. ExceptionFrame->ApLC = ContextFrame->ApLC;
  685. ExceptionFrame->ApEC &= ~((ULONGLONG)PFS_EC_MASK << PFS_EC_SHIFT);
  686. ExceptionFrame->ApEC |= ((ContextFrame->ApEC & PFS_EC_MASK) << PFS_EC_SHIFT);
  687. //
  688. // Set RSE control states in the trap frame.
  689. //
  690. TrapFrame->RsPFS = ContextFrame->RsPFS;
  691. TrapFrame->RsBSP = RtlpRseGrowBySOF (ContextFrame->RsBSP, ContextFrame->StIFS);
  692. TrapFrame->RsBSPSTORE = TrapFrame->RsBSP;
  693. TrapFrame->RsRSC = SANITIZE_RSC(ContextFrame->RsRSC, UserMode);
  694. TrapFrame->RsRNAT = ContextFrame->RsRNAT;
  695. #if DEBUG
  696. DbgPrint("KeContextToKFrames: RsRNAT = 0x%I64x\n", TrapFrame->RsRNAT);
  697. #endif // DEBUG
  698. //
  699. // Set FPSR, IPSR, IIP, and IFS in the trap frame.
  700. //
  701. TrapFrame->StFPSR = SANITIZE_FSR(ContextFrame->StFPSR, UserMode);
  702. TrapFrame->StIPSR = SANITIZE_PSR(ContextFrame->StIPSR, UserMode);
  703. TrapFrame->StIFS = SANITIZE_IFS(ContextFrame->StIFS, UserMode);
  704. TrapFrame->StIIP = ContextFrame->StIIP;
  705. //
  706. // Set application registers directly
  707. //
  708. if (Thread == KeGetCurrentThread()) {
  709. //
  710. // Set and sanitize iA status
  711. //
  712. __setReg(CV_IA64_AR21, SANITIZE_AR21_FCR (ContextFrame->StFCR, UserMode));
  713. __setReg(CV_IA64_AR24, SANITIZE_AR24_EFLAGS (ContextFrame->Eflag, UserMode));
  714. __setReg(CV_IA64_AR26, ContextFrame->SegSSD);
  715. __setReg(CV_IA64_AR27, SANITIZE_AR27_CFLG (ContextFrame->Cflag, UserMode));
  716. __setReg(CV_IA64_AR28, SANITIZE_AR28_FSR (ContextFrame->StFSR, UserMode));
  717. __setReg(CV_IA64_AR29, SANITIZE_AR29_FIR (ContextFrame->StFIR, UserMode));
  718. __setReg(CV_IA64_AR30, SANITIZE_AR30_FDR (ContextFrame->StFDR, UserMode));
  719. __setReg(CV_IA64_ApDCR, SANITIZE_DCR(ContextFrame->ApDCR, UserMode));
  720. } else {
  721. PKAPPLICATION_REGISTERS AppRegs;
  722. AppRegs = GET_APPLICATION_REGISTER_SAVEAREA(Thread->StackBase);
  723. AppRegs->Ar21 = SANITIZE_AR21_FCR (ContextFrame->StFCR, UserMode);
  724. AppRegs->Ar24 = SANITIZE_AR24_EFLAGS (ContextFrame->Eflag, UserMode);
  725. AppRegs->Ar26 = ContextFrame->SegSSD;
  726. AppRegs->Ar27 = SANITIZE_AR27_CFLG (ContextFrame->Cflag, UserMode);
  727. AppRegs->Ar28 = SANITIZE_AR28_FSR (ContextFrame->StFSR, UserMode);
  728. AppRegs->Ar29 = SANITIZE_AR29_FIR (ContextFrame->StFIR, UserMode);
  729. AppRegs->Ar30 = SANITIZE_AR30_FDR (ContextFrame->StFDR, UserMode);
  730. }
  731. }
  732. //
  733. // Set integer registers contents if specified.
  734. //
  735. if ((ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER) {
  736. TrapFrame->IntT0 = ContextFrame->IntT0;
  737. TrapFrame->IntT1 = ContextFrame->IntT1;
  738. TrapFrame->IntT2 = ContextFrame->IntT2;
  739. TrapFrame->IntT3 = ContextFrame->IntT3;
  740. TrapFrame->IntT4 = ContextFrame->IntT4;
  741. TrapFrame->IntV0 = ContextFrame->IntV0;
  742. TrapFrame->IntTeb = ContextFrame->IntTeb;
  743. TrapFrame->Preds = ContextFrame->Preds;
  744. //
  745. // t5 - t22
  746. //
  747. memcpy(&TrapFrame->IntT5, &ContextFrame->IntT5, 18*sizeof(ULONGLONG));
  748. //
  749. // Set integer registers s0 - s3 in exception frame.
  750. //
  751. ExceptionFrame->IntS0 = ContextFrame->IntS0;
  752. ExceptionFrame->IntS1 = ContextFrame->IntS1;
  753. ExceptionFrame->IntS2 = ContextFrame->IntS2;
  754. ExceptionFrame->IntS3 = ContextFrame->IntS3;
  755. //
  756. // Set the integer nats field in the trap & exception frames
  757. //
  758. R1Offset = (USHORT)((ULONG_PTR)(&TrapFrame->IntGp) >> 3) & 0x3f;
  759. R4Offset = (USHORT)((ULONG_PTR)(&ExceptionFrame->IntS0) >> 3) & 0x3f;
  760. EXTRACT_NATS(TrapFrame->IntNats, ContextFrame->IntNats,
  761. 1, R1Offset, 0xFFFFFF0E);
  762. EXTRACT_NATS(ExceptionFrame->IntNats, ContextFrame->IntNats,
  763. 4, R4Offset, 0xF0);
  764. #if DEBUG
  765. DbgPrint("KeContextToKFrames: TF->IntNats = 0x%I64x, ContestFrame->IntNats = 0x%I64x, R1OffSet = 0x%x\n",
  766. TrapFrame->IntNats, ContextFrame->IntNats, R1Offset);
  767. DbgPrint("KeContextToKFrames: EF->IntNats = 0x%I64x, R4OffSet = 0x%x\n",
  768. ExceptionFrame->IntNats, R4Offset);
  769. #endif // DEBUG
  770. //
  771. // Set other branch registers in trap and exception frames
  772. //
  773. TrapFrame->BrT0 = ContextFrame->BrT0;
  774. TrapFrame->BrT1 = ContextFrame->BrT1;
  775. memcpy(&ExceptionFrame->BrS0, &ContextFrame->BrS0, 5*sizeof(ULONGLONG));
  776. }
  777. //
  778. // Set lower floating register contents if specified.
  779. //
  780. if ((ContextFlags & CONTEXT_LOWER_FLOATING_POINT) == CONTEXT_LOWER_FLOATING_POINT) {
  781. TrapFrame->StFPSR = SANITIZE_FSR(ContextFrame->StFPSR, UserMode);
  782. //
  783. // Set floating registers fs0 - fs19 in exception frame.
  784. //
  785. RtlCopyIa64FloatRegisterContext(&ExceptionFrame->FltS0,
  786. &ContextFrame->FltS0,
  787. sizeof(FLOAT128) * (4));
  788. RtlCopyIa64FloatRegisterContext(&ExceptionFrame->FltS4,
  789. &ContextFrame->FltS4,
  790. 16*sizeof(FLOAT128));
  791. //
  792. // Set floating registers ft0 - ft9 in trap frame.
  793. //
  794. RtlCopyIa64FloatRegisterContext(&TrapFrame->FltT0,
  795. &ContextFrame->FltT0,
  796. sizeof(FLOAT128) * (10));
  797. }
  798. //
  799. // Set higher floating register contents if specified.
  800. //
  801. if ((ContextFlags & CONTEXT_HIGHER_FLOATING_POINT) == CONTEXT_HIGHER_FLOATING_POINT) {
  802. TrapFrame->StFPSR = SANITIZE_FSR(ContextFrame->StFPSR, UserMode);
  803. //
  804. // Update the higher floating point save area (f32-f127) and
  805. // set the corresponding modified bit in the PSR to 1.
  806. //
  807. RtlCopyIa64FloatRegisterContext(
  808. (PFLOAT128)GET_HIGH_FLOATING_POINT_REGISTER_SAVEAREA(Thread->StackBase),
  809. &ContextFrame->FltF32,
  810. 96*sizeof(FLOAT128)
  811. );
  812. //
  813. // set the dfh bit to force a reload of the high fp register
  814. // set on the next user access, and clear mfh to make sure
  815. // the changes are not over written.
  816. //
  817. TrapFrame->StIPSR |= (1i64 << PSR_DFH);
  818. TrapFrame->StIPSR &= ~(1i64 << PSR_MFH);
  819. }
  820. //
  821. // Set debug registers.
  822. //
  823. if ((ContextFlags & CONTEXT_DEBUG) == CONTEXT_DEBUG) {
  824. KiSetDebugContext (TrapFrame, ContextFrame, UserMode);
  825. }
  826. return;
  827. }