diff --git a/reactos/ntoskrnl/include/internal/arm/ksarm.h b/reactos/ntoskrnl/include/internal/arm/ksarm.h index 0ded6e44f5a..91adf08672e 100644 --- a/reactos/ntoskrnl/include/internal/arm/ksarm.h +++ b/reactos/ntoskrnl/include/internal/arm/ksarm.h @@ -62,7 +62,7 @@ .equ TrSvcLr, 0x44 .equ TrPc, 0x48 .equ TrSpsr, 0x4C -.equ TrapFrameLength, (22 * 0x04) +.equ TrapFrameLength, (23 * 0x04) /* * Exception Frame offsets diff --git a/reactos/ntoskrnl/ke/arm/trap.s b/reactos/ntoskrnl/ke/arm/trap.s index fde9d354f5c..26a4d523976 100644 --- a/reactos/ntoskrnl/ke/arm/trap.s +++ b/reactos/ntoskrnl/ke/arm/trap.s @@ -31,7 +31,6 @@ TEXTAREA NESTED_ENTRY KiUndefinedInstructionException PROLOG_END KiUndefinedInstructionException - // // Handle trap entry // @@ -40,21 +39,14 @@ // // Call the C handler // - adr lr, 1f + ldr lr, =KiExceptionExit mov r0, sp ldr pc, =KiUndefinedExceptionHandler - -1: - // - // Handle trap exit - // - TRAP_EPILOG 0 // NotFromSystemCall - ENTRY_END KiUndefinedInstructionException + NESTED_ENTRY KiSoftwareInterruptException PROLOG_END KiSoftwareInterruptException - // // Handle trap entry // @@ -63,21 +55,14 @@ // // Call the C handler // - adr lr, 1f + ldr lr, =KiServiceExit mov r0, sp ldr pc, =KiSoftwareInterruptHandler - -1: - // - // Handle trap exit - // - TRAP_EPILOG 1 // FromSystemCall - ENTRY_END KiSoftwareInterruptException + NESTED_ENTRY KiPrefetchAbortException PROLOG_END KiPrefetchAbortException - // // Handle trap entry // @@ -86,21 +71,14 @@ // // Call the C handler // - adr lr, 1f + ldr lr, =KiExceptionExit mov r0, sp ldr pc, =KiPrefetchAbortHandler - -1: - // - // Handle trap exit - // - TRAP_EPILOG 0 // NotFromSystemCall - ENTRY_END KiPrefetchAbortException + NESTED_ENTRY KiDataAbortException PROLOG_END KiDataAbortException - // // Handle trap entry // @@ -109,21 +87,14 @@ // // Call the C handler // - adr lr, 1f + ldr lr, =KiExceptionExit mov r0, sp ldr pc, =KiDataAbortHandler - -1: - // - // Handle trap exit - // - TRAP_EPILOG 0 // NotFromSystemCall - ENTRY_END KiDataAbortException + NESTED_ENTRY KiInterruptException PROLOG_END KiInterruptException - // // Handle trap entry // @@ -132,25 +103,35 @@ // // Call the C handler // - adr lr, 1f + ldr lr, =KiExceptionExit mov r0, sp mov r1, #0 ldr pc, =KiInterruptHandler - -1: - // - // Handle trap exit - // - TRAP_EPILOG 0 // NotFromSystemCall - ENTRY_END KiInterruptException + NESTED_ENTRY KiFastInterruptException PROLOG_END KiFastInterruptException - // // FIXME-PERF: Implement FIQ exception // b . - ENTRY_END KiFastInterruptException + + + NESTED_ENTRY KiExceptionExit + PROLOG_END KiExceptionExit + // + // Handle trap exit + // + TRAP_EPILOG 0 // NotFromSystemCall + ENTRY_END KiExceptionExit + + + NESTED_ENTRY KiServiceExit + PROLOG_END KiServiceExit + // + // Handle trap exit + // + TRAP_EPILOG 1 // FromSystemCall + ENTRY_END KiServiceExit diff --git a/reactos/ntoskrnl/ke/arm/trapc.c b/reactos/ntoskrnl/ke/arm/trapc.c index 28581e9c005..71a56216529 100644 --- a/reactos/ntoskrnl/ke/arm/trapc.c +++ b/reactos/ntoskrnl/ke/arm/trapc.c @@ -457,7 +457,6 @@ KiPrefetchAbortHandler(IN PKTRAP_FRAME TrapFrame) // // Unhandled // - while (TRUE); DPRINT1("[PREFETCH ABORT] (%x) @ %p/%p/%p\n", KeArmInstructionFaultStatusRegisterGet(), Address, TrapFrame->SvcLr, TrapFrame->Pc); UNIMPLEMENTED; @@ -516,6 +515,7 @@ KiSoftwareInterruptHandler(IN PKTRAP_FRAME TrapFrame) // Save old previous mode // TrapFrame->PreviousMode = PreviousMode; + TrapFrame->PreviousTrapFrame = (ULONG_PTR)Thread->TrapFrame; // // Save previous mode and trap frame diff --git a/reactos/ntoskrnl/ke/arm/usercall.c b/reactos/ntoskrnl/ke/arm/usercall.c index 7ffc6ad0668..1f11468d834 100644 --- a/reactos/ntoskrnl/ke/arm/usercall.c +++ b/reactos/ntoskrnl/ke/arm/usercall.c @@ -9,6 +9,7 @@ /* INCLUDES *******************************************************************/ #include +#include #define NDEBUG #include @@ -90,6 +91,7 @@ KiSystemService(IN PKTHREAD Thread, PVOID SystemCall; PVOID* Argument; PVOID Arguments[0x11]; // Maximum 17 arguments + KIRQL OldIrql; ASSERT(TrapFrame->DbgArgMark == 0xBADB0D00); // @@ -209,4 +211,53 @@ KiSystemService(IN PKTHREAD Thread, // TrapFrame->R0 = KiSyscallHandlers[ArgumentCount]((PVOID)SystemCall, (PVOID)Arguments); + + // + // Check if this was a user call + // + if (KiGetPreviousMode(TrapFrame) == UserMode) + { + // + // Make sure we didn't return at elevated IRQL + // + OldIrql = KeGetCurrentIrql(); + if (OldIrql != PASSIVE_LEVEL) + { + // + // Forcibly put us in a sane state + // + KeGetPcr()->CurrentIrql = 0; + _disable(); + + // + // Fail + // + KeBugCheckEx(IRQL_GT_ZERO_AT_SYSTEM_SERVICE, + (ULONG_PTR)SystemCall, + OldIrql, + 0, + 0); + } + + // + // Make sure we're not attached and that APCs are not disabled + // + if ((KeGetCurrentThread()->ApcStateIndex != CurrentApcEnvironment) || + (KeGetCurrentThread()->CombinedApcDisable != 0)) + { + // + // Fail + // + KeBugCheckEx(APC_INDEX_MISMATCH, + (ULONG_PTR)SystemCall, + KeGetCurrentThread()->ApcStateIndex, + KeGetCurrentThread()->CombinedApcDisable, + 0); + } + } + + // + // Restore the old trap frame + // + Thread->TrapFrame = (PKTRAP_FRAME)TrapFrame->PreviousTrapFrame; }