UefiCpuPkg/PiSmmCpuDxeSmm: patch "gSmiStack" with PatchInstructionX86()
[mirror_edk2.git] / UefiCpuPkg / PiSmmCpuDxeSmm / SmramSaveState.c
index 539c0294cd6ee4573c856caf67b0bcbc0b3148ac..f0c289254330d3949a0f00dcd3fcc98818c13b9f 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
 Provides services to access SMRAM Save State Map\r
 \r
-Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -23,6 +23,34 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Register/Cpuid.h>\r
 #include <Register/SmramSaveStateMap.h>\r
 \r
+#include "PiSmmCpuDxeSmm.h"\r
+\r
+typedef struct {\r
+  UINT64                            Signature;              // Offset 0x00\r
+  UINT16                            Reserved1;              // Offset 0x08\r
+  UINT16                            Reserved2;              // Offset 0x0A\r
+  UINT16                            Reserved3;              // Offset 0x0C\r
+  UINT16                            SmmCs;                  // Offset 0x0E\r
+  UINT16                            SmmDs;                  // Offset 0x10\r
+  UINT16                            SmmSs;                  // Offset 0x12\r
+  UINT16                            SmmOtherSegment;        // Offset 0x14\r
+  UINT16                            Reserved4;              // Offset 0x16\r
+  UINT64                            Reserved5;              // Offset 0x18\r
+  UINT64                            Reserved6;              // Offset 0x20\r
+  UINT64                            Reserved7;              // Offset 0x28\r
+  UINT64                            SmmGdtPtr;              // Offset 0x30\r
+  UINT32                            SmmGdtSize;             // Offset 0x38\r
+  UINT32                            Reserved8;              // Offset 0x3C\r
+  UINT64                            Reserved9;              // Offset 0x40\r
+  UINT64                            Reserved10;             // Offset 0x48\r
+  UINT16                            Reserved11;             // Offset 0x50\r
+  UINT16                            Reserved12;             // Offset 0x52\r
+  UINT32                            Reserved13;             // Offset 0x54\r
+  UINT64                            Reserved14;             // Offset 0x58\r
+} PROCESSOR_SMM_DESCRIPTOR;\r
+\r
+extern CONST PROCESSOR_SMM_DESCRIPTOR      gcPsd;\r
+\r
 //\r
 // EFER register LMA bit\r
 //\r
@@ -77,11 +105,11 @@ typedef struct {
 ///\r
 /// Variables from SMI Handler\r
 ///\r
-extern UINT32           gSmbase;\r
-extern volatile UINT32  gSmiStack;\r
-extern UINT32           gSmiCr3;\r
-extern volatile UINT8   gcSmiHandlerTemplate[];\r
-extern CONST UINT16     gcSmiHandlerSize;\r
+X86_ASSEMBLY_PATCH_LABEL gPatchSmbase;\r
+X86_ASSEMBLY_PATCH_LABEL gPatchSmiStack;\r
+extern UINT32            gSmiCr3;\r
+extern volatile UINT8    gcSmiHandlerTemplate[];\r
+extern CONST UINT16      gcSmiHandlerSize;\r
 \r
 //\r
 // Variables used by SMI Handler\r
@@ -657,6 +685,17 @@ InstallSmiHandler (
   IN UINT32  Cr3\r
   )\r
 {\r
+  PROCESSOR_SMM_DESCRIPTOR  *Psd;\r
+  UINT32                    CpuSmiStack;\r
+\r
+  //\r
+  // Initialize PROCESSOR_SMM_DESCRIPTOR\r
+  //\r
+  Psd = (PROCESSOR_SMM_DESCRIPTOR *)(VOID *)((UINTN)SmBase + SMM_PSD_OFFSET);\r
+  CopyMem (Psd, &gcPsd, sizeof (gcPsd));\r
+  Psd->SmmGdtPtr = (UINT64)GdtBase;\r
+  Psd->SmmGdtSize = (UINT32)GdtSize;\r
+\r
   if (SmmCpuFeaturesGetSmiHandlerSize () != 0) {\r
     //\r
     // Install SMI handler provided by library\r
@@ -678,22 +717,23 @@ InstallSmiHandler (
   //\r
   // Initialize values in template before copy\r
   //\r
-  gSmiStack             = (UINT32)((UINTN)SmiStack + StackSize - sizeof (UINTN));\r
+  CpuSmiStack = (UINT32)((UINTN)SmiStack + StackSize - sizeof (UINTN));\r
+  PatchInstructionX86 (gPatchSmiStack, CpuSmiStack, 4);\r
   gSmiCr3               = Cr3;\r
-  gSmbase               = SmBase;\r
+  PatchInstructionX86 (gPatchSmbase, SmBase, 4);\r
   gSmiHandlerIdtr.Base  = IdtBase;\r
   gSmiHandlerIdtr.Limit = (UINT16)(IdtSize - 1);\r
 \r
   //\r
   // Set the value at the top of the CPU stack to the CPU Index\r
   //\r
-  *(UINTN*)(UINTN)gSmiStack = CpuIndex;\r
+  *(UINTN*)(UINTN)CpuSmiStack = CpuIndex;\r
 \r
   //\r
   // Copy template to CPU specific SMI handler location\r
   //\r
   CopyMem (\r
-    (VOID*)(UINTN)(SmBase + SMM_HANDLER_OFFSET),\r
+    (VOID*)((UINTN)SmBase + SMM_HANDLER_OFFSET),\r
     (VOID*)gcSmiHandlerTemplate,\r
     gcSmiHandlerSize\r
     );\r