Author: ros-arm-bringup Date: Mon Jul 21 10:55:58 2008 New Revision: 34640
URL: http://svn.reactos.org/svn/reactos?rev=34640&view=rev Log: - Improve system call handler by adding more debugging checks to be used later. - Optimize and simplify trap handling by using a common exit just like on x86's Kei386EoiHelper - KiExceptionExit. This way the code isn't duplicated 6 times. - Do the same for system calls (KiServiceExit). - Save the previous trap frame and restore it during each system call.
Modified: trunk/reactos/ntoskrnl/include/internal/arm/ksarm.h trunk/reactos/ntoskrnl/ke/arm/trap.s trunk/reactos/ntoskrnl/ke/arm/trapc.c trunk/reactos/ntoskrnl/ke/arm/usercall.c
Modified: trunk/reactos/ntoskrnl/include/internal/arm/ksarm.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/a... ============================================================================== --- trunk/reactos/ntoskrnl/include/internal/arm/ksarm.h [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/include/internal/arm/ksarm.h [iso-8859-1] Mon Jul 21 10:55:58 2008 @@ -62,7 +62,7 @@ .equ TrSvcLr, 0x44 .equ TrPc, 0x48 .equ TrSpsr, 0x4C -.equ TrapFrameLength, (22 * 0x04) +.equ TrapFrameLength, (23 * 0x04)
/* * Exception Frame offsets
Modified: trunk/reactos/ntoskrnl/ke/arm/trap.s URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/arm/trap.s?rev=... ============================================================================== --- trunk/reactos/ntoskrnl/ke/arm/trap.s [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ke/arm/trap.s [iso-8859-1] Mon Jul 21 10:55:58 2008 @@ -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 + ENTRY_END KiUndefinedInstructionException
-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 + ENTRY_END KiDataAbortException
-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 + ENTRY_END KiInterruptException + + + NESTED_ENTRY KiFastInterruptException + PROLOG_END KiFastInterruptException + // + // FIXME-PERF: Implement FIQ exception + // + b . + ENTRY_END KiFastInterruptException
-1: + + NESTED_ENTRY KiExceptionExit + PROLOG_END KiExceptionExit // // Handle trap exit // TRAP_EPILOG 0 // NotFromSystemCall - - ENTRY_END KiInterruptException + ENTRY_END KiExceptionExit
- NESTED_ENTRY KiFastInterruptException - PROLOG_END KiFastInterruptException - + + NESTED_ENTRY KiServiceExit + PROLOG_END KiServiceExit // - // FIXME-PERF: Implement FIQ exception - // - b . - - ENTRY_END KiFastInterruptException + // Handle trap exit + // + TRAP_EPILOG 1 // FromSystemCall + ENTRY_END KiServiceExit
Modified: trunk/reactos/ntoskrnl/ke/arm/trapc.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/arm/trapc.c?rev... ============================================================================== --- trunk/reactos/ntoskrnl/ke/arm/trapc.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ke/arm/trapc.c [iso-8859-1] Mon Jul 21 10:55:58 2008 @@ -457,7 +457,6 @@ // // Unhandled // - while (TRUE); DPRINT1("[PREFETCH ABORT] (%x) @ %p/%p/%p\n", KeArmInstructionFaultStatusRegisterGet(), Address, TrapFrame->SvcLr, TrapFrame->Pc); UNIMPLEMENTED; @@ -516,6 +515,7 @@ // Save old previous mode // TrapFrame->PreviousMode = PreviousMode; + TrapFrame->PreviousTrapFrame = (ULONG_PTR)Thread->TrapFrame;
// // Save previous mode and trap frame
Modified: trunk/reactos/ntoskrnl/ke/arm/usercall.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/arm/usercall.c?... ============================================================================== --- trunk/reactos/ntoskrnl/ke/arm/usercall.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ke/arm/usercall.c [iso-8859-1] Mon Jul 21 10:55:58 2008 @@ -9,6 +9,7 @@ /* INCLUDES *******************************************************************/
#include <ntoskrnl.h> +#include <internal/arm/ksarm.h> #define NDEBUG #include <debug.h>
@@ -90,6 +91,7 @@ PVOID SystemCall; PVOID* Argument; PVOID Arguments[0x11]; // Maximum 17 arguments + KIRQL OldIrql; ASSERT(TrapFrame->DbgArgMark == 0xBADB0D00);
// @@ -209,4 +211,53 @@ // 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; }