diff --git a/MdePkg/Include/Library/BaseLib.h b/MdePkg/Include/Library/BaseLib.h index a84a09c467..ad2320a43c 100644 --- a/MdePkg/Include/Library/BaseLib.h +++ b/MdePkg/Include/Library/BaseLib.h @@ -5616,10 +5616,10 @@ typedef struct { } IA32_DESCRIPTOR; #pragma pack () -#define IA32_IDT_GATE_TYPE_TASK 0x85 +#define IA32_IDT_GATE_TYPE_TASK 0xE5 #define IA32_IDT_GATE_TYPE_INTERRUPT_16 0x86 #define IA32_IDT_GATE_TYPE_TRAP_16 0x87 -#define IA32_IDT_GATE_TYPE_INTERRUPT_32 0x8E +#define IA32_IDT_GATE_TYPE_INTERRUPT_32 0xEE #define IA32_IDT_GATE_TYPE_TRAP_32 0x8F #define IA32_GDT_TYPE_TSS 0x9 diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc index 3cce361b19..95466c7b4e 100644 --- a/OvmfPkg/OvmfPkgIa32.dsc +++ b/OvmfPkg/OvmfPkgIa32.dsc @@ -595,6 +595,7 @@ gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x70000000 !endif gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard|TRUE + gEfiMdeModulePkgTokenSpaceGuid.PcdEnableUserSpace|TRUE # # Firmware volume supports UE, and may require PE. diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c index 865bd10534..da588d6b3a 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c @@ -202,22 +202,31 @@ ArchSetupExceptionStack ( // be filled by processor during task switching. // TssBase = (UINTN)Tss; - + // + // Last byte of bitmap must be followed by a byte with all bits set. + // TssDesc->Uint64 = 0; - TssDesc->Bits.LimitLow = (UINT16)(sizeof (IA32_TASK_STATE_SEGMENT) + IO_BIT_MAP_SIZE - 1); + TssDesc->Bits.LimitLow = (UINT16)(sizeof (IA32_TASK_STATE_SEGMENT) + IO_BIT_MAP_SIZE - 2); 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 = (sizeof (IA32_TASK_STATE_SEGMENT) + IO_BIT_MAP_SIZE - 1) >> 16; + TssDesc->Bits.LimitHigh = (sizeof (IA32_TASK_STATE_SEGMENT) + IO_BIT_MAP_SIZE - 2) >> 16; TssDesc->Bits.BaseHigh = (UINT8)(TssBase >> 24); // // Set I/O Permission Bit Map // ZeroMem (Tss, sizeof (*Tss)); + // + // Plus 1 byte is for compact stack layout in case StackTop is already aligned. + // + StackTop = StackTop - CPU_STACK_ALIGNMENT + 1; + StackTop = (UINTN)ALIGN_POINTER (StackTop, CPU_STACK_ALIGNMENT); + Tss->ESP0 = StackTop; + Tss->SS0 = AsmReadSs (); Tss->IOMapBaseAddress = sizeof (IA32_TASK_STATE_SEGMENT); // // Allow access to gUartBase = 0x3F8 and Offsets: 0x01, 0x03, 0x04, 0x05, 0x06 @@ -240,11 +249,7 @@ ArchSetupExceptionStack ( // Fixup exception task descriptor and task-state segment // AsmGetTssTemplateMap (&TemplateMap); - // - // Plus 1 byte is for compact stack layout in case StackTop is already aligned. - // - 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, ++Tss) { // @@ -257,6 +262,7 @@ ArchSetupExceptionStack ( 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.BaseHigh = (UINT8)(TssBase >> 24); diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.nasm b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.nasm index c6876eff64..b0cb2a9b4f 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.nasm +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.nasm @@ -208,7 +208,7 @@ ErrorCodeAndVectorOnStack: jz sameCPL_0 mov ecx, [ecx] sameCPL_0: - push ecx ; ESP + push ecx ; ESP push dword [ebp] ; EBP push esi push edi @@ -390,7 +390,7 @@ sameCPL_1: pop ds pop dword [ebp + 4 * 4] ; Check whether Ring0 process was interrupted. - mov ecx, ss + mov ecx, ds and ecx, 3 jz sameCPL_2 pop dword [ebp + 7 * 4] @@ -413,9 +413,8 @@ continue: push ecx mov ecx, ds and ecx, 3 - cmp ecx, 3 pop ecx - je ReturnToRing3 + jnz ReturnToRing3 pop dword [ebp - 8] pop dword [ebp - 4]