Exemple #1
0
DECLSPEC_NOINLINE
VOID
KiContinuePreviousModeUser (
    IN PCONTEXT ContextRecord,
    IN PKEXCEPTION_FRAME ExceptionFrame,
    IN PKTRAP_FRAME TrapFrame
    )

/*++

Routine Description:

    This function is called to copy the specified context record when the
    previous mode is user. Its only purpose is to save stack space in the
    caller. 

    N.B. This routine assumes that the caller has protected access to the
       specified context record.

Arguments:

    ContextRecord - Supplies a pointer to a context record.

    ExceptionFrame - Supplies a pointer to an exception frame.

    TrapFrame - Supplies a pointer to a trap frame.

Return Value:

    None.

--*/

{

    CONTEXT ContextRecord2;

    //
    // Copy the context record to a stack local context record.
    //
    // N.B. The context record has already been probed for read
    //      access.
    //

    RtlCopyMemory(&ContextRecord2, ContextRecord, sizeof(CONTEXT));

    //
    // Move information from the context record to the exception and trap
    // frames.
    //

    KeContextToKframes(TrapFrame,
                       ExceptionFrame,
                       &ContextRecord2,
                       ContextRecord2.ContextFlags,
                       UserMode);

    return;
}
Exemple #2
0
VOID
KiRestoreProcessorState (
    IN PKTRAP_FRAME TrapFrame,
    IN PKEXCEPTION_FRAME ExceptionFrame
)

/*++

Routine Description:

    This function moves processor register state from the current
    processor context structure in the processor block to the
    specified trap and exception frames.

Arguments:

    TrapFrame - Supplies a pointer to a trap frame.

    ExceptionFrame - Supplies a pointer to an exception frame.

Return Value:

    None.

--*/

{

    PKPRCB Prcb;

    //
    // Get the address of the current processor block and move the
    // specified register state from the processor context structure
    // to the specified trap and exception frames
    //
    Prcb = KeGetCurrentPrcb();

#if !defined(NT_UP)

    KeContextToKframes(TrapFrame,
                       ExceptionFrame,
                       &Prcb->ProcessorState.ContextFrame,
                       CONTEXT_FULL,
                       KernelMode);

#endif

    //
    // Restore the current processor control state.
    // Currently, the primary use is to allow the kernel
    // debugger to set hardware debug registers. Still
    // investigating whether this is required for MP systems.
    //

    KiRestoreProcessorControlState(&Prcb->ProcessorState);
    return;
}
Exemple #3
0
VOID
KiInitializeContextThread (
    IN PKTHREAD Thread,
    IN PKSYSTEM_ROUTINE SystemRoutine,
    IN PKSTART_ROUTINE StartRoutine OPTIONAL,
    IN PVOID StartContext OPTIONAL,
    IN PCONTEXT ContextRecord OPTIONAL
    )

/*++

Routine Description:

    This function initializes the machine dependent context of a thread object.

    N.B. This function does not check the accessibility of the context record.
         It is assumed the the caller of this routine is either prepared to
         handle access violations or has probed and copied the context record
         as appropriate.

Arguments:

    Thread - Supplies a pointer to a dispatcher object of type thread.

    SystemRoutine - Supplies a pointer to the system function that is to be
        called when the thread is first scheduled for execution.

    StartRoutine - Supplies an optional pointer to a function that is to be
        called after the system has finished initializing the thread. This
        parameter is specified if the thread is a system thread and will
        execute totally in kernel mode.

    StartContext - Supplies an optional pointer to an arbitrary data structure
        which will be passed to the StartRoutine as a parameter. This
        parameter is specified if the thread is a system thread and will
        execute totally in kernel mode.

    ContextRecord - Supplies an optional pointer a context frame which contains
        the initial user mode state of the thread. This parameter is specified
        if the thread is a user thread and will execute in user mode. If this
        parameter is not specified, then the Teb parameter is ignored.

Return Value:

    None.

--*/

{

    PKEXCEPTION_FRAME CxFrame;
    PKEXCEPTION_FRAME ExFrame;
    ULONG_PTR InitialStack;
    PKTRAP_FRAME TrFrame;

    //
    // If a context frame is specified, then initialize a trap frame and
    // and an exception frame with the specified user mode context.
    //

    InitialStack = (ULONG_PTR)Thread->InitialStack;
    if (ARGUMENT_PRESENT(ContextRecord)) {
        TrFrame = (PKTRAP_FRAME)(((InitialStack) -
                  sizeof(KTRAP_FRAME)) & ~((ULONG_PTR)15));
        ExFrame = (PKEXCEPTION_FRAME)(((ULONG_PTR)TrFrame -
                  sizeof(KEXCEPTION_FRAME)) & ~((ULONG_PTR)15));
        CxFrame = (PKEXCEPTION_FRAME)(((ULONG_PTR)ExFrame -
                  sizeof(KEXCEPTION_FRAME)) & ~((ULONG_PTR)15));

        //
        // Zero the exception and trap frames and copy information from the
        // specified context frame to the trap and exception frames.
        //

        RtlZeroMemory((PVOID)ExFrame, sizeof(KEXCEPTION_FRAME));
        RtlZeroMemory((PVOID)TrFrame, sizeof(KTRAP_FRAME));
        KeContextToKframes(TrFrame, ExFrame,
                           ContextRecord,
                           ContextRecord->ContextFlags | CONTEXT_CONTROL,
                           UserMode);

        //
        // If the FPCR quadword in the specified context record is zero,
        // then assume it is a default value and force floating point round
        // to nearest mode (the hardware default mode is chopped rounding
        // which is not desirable for NT). It would be nice to initialize
        // the SoftFpcr here also but not all threads have a Teb.
        //

        if (TrFrame->Fpcr == 0) {
            ((PFPCR)(&TrFrame->Fpcr))->DynamicRoundingMode = ROUND_TO_NEAREST;
        }

        //
        // Set the saved previous processor mode in the trap frame and the
        // previous processor mode in the thread object to user mode.
        //

        TrFrame->PreviousMode = UserMode;
        Thread->PreviousMode = UserMode;

        //
        // Initialize the return address in the exception frame.
        //

        ExFrame->IntRa = 0;

    } else {
        ExFrame = NULL;
        CxFrame = (PKEXCEPTION_FRAME)(((InitialStack) -
                  sizeof(KEXCEPTION_FRAME)) & ~((ULONG_PTR)15));

        //
        // Set the previous mode in thread object to kernel.
        //

        Thread->PreviousMode = KernelMode;
    }

    //
    // Initialize context switch frame and set thread start up parameters.
    //
    // N.B. ULONG becomes canonical longword with (ULONGLONG)(LONG) cast.
    //

    CxFrame->SwapReturn = (ULONGLONG)(LONG_PTR)KiThreadStartup;
    if (ExFrame == NULL) {
        CxFrame->IntFp = (ULONGLONG)(LONG_PTR)ExFrame;

    } else {
        CxFrame->IntFp = (ULONGLONG)(LONG_PTR)TrFrame;
    }

    CxFrame->IntS0 = (ULONGLONG)(LONG_PTR)ContextRecord;
    CxFrame->IntS1 = (ULONGLONG)(LONG_PTR)StartContext;
    CxFrame->IntS2 = (ULONGLONG)(LONG_PTR)StartRoutine;
    CxFrame->IntS3 = (ULONGLONG)(LONG_PTR)SystemRoutine;

    CxFrame->Psr = 0;			// clear everything
    ((PSR *)(&CxFrame->Psr))->INTERRUPT_ENABLE = 1;
    ((PSR *)(&CxFrame->Psr))->IRQL = DISPATCH_LEVEL;
    ((PSR *)(&CxFrame->Psr))->MODE = 0;

    //
    // Set the initial kernel stack pointer.
    //

    Thread->KernelStack = (PVOID)(ULONGLONG)(LONG_PTR)CxFrame;
    return;
}
Exemple #4
0
VOID
Ke386SetIOPL(
    IN PKPROCESS Process
    )

/*++

Routine Description:

    Gives IOPL to the specified process.

    All threads created from this point on will get IOPL.  The current
    process will get IOPL.  Must be called from context of thread and
    process that are to have IOPL.

    Iopl (to be made a boolean) in KPROCESS says all
    new threads to get IOPL.

    Iopl (to be made a boolean) in KTHREAD says given
    thread to get IOPL.

    N.B.    If a kernel mode only thread calls this procedure, the
            result is (a) poinless and (b) will break the system.

Arguments:

    Process - Pointer to the process == IGNORED!!!

Return Value:

    none

--*/

{

    PKTHREAD    Thread;
    PKPROCESS   Process2;
    PKTRAP_FRAME    TrapFrame;
    CONTEXT     Context;

    //
    // get current thread and Process2, set flag for IOPL in both of them
    //

    Thread = KeGetCurrentThread();
    Process2 = Thread->ApcState.Process;

    Process2->Iopl = 1;
    Thread->Iopl = 1;

    //
    // Force IOPL to be on for current thread
    //

    TrapFrame = (PKTRAP_FRAME)((PUCHAR)Thread->InitialStack -
                ALIGN_UP(sizeof(KTRAP_FRAME),KTRAP_FRAME_ALIGN) -
                sizeof(FX_SAVE_AREA));

    Context.ContextFlags = CONTEXT_CONTROL;
    KeContextFromKframes(TrapFrame,
                         NULL,
                         &Context);

    Context.EFlags |= (EFLAGS_IOPL_MASK & -1);  // IOPL == 3

    KeContextToKframes(TrapFrame,
                       NULL,
                       &Context,
                       CONTEXT_CONTROL,
                       UserMode);

    return;
}
Exemple #5
0
VOID
KiRestoreProcessorState (
    IN PKTRAP_FRAME TrapFrame,
    IN PKEXCEPTION_FRAME ExceptionFrame
    )

/*++

Routine Description:

    This function restores the processor state to the specified exception
    and trap frames, and restores the processor control state.

Arguments:

    TrapFrame - Supplies a pointer to a trap frame.

    ExceptionFrame - Supplies a pointer to an exception frame.

Return Value:

    None.

--*/

{

#if !defined(NT_UP)

    PKPRCB Prcb;
    KPROCESSOR_MODE PreviousMode;

    //
    // Get the address of the current processor block, move the specified
    // register state from the processor context structure to the specified
    // trap and exception frames, and restore the processor control state.
    //

    if ((TrapFrame->SegCs & MODE_MASK) != 0) {
        PreviousMode = UserMode;
    } else {
        PreviousMode = KernelMode;
    }

    Prcb = KeGetCurrentPrcb();
    KeContextToKframes(TrapFrame,
                       ExceptionFrame,
                       &Prcb->ProcessorState.ContextFrame,
                       CONTEXT_FULL,
                       PreviousMode);

    KiRestoreProcessorControlState(&Prcb->ProcessorState);

#else

    UNREFERENCED_PARAMETER(TrapFrame);
    UNREFERENCED_PARAMETER(ExceptionFrame);

#endif

    return;
}