]> git.proxmox.com Git - mirror_edk2.git/commitdiff
UefiCpuPkg: Add a 16-bit protected mode code segment descriptor
authorTom Lendacky <thomas.lendacky@amd.com>
Wed, 12 Aug 2020 20:21:42 +0000 (15:21 -0500)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Mon, 17 Aug 2020 02:46:39 +0000 (02:46 +0000)
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2198

A hypervisor is not allowed to update an SEV-ES guests register state,
so when booting an SEV-ES guest AP, the hypervisor is not allowed to
set the RIP to the guest requested value. Instead, an SEV-ES AP must be
transition from 64-bit long mode to 16-bit real mode in response to an
INIT-SIPI-SIPI sequence. This requires a 16-bit code segment descriptor.
For PEI, create this descriptor in the reset vector GDT table. For DXE,
create this descriptor from the newly reserved entry at location 0x28.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
UefiCpuPkg/CpuDxe/CpuGdt.c
UefiCpuPkg/CpuDxe/CpuGdt.h
UefiCpuPkg/ResetVector/Vtf0/Ia16/Real16ToFlat32.asm

index 64efadeba60141fc5f2146f7943672c8901c712a..a1ab543f2da571e66b548a8f3c80713e34fed31a 100644 (file)
@@ -70,14 +70,14 @@ STATIC GDT_ENTRIES GdtTemplate = {
     0x0,\r
   },\r
   //\r
-  // SPARE4_SEL\r
+  // SYS_CODE16_SEL\r
   //\r
   {\r
-    0x0,            // limit 15:0\r
+    0x0FFFF,        // limit 15:0\r
     0x0,            // base 15:0\r
     0x0,            // base 23:16\r
-    0x0,            // type\r
-    0x0,            // limit 19:16, flags\r
+    0x09A,          // present, ring 0, code, execute/read\r
+    0x08F,          // page-granular, 16-bit\r
     0x0,            // base 31:24\r
   },\r
   //\r
index 3a0210b2f172d3426119c6f5f1c583e60c25355b..1c94487cbee8a36986c71fc0141d0e6750f4cab9 100644 (file)
@@ -36,7 +36,7 @@ struct _GDT_ENTRIES {
   GDT_ENTRY LinearCode;\r
   GDT_ENTRY SysData;\r
   GDT_ENTRY SysCode;\r
-  GDT_ENTRY Spare4;\r
+  GDT_ENTRY SysCode16;\r
   GDT_ENTRY LinearData64;\r
   GDT_ENTRY LinearCode64;\r
   GDT_ENTRY Spare5;\r
@@ -49,7 +49,7 @@ struct _GDT_ENTRIES {
 #define LINEAR_CODE_SEL   OFFSET_OF (GDT_ENTRIES, LinearCode)\r
 #define SYS_DATA_SEL      OFFSET_OF (GDT_ENTRIES, SysData)\r
 #define SYS_CODE_SEL      OFFSET_OF (GDT_ENTRIES, SysCode)\r
-#define SPARE4_SEL        OFFSET_OF (GDT_ENTRIES, Spare4)\r
+#define SYS_CODE16_SEL    OFFSET_OF (GDT_ENTRIES, SysCode16)\r
 #define LINEAR_DATA64_SEL OFFSET_OF (GDT_ENTRIES, LinearData64)\r
 #define LINEAR_CODE64_SEL OFFSET_OF (GDT_ENTRIES, LinearCode64)\r
 #define SPARE5_SEL        OFFSET_OF (GDT_ENTRIES, Spare5)\r
index ce4ebfffb688e06e67488246e585cf4c1e9015af..0e79a3984b168fa435e4186e046eb5451a58dac2 100644 (file)
@@ -129,5 +129,14 @@ LINEAR_CODE64_SEL   equ $-GDT_BASE
     DB      0            ; base 31:24\r
 %endif\r
 \r
+; linear code segment descriptor\r
+LINEAR_CODE16_SEL     equ $-GDT_BASE\r
+    DW      0xffff       ; limit 15:0\r
+    DW      0            ; base 15:0\r
+    DB      0            ; base 23:16\r
+    DB      PRESENT_FLAG(1)|DPL(0)|SYSTEM_FLAG(1)|DESC_TYPE(CODE32_TYPE)\r
+    DB      GRANULARITY_FLAG(1)|DEFAULT_SIZE32(0)|CODE64_FLAG(0)|UPPER_LIMIT(0xf)\r
+    DB      0            ; base 31:24\r
+\r
 GDT_END:\r
 \r