UefiCpuPkg/MpLib: Add GDTR, IDTR and TR in saved AP data
authorJian J Wang <jian.j.wang@intel.com>
Thu, 7 Dec 2017 12:16:29 +0000 (20:16 +0800)
committerStar Zeng <star.zeng@intel.com>
Fri, 8 Dec 2017 06:38:50 +0000 (14:38 +0800)
In current implementation of CPU MP service, AP is initialized with data
copied from BSP. Stack switch required by Stack Guard feature needs different
GDT, IDT table and task gates for each logic processor. This patch adds GDTR,
IDTR and TR into structure CPU_VOLATILE_REGISTERS and related code in save
and restore methods. This can make sure that any changes to GDT, IDT and task
gate for an AP will be kept from overwritten by BSP settings.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Suggested-by: Ayellet Wolman <ayellet.wolman@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Jian J Wang <jian.j.wang@intel.com>
Reviewed-by: Jeff Fan <vanjeff_919@hotmail.com>
Reviewed-by: Jiewen.yao@intel.com
UefiCpuPkg/Library/MpInitLib/MpLib.c
UefiCpuPkg/Library/MpInitLib/MpLib.h

index 61b14c98438e85544ed63700923144f0b41d18e5..0c2058a7b0db7e340e2e23a07e844d6fafe444a6 100644 (file)
@@ -195,6 +195,10 @@ SaveVolatileRegisters (
     VolatileRegisters->Dr6 = AsmReadDr6 ();\r
     VolatileRegisters->Dr7 = AsmReadDr7 ();\r
   }\r
+\r
+  AsmReadGdtr (&VolatileRegisters->Gdtr);\r
+  AsmReadIdtr (&VolatileRegisters->Idtr);\r
+  VolatileRegisters->Tr = AsmReadTr ();\r
 }\r
 \r
 /**\r
@@ -211,6 +215,7 @@ RestoreVolatileRegisters (
   )\r
 {\r
   CPUID_VERSION_INFO_EDX        VersionInfoEdx;\r
+  IA32_TSS_DESCRIPTOR           *Tss;\r
 \r
   AsmWriteCr0 (VolatileRegisters->Cr0);\r
   AsmWriteCr3 (VolatileRegisters->Cr3);\r
@@ -231,6 +236,18 @@ RestoreVolatileRegisters (
       AsmWriteDr7 (VolatileRegisters->Dr7);\r
     }\r
   }\r
+\r
+  AsmWriteGdtr (&VolatileRegisters->Gdtr);\r
+  AsmWriteIdtr (&VolatileRegisters->Idtr);\r
+  if (VolatileRegisters->Tr != 0 &&\r
+      VolatileRegisters->Tr < VolatileRegisters->Gdtr.Limit) {\r
+    Tss = (IA32_TSS_DESCRIPTOR *)(VolatileRegisters->Gdtr.Base +\r
+                                  VolatileRegisters->Tr);\r
+    if (Tss->Bits.P == 1) {\r
+      Tss->Bits.Type &= 0xD;  // 1101 - Clear busy bit just in case\r
+      AsmWriteTr (VolatileRegisters->Tr);\r
+    }\r
+  }\r
 }\r
 \r
 /**\r
index d13d5c06f59dd3bc03f8a10baf429209cb18ba98..685e96cbac45f694ad7e03600da5a828338b3773 100644 (file)
@@ -102,6 +102,9 @@ typedef struct {
   UINTN                          Dr3;\r
   UINTN                          Dr6;\r
   UINTN                          Dr7;\r
+  IA32_DESCRIPTOR                Gdtr;\r
+  IA32_DESCRIPTOR                Idtr;\r
+  UINT16                         Tr;\r
 } CPU_VOLATILE_REGISTERS;\r
 \r
 //\r