[ros-dev] [ros-diffs] [sir_richard] 45052: Patch that fixes VMWare boot (and should fix QEMu/KVM boot on the testbot): [NTOS]: A trap can get us into a state where DS/ES are invalid, making any pointer dereference (on DS/ES segmented memory, not SS, the stack) crash (and probably double-fault). Therefore, we have to be careful to switch to a good DS/ES before touching the TrapFrame pointer, which we don't have in ESP like the ASM code, but in a DS/ES-segmented register. For V8086 traps we can switch to the good DS/ES immediately, but for other kinds of traps, we actually need to save the current (bad) segments first. So we save them on the stack now, then switch to the good ones, then store the stack values into the trap frame. This is what happens on a non-optimized (-O0) build. On an optimized build, the segments will end up in registers instead, which is fine too (they'll be direct values). The order of instructions is guaranteed since the segment macros are volatile. [NTOS]: The GPF and Invalid Opcode handlers are performance critical when talking about V8086 traps, because they control the main flow of execution during that mode (GPFs will be issued for any privileged instruction we need to emulate, and invalid opcode might be generated for BOPs). Because of this, we employ a fast entry/exit macro into V8086 mode since we can make certain assumptions. We detect, and use, such scenarios when the V8086 flag is enabled in EFLAGS. However, because we can land in a GPF handler with an invalid DS/ES, as some V8086 code could trample this during BIOS calls for example, we must make sure that we are on a valid DS/ES before dereferencing any pointer. We fixup DS/ES either in KiEnterTrap (for normal entry/exit) or, for V86, in KiEnterV86Trap. Notice the problem: we need to detect which of these to use early on but we can't touch the EFLAGS in the frame because DS/ES could be invalid. Thankfully SS is always guaranteed valid, so stack dereferences are game! We therefore read the EFLAGS here, in assembly, where we can touch ESP as we please. We save this in EDX, which will be used as the second argument for the FASTCALL C trap entry. When we make the fast V86 check, we use the parameter instead of the trap frame, leading us to using the correct trap entry function, which fixes up DS/ES and lets us go on our merry way... [NTOS]: Make appropriate changes to GENERATE_TRAP_HANDLERS macro. [NTOS]: Switch to using well-known NT trap handler names (hex-based, double-zeroed) instead of decimal-based trap handler names which are confusing. [NTOS]: Clean up some debug spew.

Timo Kreuzer timo.kreuzer at web.de
Tue Jan 12 13:37:38 CET 2010


I suggest the following changes to the current implementation:

1.) Replace the PUSHA in the trap entry code, by a series of MOVs to the
correct stack positions. The same for the trap exit code.
KiTrapFrameFromPushaStack can be removed then. This would result in more
clear, less complex and faster code, with only  a few additional
assembly instructions in  the trap entry macro. The exit could be done
either by normal call/return or by a jmp to an exit handler.

2.) Segements should be fixed up before entering C code, as not doing so
may introduce possible compiler dependend breakages. It's also much
cleaner and there's no reason to do the same stuff later in inline
assembly instead of direcly in the asm entry point.

The resulting code might looks something like this:

    /* Allocate KTRAP_FRAME */
    sub esp, KTRAP_FRAME_LENGTH - 10 * 4

    /* Save integer registers */
    mov [esp + KTRAP_FRAME_EBP], ebp
    mov [esp + KTRAP_FRAME_EBX], ebx
    mov [esp + KTRAP_FRAME_ESI], esi
    mov [esp + KTRAP_FRAME_EDI], edi
    mov [esp + KTRAP_FRAME_EAX], eax
    mov [esp + KTRAP_FRAME_ECX], ecx
    mov [esp + KTRAP_FRAME_EDX], edx
    mov [esp + KTRAP_FRAME_EBX], ebx

    /* Save segment regs */
    mov [esp + KTRAP_FRAME_SEGDS], ds
    mov [esp + KTRAP_FRAME_SEGES], es

    /* Fixup segment regs */
    mov ax, KGDT_R3_DATA | RPL_MASK
    mov ds, ax
    mov es, ax


More information about the Ros-dev mailing list