Ring3: Fixed buggy timer interrupt handling for X64.

This commit is contained in:
Mikhail Krichanov 2024-09-05 15:54:33 +03:00
parent d4e1092dc7
commit ede4877e3b
4 changed files with 35 additions and 40 deletions

View File

@ -611,6 +611,7 @@
gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x00000003 gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x00000003
!endif !endif
gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard|TRUE gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard|TRUE
gEfiMdeModulePkgTokenSpaceGuid.PcdEnableUserSpace|TRUE
################################################################################ ################################################################################
# #

View File

@ -208,21 +208,23 @@ ArchSetupExceptionStack (
// be filled by processor during task switching. // be filled by processor during task switching.
// //
TssBase = (UINTN)Tss; TssBase = (UINTN)Tss;
//
// Last byte of bitmap must be followed by a byte with all bits set.
//
TssDesc->Uint128.Uint64 = 0; TssDesc->Uint128.Uint64 = 0;
TssDesc->Uint128.Uint64_1 = 0; TssDesc->Uint128.Uint64_1 = 0;
TssDesc->Bits.LimitLow = (UINT16)(CPU_TSS_SIZE - 1); TssDesc->Bits.LimitLow = (UINT16)(CPU_TSS_SIZE - 2);
TssDesc->Bits.BaseLow = (UINT16)TssBase; TssDesc->Bits.BaseLow = (UINT16)TssBase;
TssDesc->Bits.BaseMidl = (UINT8)(TssBase >> 16); TssDesc->Bits.BaseMidl = (UINT8)(TssBase >> 16);
TssDesc->Bits.Type = IA32_GDT_TYPE_TSS; TssDesc->Bits.Type = IA32_GDT_TYPE_TSS;
TssDesc->Bits.DPL = 3; TssDesc->Bits.DPL = 3;
TssDesc->Bits.P = 1; TssDesc->Bits.P = 1;
TssDesc->Bits.LimitHigh = (CPU_TSS_SIZE - 1) >> 16; TssDesc->Bits.LimitHigh = (CPU_TSS_SIZE - 2) >> 16;
TssDesc->Bits.BaseMidh = (UINT8)(TssBase >> 24); TssDesc->Bits.BaseMidh = (UINT8)(TssBase >> 24);
TssDesc->Bits.BaseHigh = (UINT32)(TssBase >> 32); TssDesc->Bits.BaseHigh = (UINT32)(TssBase >> 32);
// //
// Fixup exception task descriptor and task-state segment // Set I/O Permission Bit Map
// //
ZeroMem (Tss, sizeof (*Tss)); ZeroMem (Tss, sizeof (*Tss));
// //
@ -230,6 +232,26 @@ ArchSetupExceptionStack (
// //
StackTop = StackTop - CPU_STACK_ALIGNMENT + 1; StackTop = StackTop - CPU_STACK_ALIGNMENT + 1;
StackTop = (UINTN)ALIGN_POINTER (StackTop, CPU_STACK_ALIGNMENT); StackTop = (UINTN)ALIGN_POINTER (StackTop, CPU_STACK_ALIGNMENT);
Tss->RSP0 = StackTop;
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;
}
//
// Fixup IST and task-state segment
//
IdtTable = (IA32_IDT_GATE_DESCRIPTOR *)Idtr.Base; IdtTable = (IA32_IDT_GATE_DESCRIPTOR *)Idtr.Base;
for (Index = 0; Index < CPU_STACK_SWITCH_EXCEPTION_NUMBER; ++Index) { for (Index = 0; Index < CPU_STACK_SWITCH_EXCEPTION_NUMBER; ++Index) {
// //
@ -256,24 +278,6 @@ ArchSetupExceptionStack (
// //
AsmWriteGdtr (&Gdtr); AsmWriteGdtr (&Gdtr);
//
// Set I/O Permission Bit Map
//
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;
}
// //
// Load current task // Load current task
// //

View File

@ -41,7 +41,7 @@ typedef struct {
// //
// 0x81 is needed to allow Ring3 code access to Uart in I/O Permission Bit Map. // 0x81 is needed to allow Ring3 code access to Uart in I/O Permission Bit Map.
// //
#define IO_BIT_MAP_SIZE 0x81 #define IO_BIT_MAP_SIZE (ALIGN_VALUE (0x81, 16))
#define CPU_TSS_SIZE (sizeof (IA32_TASK_STATE_SEGMENT) + IO_BIT_MAP_SIZE) #define CPU_TSS_SIZE (sizeof (IA32_TASK_STATE_SEGMENT) + IO_BIT_MAP_SIZE)
#endif #endif

View File

@ -207,20 +207,11 @@ HasErrorCode:
mov rax, gs mov rax, gs
push rax push rax
; Check whether Ring3 process was interrupted. mov ax, ss
and rax, 3 mov ds, ax
cmp rax, 3 mov es, ax
jne SkipHook mov fs, ax
mov rax, cr2 mov gs, ax
cmp rax, 0xFFFFFFFFFFFFFFF8
jne SkipHook
mov rcx, 32
SkipHook:
mov rax, ss
mov ds, rax
mov es, rax
mov fs, rax
mov gs, rax
mov [rbp + 8], rcx ; save vector number mov [rbp + 8], rcx ; save vector number
@ -426,7 +417,7 @@ CetDone:
;; UINT64 R8, R9, R10, R11, R12, R13, R14, R15; ;; UINT64 R8, R9, R10, R11, R12, R13, R14, R15;
pop rdi pop rdi
pop rsi pop rsi
add rsp, 8 ; not for rbp add rsp, 8 ; not for rbp
pop qword [rbp + 48] ; for rsp pop qword [rbp + 48] ; for rsp
pop rbx pop rbx
pop rdx pop rdx
@ -445,9 +436,8 @@ CetDone:
push rcx push rcx
mov rcx, ds mov rcx, ds
and rcx, 3 and rcx, 3
cmp rcx, 3
pop rcx pop rcx
je ReturnToRing3 jnz ReturnToRing3
mov rsp, rbp mov rsp, rbp
pop rbp pop rbp