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.

1053 lines
32 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. PETHREAD Thread = PsGetCurrentThread();
  44. *Status = ExceptionPointer->ExceptionRecord->ExceptionCode;
  45. if (*Status == STATUS_IN_PAGE_ERROR &&
  46. ExceptionPointer->ExceptionRecord->NumberParameters >= 3) {
  47. *Status = (LONG) ExceptionPointer->ExceptionRecord->ExceptionInformation[2];
  48. }
  49. DbgPrint("KeFlushRseExceptionFilter: Exception raised in krnl-to-user bstore copy. Status = %x\n", *Status);
  50. return EXCEPTION_EXECUTE_HANDLER;
  51. }
  52. VOID
  53. KiGetDebugContext (
  54. IN PKTRAP_FRAME TrapFrame,
  55. IN OUT PCONTEXT ContextFrame
  56. )
  57. /*++
  58. Routine Description:
  59. This routine moves the user mode h/w debug registers from the debug register
  60. save area in the kernel stack to the context record.
  61. Arguments:
  62. TrapFrame - Supplies a pointer to a trap frame from which volatile context
  63. should be copied into the context record.
  64. ContextFrame - Supplies a pointer to the context frame that receives the
  65. context.
  66. Return Value:
  67. None.
  68. Note:
  69. PSR.db must be set to activate the debug registers.
  70. This is used for getting user mode debug registers.
  71. --*/
  72. {
  73. PKDEBUG_REGISTERS DebugRegistersSaveArea;
  74. if (TrapFrame->PreviousMode == UserMode) {
  75. DebugRegistersSaveArea = GET_DEBUG_REGISTER_SAVEAREA();
  76. RtlCopyMemory(&ContextFrame->DbI0,
  77. (PVOID)DebugRegistersSaveArea,
  78. sizeof(KDEBUG_REGISTERS));
  79. }
  80. }
  81. VOID
  82. KiSetDebugContext (
  83. IN OUT PKTRAP_FRAME TrapFrame,
  84. IN PCONTEXT ContextFrame,
  85. IN KPROCESSOR_MODE PreviousMode
  86. )
  87. /*++
  88. Routine Description:
  89. This routine moves the debug context from the specified context frame into
  90. the debug registers save area in the kernel stack.
  91. Arguments:
  92. TrapFrame - Supplies a pointer to a trap frame.
  93. ContextFrame - Supplies a pointer to a context frame that contains the
  94. context that is to be copied.
  95. PreviousMode - Supplies the processor mode for the target context.
  96. Return Value:
  97. None.
  98. Notes:
  99. PSR.db must be set to activate the debug registers.
  100. This is used for setting up debug registers for user mode.
  101. --*/
  102. {
  103. PKDEBUG_REGISTERS DebugRegistersSaveArea; // User mode h/w debug registers
  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. USHORT RNatSaveIndex;
  152. SHORT BsFrameSize;
  153. SHORT TempFrameSize;
  154. //
  155. // Set control information if specified.
  156. //
  157. if ((ContextFrame->ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL) {
  158. ContextFrame->IntGp = TrapFrame->IntGp;
  159. ContextFrame->IntSp = TrapFrame->IntSp;
  160. ContextFrame->ApUNAT = TrapFrame->ApUNAT;
  161. ContextFrame->BrRp = TrapFrame->BrRp;
  162. ContextFrame->ApCCV = TrapFrame->ApCCV;
  163. ContextFrame->ApDCR = TrapFrame->ApDCR;
  164. ContextFrame->StFPSR = TrapFrame->StFPSR;
  165. ContextFrame->StIPSR = TrapFrame->StIPSR;
  166. ContextFrame->StIIP = TrapFrame->StIIP;
  167. ContextFrame->StIFS = TrapFrame->StIFS;
  168. //
  169. // Set RSE control states from the trap frame.
  170. //
  171. ContextFrame->RsPFS = TrapFrame->RsPFS;
  172. BsFrameSize = (SHORT)(TrapFrame->StIFS & PFS_SIZE_MASK);
  173. RNatSaveIndex = (USHORT) (TrapFrame->RsBSP >> 3) & NAT_BITS_PER_RNAT_REG;
  174. TempFrameSize = BsFrameSize - RNatSaveIndex;
  175. while (TempFrameSize > 0) {
  176. BsFrameSize++;
  177. TempFrameSize -= NAT_BITS_PER_RNAT_REG;
  178. }
  179. ContextFrame->RsBSP = TrapFrame->RsBSP - BsFrameSize * 8;
  180. ContextFrame->RsBSPSTORE = ContextFrame->RsBSP;
  181. ContextFrame->RsRSC = TrapFrame->RsRSC;
  182. ContextFrame->RsRNAT = TrapFrame->RsRNAT;
  183. #if DEBUG
  184. DbgPrint("KeContextFromKFrames: RsRNAT = 0x%I64x\n",
  185. ContextFrame->RsRNAT);
  186. #endif // DEBUG
  187. //
  188. // Set preserved applicaton registers from exception frame.
  189. //
  190. ContextFrame->ApLC = ExceptionFrame->ApLC;
  191. ContextFrame->ApEC = (ExceptionFrame->ApEC >> PFS_EC_SHIFT) & PFS_EC_MASK;
  192. //
  193. // Get iA status from the application registers
  194. //
  195. ContextFrame->StFCR = __getReg(CV_IA64_AR21);
  196. ContextFrame->Eflag = __getReg(CV_IA64_AR24);
  197. ContextFrame->SegCSD = __getReg(CV_IA64_AR25);
  198. ContextFrame->SegSSD = __getReg(CV_IA64_AR26);
  199. ContextFrame->Cflag = __getReg(CV_IA64_AR27);
  200. ContextFrame->StFSR = __getReg(CV_IA64_AR28);
  201. ContextFrame->StFIR = __getReg(CV_IA64_AR29);
  202. ContextFrame->StFDR = __getReg(CV_IA64_AR30);
  203. }
  204. //
  205. // Set integer register contents if specified.
  206. //
  207. if ((ContextFrame->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER) {
  208. ContextFrame->IntT0 = TrapFrame->IntT0;
  209. ContextFrame->IntT1 = TrapFrame->IntT1;
  210. ContextFrame->IntT2 = TrapFrame->IntT2;
  211. ContextFrame->IntT3 = TrapFrame->IntT3;
  212. ContextFrame->IntT4 = TrapFrame->IntT4;
  213. ContextFrame->IntV0 = TrapFrame->IntV0;
  214. ContextFrame->IntTeb = TrapFrame->IntTeb;
  215. ContextFrame->Preds = TrapFrame->Preds;
  216. //
  217. // t5 - t22
  218. //
  219. memcpy(&ContextFrame->IntT5, &TrapFrame->IntT5, 18*sizeof(ULONGLONG));
  220. //
  221. // Set branch registers from trap frame & exception frame
  222. //
  223. ContextFrame->BrT0 = TrapFrame->BrT0;
  224. ContextFrame->BrT1 = TrapFrame->BrT1;
  225. memcpy(&ContextFrame->BrS0, &ExceptionFrame->BrS0, 5*sizeof(ULONGLONG));
  226. //
  227. // Set integer registers s0 - s3 from exception frame.
  228. //
  229. ContextFrame->IntS0 = ExceptionFrame->IntS0;
  230. ContextFrame->IntS1 = ExceptionFrame->IntS1;
  231. ContextFrame->IntS2 = ExceptionFrame->IntS2;
  232. ContextFrame->IntS3 = ExceptionFrame->IntS3;
  233. //
  234. // Set the integer nats field in the context
  235. //
  236. R1Offset = (USHORT)((ULONG_PTR)(&TrapFrame->IntGp) >> 3) & 0x3f;
  237. R4Offset = (USHORT)((ULONG_PTR)(&ExceptionFrame->IntS0) >> 3) & 0x3f;
  238. ALIGN_NATS(IntNats1, TrapFrame->IntNats, 1, R1Offset, 0xFFFFFF0E);
  239. ALIGN_NATS(IntNats2, ExceptionFrame->IntNats, 4, R4Offset, 0xF0);
  240. ContextFrame->IntNats = IntNats1 | IntNats2;
  241. #if DEBUG
  242. DbgPrint("KeContextFromKFrames: TF->IntNats = 0x%I64x, R1OffSet = 0x%x, R4Offset = 0x%x\n",
  243. TrapFrame->IntNats, R1Offset, R4Offset);
  244. DbgPrint("KeContextFromKFrames: CF->IntNats = 0x%I64x, IntNats1 = 0x%I64x, IntNats2 = 0x%I64x\n",
  245. ContextFrame->IntNats, IntNats1, IntNats2);
  246. #endif // DEBUG
  247. }
  248. //
  249. // Set lower floating register contents if specified.
  250. //
  251. if ((ContextFrame->ContextFlags & CONTEXT_LOWER_FLOATING_POINT) == CONTEXT_LOWER_FLOATING_POINT) {
  252. //
  253. // Set EM + ia32 FP status
  254. //
  255. ContextFrame->StFPSR = TrapFrame->StFPSR;
  256. //
  257. // Set floating registers fs0 - fs19 from exception frame.
  258. //
  259. RtlCopyIa64FloatRegisterContext(&ContextFrame->FltS0,
  260. &ExceptionFrame->FltS0,
  261. sizeof(FLOAT128) * (4));
  262. RtlCopyIa64FloatRegisterContext(&ContextFrame->FltS4,
  263. &ExceptionFrame->FltS4,
  264. 16*sizeof(FLOAT128));
  265. //
  266. // Set floating registers ft0 - ft9 from trap frame.
  267. //
  268. RtlCopyIa64FloatRegisterContext(&ContextFrame->FltT0,
  269. &TrapFrame->FltT0,
  270. sizeof(FLOAT128) * (10));
  271. }
  272. if ((ContextFrame->ContextFlags & CONTEXT_HIGHER_FLOATING_POINT) == CONTEXT_HIGHER_FLOATING_POINT) {
  273. ContextFrame->StFPSR = TrapFrame->StFPSR;
  274. //
  275. // Set floating regs f32 - f127 from higher floating point save area
  276. //
  277. if (TrapFrame->PreviousMode == UserMode) {
  278. RtlCopyIa64FloatRegisterContext(
  279. &ContextFrame->FltF32,
  280. (PFLOAT128)GET_HIGH_FLOATING_POINT_REGISTER_SAVEAREA(KeGetCurrentThread()->StackBase),
  281. 96*sizeof(FLOAT128)
  282. );
  283. }
  284. }
  285. //
  286. // Get user debug registers from save area in kernel stack.
  287. // Note: PSR.db must be set to activate the debug registers.
  288. //
  289. if ((ContextFrame->ContextFlags & CONTEXT_DEBUG) == CONTEXT_DEBUG) {
  290. KiGetDebugContext(TrapFrame, ContextFrame);
  291. }
  292. return;
  293. }
  294. VOID
  295. KeContextToKframes (
  296. IN OUT PKTRAP_FRAME TrapFrame,
  297. IN OUT PKEXCEPTION_FRAME ExceptionFrame,
  298. IN PCONTEXT ContextFrame,
  299. IN ULONG ContextFlags,
  300. IN KPROCESSOR_MODE PreviousMode
  301. )
  302. /*++
  303. Routine Description:
  304. This routine moves the selected contents of the specified context frame into
  305. the specified trap and exception frames according to the specified context
  306. flags.
  307. Arguments:
  308. TrapFrame - Supplies a pointer to a trap frame that receives the volatile
  309. context from the context record.
  310. ExceptionFrame - Supplies a pointer to an exception frame that receives
  311. the nonvolatile context from the context record.
  312. ContextFrame - Supplies a pointer to a context frame that contains the
  313. context that is to be copied into the trap and exception frames.
  314. ContextFlags - Supplies the set of flags that specify which parts of the
  315. context frame are to be copied into the trap and exception frames.
  316. PreviousMode - Supplies the processor mode for which the trap and exception
  317. frames are being built.
  318. Return Value:
  319. None.
  320. --*/
  321. {
  322. USHORT R1Offset, R4Offset;
  323. USHORT RNatSaveIndex;
  324. SHORT BsFrameSize;
  325. SHORT TempFrameSize;
  326. //
  327. // Set control information if specified.
  328. //
  329. if ((ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL) {
  330. TrapFrame->IntGp = ContextFrame->IntGp;
  331. TrapFrame->IntSp = ContextFrame->IntSp;
  332. TrapFrame->ApUNAT = ContextFrame->ApUNAT;
  333. TrapFrame->BrRp = ContextFrame->BrRp;
  334. TrapFrame->ApCCV = ContextFrame->ApCCV;
  335. TrapFrame->ApDCR = SANITIZE_DCR(ContextFrame->ApDCR, PreviousMode);
  336. //
  337. // Set preserved applicaton registers in exception frame.
  338. //
  339. ExceptionFrame->ApLC = ContextFrame->ApLC;
  340. ExceptionFrame->ApEC &= ~((ULONGLONG)PFS_EC_MASK << PFS_EC_SHIFT);
  341. ExceptionFrame->ApEC |= ((ContextFrame->ApEC & PFS_EC_MASK) << PFS_EC_SHIFT);
  342. //
  343. // Set RSE control states in the trap frame.
  344. //
  345. TrapFrame->RsPFS = SANITIZE_PFS(ContextFrame->RsPFS, PreviousMode);
  346. BsFrameSize = (SHORT)(ContextFrame->StIFS & PFS_SIZE_MASK);
  347. RNatSaveIndex = (USHORT)((ContextFrame->RsBSP >> 3) & NAT_BITS_PER_RNAT_REG);
  348. TempFrameSize = RNatSaveIndex + BsFrameSize - NAT_BITS_PER_RNAT_REG;
  349. while (TempFrameSize >= 0) {
  350. BsFrameSize++;
  351. TempFrameSize -= NAT_BITS_PER_RNAT_REG;
  352. }
  353. TrapFrame->RsBSP = ContextFrame->RsBSP + BsFrameSize * 8;
  354. TrapFrame->RsBSPSTORE = TrapFrame->RsBSP;
  355. TrapFrame->RsRSC = ContextFrame->RsRSC;
  356. TrapFrame->RsRNAT = ContextFrame->RsRNAT;
  357. TrapFrame->EOFMarker = KTRAP_FRAME_EOF | EXCEPTION_FRAME;
  358. #if DEBUG
  359. DbgPrint("KeContextToKFrames: RsRNAT = 0x%I64x\n", TrapFrame->RsRNAT);
  360. #endif // DEBUG
  361. //
  362. // Set FPSR, IPSR, IIP, and IFS in the trap frame.
  363. //
  364. TrapFrame->StFPSR = SANITIZE_FSR(ContextFrame->StFPSR, PreviousMode);
  365. TrapFrame->StIPSR = SANITIZE_PSR(ContextFrame->StIPSR, PreviousMode);
  366. TrapFrame->StIFS = SANITIZE_IFS(ContextFrame->StIFS, PreviousMode);
  367. TrapFrame->StIIP = ContextFrame->StIIP;
  368. if (PreviousMode == UserMode ) {
  369. //
  370. // DebugActive controls h/w debug registers. Set if new psr.db = 1
  371. //
  372. PCR->DebugActive = KeGetCurrentThread()->DebugActive = ((TrapFrame->StIPSR & (1I64 << PSR_DB)) != 0);
  373. //
  374. // Set and sanitize iA status
  375. //
  376. __setReg(CV_IA64_AR21, SANITIZE_AR21_FCR (ContextFrame->StFCR, UserMode));
  377. __setReg(CV_IA64_AR24, SANITIZE_AR24_EFLAGS (ContextFrame->Eflag, UserMode));
  378. __setReg(CV_IA64_AR25, ContextFrame->SegCSD);
  379. __setReg(CV_IA64_AR26, ContextFrame->SegSSD);
  380. __setReg(CV_IA64_AR27, SANITIZE_AR27_CFLG (ContextFrame->Cflag, UserMode));
  381. __setReg(CV_IA64_AR28, SANITIZE_AR28_FSR (ContextFrame->StFSR, UserMode));
  382. __setReg(CV_IA64_AR29, SANITIZE_AR29_FIR (ContextFrame->StFIR, UserMode));
  383. __setReg(CV_IA64_AR30, SANITIZE_AR30_FDR (ContextFrame->StFDR, UserMode));
  384. }
  385. }
  386. //
  387. // Set integer registers contents if specified.
  388. //
  389. if ((ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER) {
  390. TrapFrame->IntT0 = ContextFrame->IntT0;
  391. TrapFrame->IntT1 = ContextFrame->IntT1;
  392. TrapFrame->IntT2 = ContextFrame->IntT2;
  393. TrapFrame->IntT3 = ContextFrame->IntT3;
  394. TrapFrame->IntT4 = ContextFrame->IntT4;
  395. TrapFrame->IntV0 = ContextFrame->IntV0;
  396. TrapFrame->IntTeb = ContextFrame->IntTeb;
  397. TrapFrame->Preds = ContextFrame->Preds;
  398. //
  399. // t5 - t22
  400. //
  401. memcpy(&TrapFrame->IntT5, &ContextFrame->IntT5, 18*sizeof(ULONGLONG));
  402. //
  403. // Set integer registers s0 - s3 in exception frame.
  404. //
  405. ExceptionFrame->IntS0 = ContextFrame->IntS0;
  406. ExceptionFrame->IntS1 = ContextFrame->IntS1;
  407. ExceptionFrame->IntS2 = ContextFrame->IntS2;
  408. ExceptionFrame->IntS3 = ContextFrame->IntS3;
  409. //
  410. // Set the integer nats field in the trap & exception frames
  411. //
  412. R1Offset = (USHORT)((ULONG_PTR)(&TrapFrame->IntGp) >> 3) & 0x3f;
  413. R4Offset = (USHORT)((ULONG_PTR)(&ExceptionFrame->IntS0) >> 3) & 0x3f;
  414. EXTRACT_NATS(TrapFrame->IntNats, ContextFrame->IntNats,
  415. 1, R1Offset, 0xFFFFFF0E);
  416. EXTRACT_NATS(ExceptionFrame->IntNats, ContextFrame->IntNats,
  417. 4, R4Offset, 0xF0);
  418. #if DEBUG
  419. DbgPrint("KeContextToKFrames: TF->IntNats = 0x%I64x, ContestFrame->IntNats = 0x%I64x, R1OffSet = 0x%x\n",
  420. TrapFrame->IntNats, ContextFrame->IntNats, R1Offset);
  421. DbgPrint("KeContextToKFrames: EF->IntNats = 0x%I64x, R4OffSet = 0x%x\n",
  422. ExceptionFrame->IntNats, R4Offset);
  423. #endif // DEBUG
  424. //
  425. // Set other branch registers in trap and exception frames
  426. //
  427. TrapFrame->BrT0 = ContextFrame->BrT0;
  428. TrapFrame->BrT1 = ContextFrame->BrT1;
  429. memcpy(&ExceptionFrame->BrS0, &ContextFrame->BrS0, 5*sizeof(ULONGLONG));
  430. }
  431. //
  432. // Set lower floating register contents if specified.
  433. //
  434. if ((ContextFlags & CONTEXT_LOWER_FLOATING_POINT) == CONTEXT_LOWER_FLOATING_POINT) {
  435. TrapFrame->StFPSR = SANITIZE_FSR(ContextFrame->StFPSR, PreviousMode);
  436. //
  437. // Set floating registers fs0 - fs19 in exception frame.
  438. //
  439. RtlCopyIa64FloatRegisterContext(&ExceptionFrame->FltS0,
  440. &ContextFrame->FltS0,
  441. sizeof(FLOAT128) * (4));
  442. RtlCopyIa64FloatRegisterContext(&ExceptionFrame->FltS4,
  443. &ContextFrame->FltS4,
  444. 16*sizeof(FLOAT128));
  445. //
  446. // Set floating registers ft0 - ft9 in trap frame.
  447. //
  448. RtlCopyIa64FloatRegisterContext(&TrapFrame->FltT0,
  449. &ContextFrame->FltT0,
  450. sizeof(FLOAT128) * (10));
  451. }
  452. //
  453. // Set higher floating register contents if specified.
  454. //
  455. if ((ContextFlags & CONTEXT_HIGHER_FLOATING_POINT) == CONTEXT_HIGHER_FLOATING_POINT) {
  456. TrapFrame->StFPSR = SANITIZE_FSR(ContextFrame->StFPSR, PreviousMode);
  457. if (PreviousMode == UserMode) {
  458. //
  459. // Update the higher floating point save area (f32-f127) and
  460. // set the corresponding modified bit in the PSR to 1.
  461. //
  462. RtlCopyIa64FloatRegisterContext(
  463. (PFLOAT128)GET_HIGH_FLOATING_POINT_REGISTER_SAVEAREA(KeGetCurrentThread()->StackBase),
  464. &ContextFrame->FltF32,
  465. 96*sizeof(FLOAT128)
  466. );
  467. TrapFrame->StIPSR |= (1i64 << PSR_DFH);
  468. TrapFrame->StIPSR &= ~(1i64 << PSR_MFH);
  469. }
  470. }
  471. //
  472. // Set debug registers.
  473. //
  474. if ((ContextFlags & CONTEXT_DEBUG) == CONTEXT_DEBUG) {
  475. KiSetDebugContext (TrapFrame, ContextFrame, PreviousMode);
  476. }
  477. return;
  478. }
  479. NTSTATUS
  480. KeFlushUserRseState (
  481. IN PKTRAP_FRAME TrapFrame
  482. )
  483. /*++
  484. Routine Description:
  485. This routine flushes the user rse state from the kernel backing store to the
  486. user backing store. The user context frame is update to reflect the new
  487. context state.
  488. Arguments:
  489. TrapFrame - Supplies a pointer to a trap frame.
  490. Return Value:
  491. None.
  492. --*/
  493. {
  494. SHORT BsFrameSize;
  495. SHORT RNatSaveIndex;
  496. SHORT Temp;
  497. USHORT TearPointOffset;
  498. ULONGLONG TopBound, BottomBound;
  499. ULONGLONG UserRnats1, UserRnats2;
  500. ULONGLONG Mask;
  501. ULONGLONG BspStoreReal;
  502. NTSTATUS Status = STATUS_SUCCESS;
  503. //
  504. // Copy user stacked registers' contents to user backing store.
  505. // N.B. Stack overflow could happen.
  506. //
  507. try {
  508. //
  509. // The RsBSPSTORE value may be incorrect paritcularly if the kernel debugger
  510. // done a set context on the thread, but the dirty register count in RSE is
  511. // correct.
  512. //
  513. BsFrameSize = (SHORT) (TrapFrame->RsRSC >> RSC_MBZ1);
  514. BspStoreReal = TrapFrame->RsBSP - BsFrameSize;
  515. if (BsFrameSize) {
  516. ULONGLONG Bsp, Rnat, KernelInitBsp;
  517. //
  518. // Copy the dirty stacked registers back into the
  519. // user backing store
  520. //
  521. RtlpFlushRSE(&Bsp, &Rnat);
  522. TearPointOffset = (USHORT) BspStoreReal & 0x1F8;
  523. KernelInitBsp= (PCR->InitialBStore | TearPointOffset) + BsFrameSize - 8;
  524. if ((KernelInitBsp | RNAT_ALIGNMENT) != ((Bsp - 8) | RNAT_ALIGNMENT)) {
  525. Rnat = *(PULONGLONG)(KernelInitBsp | RNAT_ALIGNMENT);
  526. }
  527. RtlCopyMemory((PVOID)(BspStoreReal),
  528. (PVOID)(PCR->InitialBStore + TearPointOffset),
  529. BsFrameSize);
  530. TopBound = (TrapFrame->RsBSP - 8) | RNAT_ALIGNMENT;
  531. BottomBound = BspStoreReal | RNAT_ALIGNMENT;
  532. RNatSaveIndex = TearPointOffset >> 3;
  533. Mask = (((1ULL << (NAT_BITS_PER_RNAT_REG - RNatSaveIndex)) - 1) << RNatSaveIndex);
  534. UserRnats1 = TrapFrame->RsRNAT & ((1ULL << RNatSaveIndex) - 1);
  535. if (TopBound > BottomBound) {
  536. //
  537. // user dirty stacked GR span across at least one RNAT
  538. // boundary; need to deposit the valid RNAT bits from
  539. // the trap frame into the kernel backing store. Also,
  540. // the RNAT field in the trap frame has to be updated.
  541. //
  542. UserRnats2 = *(PULONGLONG)BottomBound & Mask;
  543. *(PULONGLONG)BottomBound = UserRnats1 | UserRnats2;
  544. TrapFrame->RsRNAT = Rnat;
  545. #if DEBUG
  546. DbgPrint("KiFlushUserRseState 1: UserRnats1 = 0x%I64x, UserRnats2 = 0x%I64x, TF->RsRNAT = 0x%I64x\n",
  547. UserRnats1, UserRnats2, TrapFrame->RsRNAT);
  548. #endif // DEBUG
  549. } else {
  550. //
  551. // user stacked register region does not span across an
  552. // RNAT boundary; combine the RNAT fields from both the
  553. // trap frame and the context frame.
  554. //
  555. UserRnats2 = Rnat & Mask;
  556. TrapFrame->RsRNAT = UserRnats1 | UserRnats2;
  557. #if DEBUG
  558. DbgPrint("KiFlushUserRseState 2: UserRnats1 = 0x%I64x, UserRnats2 = 0x%I64x, TF->RsRNAT = 0x%I64x\n",
  559. UserRnats1, UserRnats2, TrapFrame->RsRNAT);
  560. #endif // DEBUG
  561. }
  562. }
  563. //
  564. // Successfully copied to user backing store; set the user's
  565. // bspstore to the value of its own bsp.
  566. // And Zero the loadrs field of RsRSC.
  567. //
  568. TrapFrame->RsBSPSTORE = TrapFrame->RsBSP;
  569. TrapFrame->RsRSC = ZERO_PRELOAD_SIZE(TrapFrame->RsRSC);
  570. } except (KeFlushRseExceptionFilter(GetExceptionInformation(), &Status)) {
  571. }
  572. return Status;
  573. }
  574. VOID
  575. KeContextToKframesSpecial (
  576. IN PKTHREAD Thread,
  577. IN OUT PKTRAP_FRAME TrapFrame,
  578. IN OUT PKEXCEPTION_FRAME ExceptionFrame,
  579. IN PCONTEXT ContextFrame,
  580. IN ULONG ContextFlags
  581. )
  582. /*++
  583. Routine Description:
  584. This routine moves the selected contents of the specified context frame into
  585. the specified trap and exception frames according to the specified context
  586. flags.
  587. Arguments:
  588. TrapFrame - Supplies a pointer to a trap frame that receives the volatile
  589. context from the context record.
  590. ExceptionFrame - Supplies a pointer to an exception frame that receives
  591. the nonvolatile context from the context record.
  592. ContextFrame - Supplies a pointer to a context frame that contains the
  593. context that is to be copied into the trap and exception frames.
  594. ContextFlags - Supplies the set of flags that specify which parts of the
  595. context frame are to be copied into the trap and exception frames.
  596. PreviousMode - Supplies the processor mode for which the trap and exception
  597. frames are being built.
  598. Return Value:
  599. None.
  600. --*/
  601. {
  602. USHORT R1Offset, R4Offset;
  603. USHORT RNatSaveIndex;
  604. SHORT BsFrameSize;
  605. SHORT TempFrameSize;
  606. //
  607. // Set control information if specified.
  608. //
  609. if ((ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL) {
  610. TrapFrame->IntGp = ContextFrame->IntGp;
  611. TrapFrame->IntSp = ContextFrame->IntSp;
  612. TrapFrame->ApUNAT = ContextFrame->ApUNAT;
  613. TrapFrame->BrRp = ContextFrame->BrRp;
  614. TrapFrame->ApCCV = ContextFrame->ApCCV;
  615. TrapFrame->ApDCR = SANITIZE_DCR(ContextFrame->ApDCR, UserMode);
  616. //
  617. // Set preserved applicaton registers in exception frame.
  618. //
  619. ExceptionFrame->ApLC = ContextFrame->ApLC;
  620. ExceptionFrame->ApEC &= ~((ULONGLONG)PFS_EC_MASK << PFS_EC_SHIFT);
  621. ExceptionFrame->ApEC |= ((ContextFrame->ApEC & PFS_EC_MASK) << PFS_EC_SHIFT);
  622. //
  623. // Set RSE control states in the trap frame.
  624. //
  625. TrapFrame->RsPFS = ContextFrame->RsPFS;
  626. BsFrameSize = (SHORT)(ContextFrame->StIFS & PFS_SIZE_MASK);
  627. RNatSaveIndex = (USHORT)((ContextFrame->RsBSP >> 3) & NAT_BITS_PER_RNAT_REG);
  628. TempFrameSize = RNatSaveIndex + BsFrameSize - NAT_BITS_PER_RNAT_REG;
  629. while (TempFrameSize >= 0) {
  630. BsFrameSize++;
  631. TempFrameSize -= NAT_BITS_PER_RNAT_REG;
  632. }
  633. TrapFrame->RsBSP = ContextFrame->RsBSP + BsFrameSize * 8;
  634. TrapFrame->RsBSPSTORE = TrapFrame->RsBSP;
  635. TrapFrame->RsRSC = ContextFrame->RsRSC;
  636. TrapFrame->RsRNAT = ContextFrame->RsRNAT;
  637. #if DEBUG
  638. DbgPrint("KeContextToKFrames: RsRNAT = 0x%I64x\n", TrapFrame->RsRNAT);
  639. #endif // DEBUG
  640. //
  641. // Set FPSR, IPSR, IIP, and IFS in the trap frame.
  642. //
  643. TrapFrame->StFPSR = SANITIZE_FSR(ContextFrame->StFPSR, UserMode);
  644. TrapFrame->StIPSR = SANITIZE_PSR(ContextFrame->StIPSR, UserMode);
  645. TrapFrame->StIFS = SANITIZE_IFS(ContextFrame->StIFS, UserMode);
  646. TrapFrame->StIIP = ContextFrame->StIIP;
  647. //
  648. // Set application registers directly
  649. //
  650. if (Thread == KeGetCurrentThread()) {
  651. //
  652. // Set and sanitize iA status
  653. //
  654. __setReg(CV_IA64_AR21, SANITIZE_AR21_FCR (ContextFrame->StFCR, UserMode));
  655. __setReg(CV_IA64_AR24, SANITIZE_AR24_EFLAGS (ContextFrame->Eflag, UserMode));
  656. __setReg(CV_IA64_AR25, ContextFrame->SegCSD);
  657. __setReg(CV_IA64_AR26, ContextFrame->SegSSD);
  658. __setReg(CV_IA64_AR27, SANITIZE_AR27_CFLG (ContextFrame->Cflag, UserMode));
  659. __setReg(CV_IA64_AR28, SANITIZE_AR28_FSR (ContextFrame->StFSR, UserMode));
  660. __setReg(CV_IA64_AR29, SANITIZE_AR29_FIR (ContextFrame->StFIR, UserMode));
  661. __setReg(CV_IA64_AR30, SANITIZE_AR30_FDR (ContextFrame->StFDR, UserMode));
  662. } else {
  663. PKAPPLICATION_REGISTERS AppRegs;
  664. AppRegs = GET_APPLICATION_REGISTER_SAVEAREA(Thread->StackBase);
  665. AppRegs->Ar21 = SANITIZE_AR21_FCR (ContextFrame->StFCR, UserMode);
  666. AppRegs->Ar24 = SANITIZE_AR24_EFLAGS (ContextFrame->Eflag, UserMode);
  667. AppRegs->Ar25 = ContextFrame->SegCSD;
  668. AppRegs->Ar26 = ContextFrame->SegSSD;
  669. AppRegs->Ar27 = SANITIZE_AR27_CFLG (ContextFrame->Cflag, UserMode);
  670. AppRegs->Ar28 = SANITIZE_AR28_FSR (ContextFrame->StFSR, UserMode);
  671. AppRegs->Ar29 = SANITIZE_AR29_FIR (ContextFrame->StFIR, UserMode);
  672. AppRegs->Ar30 = SANITIZE_AR30_FDR (ContextFrame->StFDR, UserMode);
  673. }
  674. }
  675. //
  676. // Set integer registers contents if specified.
  677. //
  678. if ((ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER) {
  679. TrapFrame->IntT0 = ContextFrame->IntT0;
  680. TrapFrame->IntT1 = ContextFrame->IntT1;
  681. TrapFrame->IntT2 = ContextFrame->IntT2;
  682. TrapFrame->IntT3 = ContextFrame->IntT3;
  683. TrapFrame->IntT4 = ContextFrame->IntT4;
  684. TrapFrame->IntV0 = ContextFrame->IntV0;
  685. TrapFrame->IntTeb = ContextFrame->IntTeb;
  686. TrapFrame->Preds = ContextFrame->Preds;
  687. //
  688. // t5 - t22
  689. //
  690. memcpy(&TrapFrame->IntT5, &ContextFrame->IntT5, 18*sizeof(ULONGLONG));
  691. //
  692. // Set integer registers s0 - s3 in exception frame.
  693. //
  694. ExceptionFrame->IntS0 = ContextFrame->IntS0;
  695. ExceptionFrame->IntS1 = ContextFrame->IntS1;
  696. ExceptionFrame->IntS2 = ContextFrame->IntS2;
  697. ExceptionFrame->IntS3 = ContextFrame->IntS3;
  698. //
  699. // Set the integer nats field in the trap & exception frames
  700. //
  701. R1Offset = (USHORT)((ULONG_PTR)(&TrapFrame->IntGp) >> 3) & 0x3f;
  702. R4Offset = (USHORT)((ULONG_PTR)(&ExceptionFrame->IntS0) >> 3) & 0x3f;
  703. EXTRACT_NATS(TrapFrame->IntNats, ContextFrame->IntNats,
  704. 1, R1Offset, 0xFFFFFF0E);
  705. EXTRACT_NATS(ExceptionFrame->IntNats, ContextFrame->IntNats,
  706. 4, R4Offset, 0xF0);
  707. #if DEBUG
  708. DbgPrint("KeContextToKFrames: TF->IntNats = 0x%I64x, ContestFrame->IntNats = 0x%I64x, R1OffSet = 0x%x\n",
  709. TrapFrame->IntNats, ContextFrame->IntNats, R1Offset);
  710. DbgPrint("KeContextToKFrames: EF->IntNats = 0x%I64x, R4OffSet = 0x%x\n",
  711. ExceptionFrame->IntNats, R4Offset);
  712. #endif // DEBUG
  713. //
  714. // Set other branch registers in trap and exception frames
  715. //
  716. TrapFrame->BrT0 = ContextFrame->BrT0;
  717. TrapFrame->BrT1 = ContextFrame->BrT1;
  718. memcpy(&ExceptionFrame->BrS0, &ContextFrame->BrS0, 5*sizeof(ULONGLONG));
  719. }
  720. //
  721. // Set lower floating register contents if specified.
  722. //
  723. if ((ContextFlags & CONTEXT_LOWER_FLOATING_POINT) == CONTEXT_LOWER_FLOATING_POINT) {
  724. TrapFrame->StFPSR = SANITIZE_FSR(ContextFrame->StFPSR, UserMode);
  725. //
  726. // Set floating registers fs0 - fs19 in exception frame.
  727. //
  728. RtlCopyIa64FloatRegisterContext(&ExceptionFrame->FltS0,
  729. &ContextFrame->FltS0,
  730. sizeof(FLOAT128) * (4));
  731. RtlCopyIa64FloatRegisterContext(&ExceptionFrame->FltS4,
  732. &ContextFrame->FltS4,
  733. 16*sizeof(FLOAT128));
  734. //
  735. // Set floating registers ft0 - ft9 in trap frame.
  736. //
  737. RtlCopyIa64FloatRegisterContext(&TrapFrame->FltT0,
  738. &ContextFrame->FltT0,
  739. sizeof(FLOAT128) * (10));
  740. }
  741. //
  742. // Set higher floating register contents if specified.
  743. //
  744. if ((ContextFlags & CONTEXT_HIGHER_FLOATING_POINT) == CONTEXT_HIGHER_FLOATING_POINT) {
  745. TrapFrame->StFPSR = SANITIZE_FSR(ContextFrame->StFPSR, UserMode);
  746. //
  747. // Update the higher floating point save area (f32-f127) and
  748. // set the corresponding modified bit in the PSR to 1.
  749. //
  750. RtlCopyIa64FloatRegisterContext(
  751. (PFLOAT128)GET_HIGH_FLOATING_POINT_REGISTER_SAVEAREA(Thread->StackBase),
  752. &ContextFrame->FltF32,
  753. 96*sizeof(FLOAT128)
  754. );
  755. TrapFrame->StIPSR |= (1i64 << PSR_DFH);
  756. TrapFrame->StIPSR &= ~(1i64 << PSR_MFH);
  757. }
  758. //
  759. // Set debug registers.
  760. //
  761. if ((ContextFlags & CONTEXT_DEBUG) == CONTEXT_DEBUG) {
  762. KiSetDebugContext (TrapFrame, ContextFrame, UserMode);
  763. }
  764. return;
  765. }