mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-25 14:44:28 +02:00
Ring3: Fixed memory leaks and passed UserArguments to CallBootService
through User stack for ARM, AARCH64.
This commit is contained in:
parent
6a38507512
commit
d20d45ae9b
@ -91,7 +91,7 @@
|
|||||||
UINT64 FAR; 0x320 // Fault Address Register
|
UINT64 FAR; 0x320 // Fault Address Register
|
||||||
UINT64 Type; 0x328 // Exception Type
|
UINT64 Type; 0x328 // Exception Type
|
||||||
UINT64 TTBR0; 0x330 // User Page Table
|
UINT64 TTBR0; 0x330 // User Page Table
|
||||||
UINT64 Padding;0x338 // Alignment requirement
|
UINT64 SP_EL0; 0x338 // User Stack Pointer
|
||||||
*/
|
*/
|
||||||
|
|
||||||
GCC_ASM_EXPORT(ExceptionHandlersEnd)
|
GCC_ASM_EXPORT(ExceptionHandlersEnd)
|
||||||
@ -101,7 +101,7 @@ GCC_ASM_EXPORT(CommonCExceptionHandler)
|
|||||||
|
|
||||||
#define GP_CONTEXT_SIZE (32 * 8)
|
#define GP_CONTEXT_SIZE (32 * 8)
|
||||||
#define FP_CONTEXT_SIZE (32 * 16)
|
#define FP_CONTEXT_SIZE (32 * 16)
|
||||||
#define SYS_CONTEXT_SIZE ( 8 * 8) // 7 SYS regs + Alignment requirement (ie: the stack must be aligned on 0x10)
|
#define SYS_CONTEXT_SIZE ( 8 * 8) // 8 SYS regs + Alignment requirement (ie: the stack must be aligned on 0x10)
|
||||||
|
|
||||||
ASM_FUNC_ALIGN(ExceptionHandlerBase, 4096)
|
ASM_FUNC_ALIGN(ExceptionHandlerBase, 4096)
|
||||||
|
|
||||||
@ -253,7 +253,8 @@ ASM_PFX(CommonExceptionEntry):
|
|||||||
1:mrs x2, ttbr0_el1
|
1:mrs x2, ttbr0_el1
|
||||||
b 3f
|
b 3f
|
||||||
2:mrs x2, ttbr0_el2
|
2:mrs x2, ttbr0_el2
|
||||||
3:stp x2, xzr, [x28, #0x30]
|
3:mrs x3, sp_el0
|
||||||
|
stp x2, x3, [x28, #0x30]
|
||||||
|
|
||||||
// Push FP regs to Stack.
|
// Push FP regs to Stack.
|
||||||
stp q0, q1, [x28, #-FP_CONTEXT_SIZE]!
|
stp q0, q1, [x28, #-FP_CONTEXT_SIZE]!
|
||||||
|
@ -30,34 +30,32 @@ SysCallBootService (
|
|||||||
IN EFI_SYSTEM_CONTEXT Context
|
IN EFI_SYSTEM_CONTEXT Context
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
EFI_PHYSICAL_ADDRESS Physical;
|
UINTN *UserArguments;
|
||||||
|
|
||||||
ArmEnableInterrupts ();
|
ArmEnableInterrupts ();
|
||||||
|
|
||||||
Status = CoreAllocatePages (
|
UserArguments = (UINTN *)(Context.SystemContextAArch64->SP_EL0 - 7 * sizeof (UINTN));
|
||||||
AllocateAnyPages,
|
|
||||||
EfiRing3MemoryType,
|
|
||||||
EFI_SIZE_TO_PAGES (7 * sizeof (UINTN)),
|
|
||||||
&Physical
|
|
||||||
);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
AllowSupervisorAccessToUserMemory ();
|
AllowSupervisorAccessToUserMemory ();
|
||||||
CopyMem ((VOID *)Physical, (VOID *)&(Context.SystemContextAArch64->X1), 7 * sizeof (UINTN));
|
//
|
||||||
|
// First 6 arguments are passed through X2-X7 and copied to Core stack,
|
||||||
|
// all the others are on User stack.
|
||||||
|
//
|
||||||
|
CopyMem (
|
||||||
|
(VOID *)UserArguments,
|
||||||
|
(VOID *)&(Context.SystemContextAArch64->X1),
|
||||||
|
7 * sizeof (UINTN)
|
||||||
|
);
|
||||||
ForbidSupervisorAccessToUserMemory ();
|
ForbidSupervisorAccessToUserMemory ();
|
||||||
|
|
||||||
Status = CallBootService (
|
Status = CallBootService (
|
||||||
Context.SystemContextAArch64->X0,
|
Context.SystemContextAArch64->X0,
|
||||||
Context.SystemContextAArch64->X1,
|
Context.SystemContextAArch64->X1,
|
||||||
(UINTN *)Physical,
|
UserArguments,
|
||||||
Context.SystemContextAArch64->SP
|
Context.SystemContextAArch64->SP
|
||||||
);
|
);
|
||||||
|
|
||||||
CoreFreePages (Physical, EFI_SIZE_TO_PAGES (7 * sizeof (UINTN)));
|
|
||||||
|
|
||||||
ArmDisableInterrupts ();
|
ArmDisableInterrupts ();
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
|
@ -29,10 +29,10 @@ SysCallBootService (
|
|||||||
IN EFI_SYSTEM_CONTEXT Context
|
IN EFI_SYSTEM_CONTEXT Context
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
EFI_PHYSICAL_ADDRESS Physical;
|
UINT8 Type;
|
||||||
UINT8 Type;
|
UINT8 NumberOfArguments;
|
||||||
UINT8 NumberOfArguments;
|
UINTN *UserArguments;
|
||||||
|
|
||||||
ArmEnableInterrupts ();
|
ArmEnableInterrupts ();
|
||||||
|
|
||||||
@ -47,16 +47,6 @@ SysCallBootService (
|
|||||||
++NumberOfArguments;
|
++NumberOfArguments;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = CoreAllocatePages (
|
|
||||||
AllocateAnyPages,
|
|
||||||
EfiRing3MemoryType,
|
|
||||||
EFI_SIZE_TO_PAGES ((NumberOfArguments + 1) * sizeof (UINTN)),
|
|
||||||
&Physical
|
|
||||||
);
|
|
||||||
if (EFI_ERROR (Status)) {
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
AllowSupervisorAccessToUserMemory ();
|
AllowSupervisorAccessToUserMemory ();
|
||||||
if (Type == SysCallFreePages) {
|
if (Type == SysCallFreePages) {
|
||||||
//
|
//
|
||||||
@ -64,41 +54,34 @@ SysCallBootService (
|
|||||||
// [SP] == Memory
|
// [SP] == Memory
|
||||||
// Memory is passed as 2 words on stack and aligned on 8 bytes.
|
// Memory is passed as 2 words on stack and aligned on 8 bytes.
|
||||||
//
|
//
|
||||||
CopyMem ((VOID *)(UINTN)Physical, (VOID *)&(Context.SystemContextArm->R1), 2 * sizeof (UINTN));
|
UserArguments = (UINTN *)(Context.SystemContextArm->SP - 2 * sizeof (UINTN));
|
||||||
|
|
||||||
CopyMem (
|
CopyMem (
|
||||||
(VOID *)((UINTN)Physical + 2 * sizeof (UINTN)),
|
(VOID *)UserArguments,
|
||||||
(VOID *)Context.SystemContextArm->SP,
|
(VOID *)&(Context.SystemContextArm->R1),
|
||||||
2 * sizeof (UINTN)
|
2 * sizeof (UINTN)
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
//
|
//
|
||||||
// First 2 arguments are passed through R2-R3 and copied to SysCall Stack.
|
// First 2 arguments are passed through R2-R3 and copied to Core stack,
|
||||||
|
// all the others are on User stack.
|
||||||
//
|
//
|
||||||
CopyMem ((VOID *)(UINTN)Physical, (VOID *)&(Context.SystemContextArm->R1), 3 * sizeof (UINTN));
|
UserArguments = (UINTN *)(Context.SystemContextArm->SP - 3 * sizeof (UINTN));
|
||||||
|
|
||||||
if (NumberOfArguments > 2) {
|
CopyMem (
|
||||||
//
|
(VOID *)UserArguments,
|
||||||
// All remaining arguments are on User Stack.
|
(VOID *)&(Context.SystemContextArm->R1),
|
||||||
//
|
3 * sizeof (UINTN)
|
||||||
CopyMem (
|
);
|
||||||
(VOID *)((UINTN)Physical + 3 * sizeof (UINTN)),
|
|
||||||
(VOID *)Context.SystemContextArm->SP,
|
|
||||||
(NumberOfArguments - 2) * sizeof (UINTN)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ForbidSupervisorAccessToUserMemory ();
|
ForbidSupervisorAccessToUserMemory ();
|
||||||
|
|
||||||
Status = CallBootService (
|
Status = CallBootService (
|
||||||
Type,
|
Type,
|
||||||
NumberOfArguments,
|
NumberOfArguments,
|
||||||
(UINTN *)(UINTN)Physical,
|
UserArguments,
|
||||||
Context.SystemContextArm->SP_EL1
|
Context.SystemContextArm->SP_EL1
|
||||||
);
|
);
|
||||||
//
|
|
||||||
// TODO: Fix memory leak for ReturnToCore().
|
|
||||||
//
|
|
||||||
CoreFreePages (Physical, EFI_SIZE_TO_PAGES ((NumberOfArguments + 1) * sizeof (UINTN)));
|
|
||||||
|
|
||||||
ArmDisableInterrupts ();
|
ArmDisableInterrupts ();
|
||||||
|
|
||||||
|
@ -396,7 +396,15 @@ CallBootService (
|
|||||||
|
|
||||||
switch (Type) {
|
switch (Type) {
|
||||||
case SysCallReturnToCore:
|
case SysCallReturnToCore:
|
||||||
ReturnToCore (Arguments[1], ReturnSP);
|
//
|
||||||
|
// Argument 1: EFI_STATUS Status
|
||||||
|
// Argument 2: UINTN ReturnSP
|
||||||
|
//
|
||||||
|
Status = (EFI_STATUS)Arguments[1];
|
||||||
|
|
||||||
|
FreePool (Arguments);
|
||||||
|
|
||||||
|
ReturnToCore (Status, ReturnSP);
|
||||||
break;
|
break;
|
||||||
case SysCallLocateProtocol:
|
case SysCallLocateProtocol:
|
||||||
//
|
//
|
||||||
@ -1510,5 +1518,6 @@ CallBootService (
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FreePool (Arguments);
|
||||||
return EFI_UNSUPPORTED;
|
return EFI_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
|
@ -594,11 +594,14 @@ typedef struct {
|
|||||||
UINT64 V30[2];
|
UINT64 V30[2];
|
||||||
UINT64 V31[2];
|
UINT64 V31[2];
|
||||||
|
|
||||||
UINT64 ELR; // Exception Link Register
|
UINT64 ELR; // Exception Link Register
|
||||||
UINT64 SPSR; // Saved Processor Status Register
|
UINT64 SPSR; // Saved Processor Status Register
|
||||||
UINT64 FPSR; // Floating Point Status Register
|
UINT64 FPSR; // Floating Point Status Register
|
||||||
UINT64 ESR; // Exception syndrome register
|
UINT64 ESR; // Exception syndrome register
|
||||||
UINT64 FAR; // Fault Address Register
|
UINT64 FAR; // Fault Address Register
|
||||||
|
UINT64 Type; // Exception Type
|
||||||
|
UINT64 TTBR0; // User Page Table
|
||||||
|
UINT64 SP_EL0; // User Stack Pointer
|
||||||
} EFI_SYSTEM_CONTEXT_AARCH64;
|
} EFI_SYSTEM_CONTEXT_AARCH64;
|
||||||
|
|
||||||
///
|
///
|
||||||
|
Loading…
x
Reference in New Issue
Block a user