From ede5387afd411227f168e4e0724da9aecafdce61 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 21 Mar 2024 17:51:18 +0300 Subject: [PATCH] Ring3: Fixed TSS initialization. --- OvmfPkg/OvmfPkgIa32.dsc | 1 + OvmfPkg/OvmfPkgIa32X64.dsc | 1 + OvmfPkg/OvmfPkgX64.dsc | 1 + UefiCpuPkg/Library/CpuArchLib/CpuGdt.h | 4 +-- .../Ia32/ArchExceptionHandler.c | 34 +++++++++++++++---- .../Ia32/ArchInterruptDefs.h | 3 +- .../X64/ArchExceptionHandler.c | 1 + 7 files changed, 36 insertions(+), 9 deletions(-) diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc index 1336bdd43e..3cce361b19 100644 --- a/OvmfPkg/OvmfPkgIa32.dsc +++ b/OvmfPkg/OvmfPkgIa32.dsc @@ -594,6 +594,7 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0xFFFFFFFFFFFFFF04 gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x70000000 !endif + gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard|TRUE # # Firmware volume supports UE, and may require PE. diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc index 3275674056..e05a82140a 100644 --- a/OvmfPkg/OvmfPkgIa32X64.dsc +++ b/OvmfPkg/OvmfPkgIa32X64.dsc @@ -610,6 +610,7 @@ gEfiMdePkgTokenSpaceGuid.PcdImageLoaderAllowMisalignedOffset|TRUE gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x00000003 !endif + gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard|TRUE ################################################################################ # diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc index d7ddafaddc..e704a4699f 100644 --- a/OvmfPkg/OvmfPkgX64.dsc +++ b/OvmfPkg/OvmfPkgX64.dsc @@ -621,6 +621,7 @@ gEfiMdePkgTokenSpaceGuid.PcdImageLoaderAllowMisalignedOffset|TRUE gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x00000003 !endif + gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard|TRUE # # Firmware volume supports UE, and may require PE. diff --git a/UefiCpuPkg/Library/CpuArchLib/CpuGdt.h b/UefiCpuPkg/Library/CpuArchLib/CpuGdt.h index 21ad6df184..865561042e 100644 --- a/UefiCpuPkg/Library/CpuArchLib/CpuGdt.h +++ b/UefiCpuPkg/Library/CpuArchLib/CpuGdt.h @@ -25,8 +25,8 @@ #define SPARE5_SEL OFFSET_OF (GDT, Spare5) #if defined (MDE_CPU_IA32) -#define CPU_CODE_SEL LINEAR_CODE_SEL -#define CPU_DATA_SEL LINEAR_SEL +#define CPU_CODE_SEL SYS_CODE_SEL +#define CPU_DATA_SEL SYS_DATA_SEL #elif defined (MDE_CPU_X64) #define CPU_CODE_SEL LINEAR_CODE64_SEL #define CPU_DATA_SEL LINEAR_DATA64_SEL diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c index c30ece1dc9..865bd10534 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c @@ -135,6 +135,7 @@ ArchSetupExceptionStack ( UINT8 *StackSwitchExceptions; UINTN NeedBufferSize; EXCEPTION_HANDLER_TEMPLATE_MAP TemplateMap; + UINT8 *IOBitMap; if (BufferSize == NULL) { return EFI_INVALID_PARAMETER; @@ -203,14 +204,38 @@ ArchSetupExceptionStack ( TssBase = (UINTN)Tss; TssDesc->Uint64 = 0; - TssDesc->Bits.LimitLow = sizeof (IA32_TASK_STATE_SEGMENT) - 1; + TssDesc->Bits.LimitLow = (UINT16)(sizeof (IA32_TASK_STATE_SEGMENT) + IO_BIT_MAP_SIZE - 1); TssDesc->Bits.BaseLow = (UINT16)TssBase; TssDesc->Bits.BaseMid = (UINT8)(TssBase >> 16); TssDesc->Bits.Type = IA32_GDT_TYPE_TSS; + TssDesc->Bits.DPL = 3; TssDesc->Bits.P = 1; - TssDesc->Bits.LimitHigh = 0; + TssDesc->Bits.LimitHigh = (sizeof (IA32_TASK_STATE_SEGMENT) + IO_BIT_MAP_SIZE - 1) >> 16; TssDesc->Bits.BaseHigh = (UINT8)(TssBase >> 24); + // + // Set I/O Permission Bit Map + // + ZeroMem (Tss, sizeof (*Tss)); + + Tss->IOMapBaseAddress = sizeof (IA32_TASK_STATE_SEGMENT); + // + // Allow access to gUartBase = 0x3F8 and Offsets: 0x01, 0x03, 0x04, 0x05, 0x06 + // + IOBitMap = (UINT8 *)((UINTN)Tss + Tss->IOMapBaseAddress); + for (Index = 0; Index < IO_BIT_MAP_SIZE; ++Index) { + if ((Index * 8) == 0x3F8) { + *IOBitMap = 0x84; + } else { + *IOBitMap = 0xFF; + } + + ++IOBitMap; + } + + Tss = (IA32_TASK_STATE_SEGMENT *)((UINTN)Tss + sizeof (IA32_TASK_STATE_SEGMENT) + IO_BIT_MAP_SIZE); + ++TssDesc; + // // Fixup exception task descriptor and task-state segment // @@ -221,10 +246,7 @@ ArchSetupExceptionStack ( StackTop = StackTop - CPU_STACK_ALIGNMENT + 1; StackTop = (UINTN)ALIGN_POINTER (StackTop, CPU_STACK_ALIGNMENT); IdtTable = (IA32_IDT_GATE_DESCRIPTOR *)Idtr.Base; - for (Index = 0; Index < CPU_STACK_SWITCH_EXCEPTION_NUMBER; ++Index) { - TssDesc += 1; - Tss += 1; - + for (Index = 0; Index < CPU_STACK_SWITCH_EXCEPTION_NUMBER; ++Index, ++TssDesc, ++Tss) { // // Fixup TSS descriptor // diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchInterruptDefs.h b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchInterruptDefs.h index 211d2abe48..675c45436c 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchInterruptDefs.h +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchInterruptDefs.h @@ -39,8 +39,9 @@ typedef struct { (sizeof (IA32_TSS_DESCRIPTOR) * \ (FixedPcdGetSize (PcdCpuStackSwitchExceptionList) + 1)) +#define IO_BIT_MAP_SIZE (ALIGN_VALUE (0x81, 16)) #define CPU_TSS_SIZE \ (sizeof (IA32_TASK_STATE_SEGMENT) * \ - (FixedPcdGetSize (PcdCpuStackSwitchExceptionList) + 1)) + (FixedPcdGetSize (PcdCpuStackSwitchExceptionList) + 1) + IO_BIT_MAP_SIZE) #endif diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c index 76a51e28d0..a1275b53df 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c @@ -215,6 +215,7 @@ ArchSetupExceptionStack ( TssDesc->Bits.BaseLow = (UINT16)TssBase; TssDesc->Bits.BaseMidl = (UINT8)(TssBase >> 16); TssDesc->Bits.Type = IA32_GDT_TYPE_TSS; + TssDesc->Bits.DPL = 3; TssDesc->Bits.P = 1; TssDesc->Bits.LimitHigh = (CPU_TSS_SIZE - 1) >> 16; TssDesc->Bits.BaseMidh = (UINT8)(TssBase >> 24);