UefiCpuPkg: Add a 16-bit protected mode code segment descriptor

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>
This commit is contained in:
Tom Lendacky 2020-08-12 15:21:42 -05:00 committed by mergify[bot]
parent 437eb3f7a8
commit 0d7601e546
3 changed files with 15 additions and 6 deletions

View File

@ -70,14 +70,14 @@ STATIC GDT_ENTRIES GdtTemplate = {
0x0, 0x0,
}, },
// //
// SPARE4_SEL // SYS_CODE16_SEL
// //
{ {
0x0, // limit 15:0 0x0FFFF, // limit 15:0
0x0, // base 15:0 0x0, // base 15:0
0x0, // base 23:16 0x0, // base 23:16
0x0, // type 0x09A, // present, ring 0, code, execute/read
0x0, // limit 19:16, flags 0x08F, // page-granular, 16-bit
0x0, // base 31:24 0x0, // base 31:24
}, },
// //

View File

@ -36,7 +36,7 @@ struct _GDT_ENTRIES {
GDT_ENTRY LinearCode; GDT_ENTRY LinearCode;
GDT_ENTRY SysData; GDT_ENTRY SysData;
GDT_ENTRY SysCode; GDT_ENTRY SysCode;
GDT_ENTRY Spare4; GDT_ENTRY SysCode16;
GDT_ENTRY LinearData64; GDT_ENTRY LinearData64;
GDT_ENTRY LinearCode64; GDT_ENTRY LinearCode64;
GDT_ENTRY Spare5; GDT_ENTRY Spare5;
@ -49,7 +49,7 @@ struct _GDT_ENTRIES {
#define LINEAR_CODE_SEL OFFSET_OF (GDT_ENTRIES, LinearCode) #define LINEAR_CODE_SEL OFFSET_OF (GDT_ENTRIES, LinearCode)
#define SYS_DATA_SEL OFFSET_OF (GDT_ENTRIES, SysData) #define SYS_DATA_SEL OFFSET_OF (GDT_ENTRIES, SysData)
#define SYS_CODE_SEL OFFSET_OF (GDT_ENTRIES, SysCode) #define SYS_CODE_SEL OFFSET_OF (GDT_ENTRIES, SysCode)
#define SPARE4_SEL OFFSET_OF (GDT_ENTRIES, Spare4) #define SYS_CODE16_SEL OFFSET_OF (GDT_ENTRIES, SysCode16)
#define LINEAR_DATA64_SEL OFFSET_OF (GDT_ENTRIES, LinearData64) #define LINEAR_DATA64_SEL OFFSET_OF (GDT_ENTRIES, LinearData64)
#define LINEAR_CODE64_SEL OFFSET_OF (GDT_ENTRIES, LinearCode64) #define LINEAR_CODE64_SEL OFFSET_OF (GDT_ENTRIES, LinearCode64)
#define SPARE5_SEL OFFSET_OF (GDT_ENTRIES, Spare5) #define SPARE5_SEL OFFSET_OF (GDT_ENTRIES, Spare5)

View File

@ -129,5 +129,14 @@ LINEAR_CODE64_SEL equ $-GDT_BASE
DB 0 ; base 31:24 DB 0 ; base 31:24
%endif %endif
; linear code segment descriptor
LINEAR_CODE16_SEL equ $-GDT_BASE
DW 0xffff ; limit 15:0
DW 0 ; base 15:0
DB 0 ; base 23:16
DB PRESENT_FLAG(1)|DPL(0)|SYSTEM_FLAG(1)|DESC_TYPE(CODE32_TYPE)
DB GRANULARITY_FLAG(1)|DEFAULT_SIZE32(0)|CODE64_FLAG(0)|UPPER_LIMIT(0xf)
DB 0 ; base 31:24
GDT_END: GDT_END: