Ring3: Added SetExceptionAddresses(), aligned exceptions' stacks.

This commit is contained in:
Mikhail Krichanov 2024-11-29 14:33:17 +03:00
parent 58038f62ad
commit 1a5a22e450
3 changed files with 32 additions and 12 deletions
MdeModulePkg/Include/Library
UefiCpuPkg/Library
CpuArchLib
CpuExceptionHandlerLib

View File

@ -113,4 +113,11 @@ GetExceptionAddresses (
VOID
);
VOID
EFIAPI
SetExceptionAddresses (
IN VOID *Buffer,
IN UINTN BufferSize
);
#endif

View File

@ -622,9 +622,11 @@ InitializeExceptionStackSwitchHandlers (
{
EXCEPTION_STACK_SWITCH_CONTEXT *SwitchStackData;
UINTN Index;
MSR_IA32_APIC_BASE_REGISTER ApicBaseMsr;
MpInitLibWhoAmI (&Index);
SwitchStackData = (EXCEPTION_STACK_SWITCH_CONTEXT *)Buffer;
SwitchStackData = (EXCEPTION_STACK_SWITCH_CONTEXT *)Buffer;
ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE);
//
// This may be called twice for each Cpu. Only run InitializeSeparateExceptionStacks
@ -632,6 +634,9 @@ InitializeExceptionStackSwitchHandlers (
//
if ((SwitchStackData[Index].Status == EFI_NOT_STARTED) || (SwitchStackData[Index].Status == EFI_BUFFER_TOO_SMALL)) {
SwitchStackData[Index].Status = InitializeSeparateExceptionStacks (SwitchStackData[Index].Buffer, &SwitchStackData[Index].BufferSize);
if ((ApicBaseMsr.Bits.BSP != 0) && (SwitchStackData[Index].Status == EFI_SUCCESS)) {
SetExceptionAddresses (SwitchStackData[Index].Buffer, SwitchStackData[Index].BufferSize);
}
}
}
@ -674,6 +679,7 @@ InitializeMpExceptionStackSwitchHandlers (
for (Index = 0; Index < mNumberOfProcessors; ++Index) {
if (SwitchStackData[Index].Status == EFI_BUFFER_TOO_SMALL) {
ASSERT (SwitchStackData[Index].BufferSize != 0);
SwitchStackData[Index].BufferSize = ALIGN_VALUE (SwitchStackData[Index].BufferSize, EFI_PAGE_SIZE);
BufferSize += SwitchStackData[Index].BufferSize;
} else {
ASSERT (SwitchStackData[Index].Status == EFI_SUCCESS);
@ -682,8 +688,9 @@ InitializeMpExceptionStackSwitchHandlers (
}
if (BufferSize != 0) {
Buffer = AllocateRuntimeZeroPool (BufferSize);
Buffer = AllocateRuntimePages (EFI_SIZE_TO_PAGES (BufferSize));
ASSERT (Buffer != NULL);
SetMem (Buffer, BufferSize, 0);
BufferSize = 0;
for (Index = 0; Index < mNumberOfProcessors; ++Index) {
if (SwitchStackData[Index].Status == EFI_BUFFER_TOO_SMALL) {

View File

@ -136,17 +136,13 @@ InitializeSeparateExceptionStacks (
UINTN LocalBufferSize;
EFI_STATUS Status;
mAddresses.ExceptionStackSize = CPU_STACK_SWITCH_EXCEPTION_NUMBER * CPU_KNOWN_GOOD_STACK_SIZE;
if ((Buffer == NULL) && (BufferSize == NULL)) {
SetMem (mBuffer, sizeof (mBuffer), 0);
LocalBufferSize = sizeof (mBuffer);
Status = ArchSetupExceptionStack (mBuffer, &LocalBufferSize);
ASSERT_EFI_ERROR (Status);
mAddresses.ExceptionStackBase = (UINTN)mBuffer;
return Status;
} else {
mAddresses.ExceptionStackBase = (UINTN)Buffer;
return ArchSetupExceptionStack (Buffer, BufferSize);
}
}
@ -209,11 +205,21 @@ GetExceptionAddresses (
{
mSwitchCr3Flag = 1;
mAddresses.ExceptionHandlerBase = (UINTN)&ExceptionHandlerBase;
mAddresses.ExceptionHandlerSize = (UINTN)&ExceptionHandlerEnd - mAddresses.ExceptionHandlerBase;
mAddresses.ExceptionDataBase = (UINTN)&CorePageTable;
CorePageTable = AsmReadCr3 ();
return &mAddresses;
}
VOID
EFIAPI
SetExceptionAddresses (
IN VOID *Buffer,
IN UINTN BufferSize
)
{
mAddresses.ExceptionStackBase = (UINTN)Buffer;
mAddresses.ExceptionStackSize = BufferSize;
mAddresses.ExceptionHandlerBase = (UINTN)&ExceptionHandlerBase;
mAddresses.ExceptionHandlerSize = (UINTN)&ExceptionHandlerEnd - mAddresses.ExceptionHandlerBase;
mAddresses.ExceptionDataBase = (UINTN)&CorePageTable;
CorePageTable = AsmReadCr3 ();
}