[edk2] [PATCH v2 6/8] UefiCpuPkg/MpLib: Add GDTR, IDTR and TR in saved AP data

Jian J Wang posted 8 patches 7 years, 1 month ago
There is a newer version of this series
[edk2] [PATCH v2 6/8] UefiCpuPkg/MpLib: Add GDTR, IDTR and TR in saved AP data
Posted by Jian J Wang 7 years, 1 month ago
> v2:
>    Add code to save/restore GDTR, IDTR and TR for AP.

In current implementation of CPU MP, 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 save/restore methods. This will
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>
---
 UefiCpuPkg/Library/MpInitLib/MpLib.c | 17 +++++++++++++++++
 UefiCpuPkg/Library/MpInitLib/MpLib.h |  3 +++
 2 files changed, 20 insertions(+)

diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c
index 61b14c9843..0c2058a7b0 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c
@@ -195,6 +195,10 @@ SaveVolatileRegisters (
     VolatileRegisters->Dr6 = AsmReadDr6 ();
     VolatileRegisters->Dr7 = AsmReadDr7 ();
   }
+
+  AsmReadGdtr (&VolatileRegisters->Gdtr);
+  AsmReadIdtr (&VolatileRegisters->Idtr);
+  VolatileRegisters->Tr = AsmReadTr ();
 }
 
 /**
@@ -211,6 +215,7 @@ RestoreVolatileRegisters (
   )
 {
   CPUID_VERSION_INFO_EDX        VersionInfoEdx;
+  IA32_TSS_DESCRIPTOR           *Tss;
 
   AsmWriteCr0 (VolatileRegisters->Cr0);
   AsmWriteCr3 (VolatileRegisters->Cr3);
@@ -231,6 +236,18 @@ RestoreVolatileRegisters (
       AsmWriteDr7 (VolatileRegisters->Dr7);
     }
   }
+
+  AsmWriteGdtr (&VolatileRegisters->Gdtr);
+  AsmWriteIdtr (&VolatileRegisters->Idtr);
+  if (VolatileRegisters->Tr != 0 &&
+      VolatileRegisters->Tr < VolatileRegisters->Gdtr.Limit) {
+    Tss = (IA32_TSS_DESCRIPTOR *)(VolatileRegisters->Gdtr.Base +
+                                  VolatileRegisters->Tr);
+    if (Tss->Bits.P == 1) {
+      Tss->Bits.Type &= 0xD;  // 1101 - Clear busy bit just in case
+      AsmWriteTr (VolatileRegisters->Tr);
+    }
+  }
 }
 
 /**
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h
index d13d5c06f5..685e96cbac 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.h
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h
@@ -102,6 +102,9 @@ typedef struct {
   UINTN                          Dr3;
   UINTN                          Dr6;
   UINTN                          Dr7;
+  IA32_DESCRIPTOR                Gdtr;
+  IA32_DESCRIPTOR                Idtr;
+  UINT16                         Tr;
 } CPU_VOLATILE_REGISTERS;
 
 //
-- 
2.14.1.windows.1

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel