Author: sir_richard Date: Tue Feb 2 23:56:13 2010 New Revision: 45381
URL: http://svn.reactos.org/svn/reactos?rev=45381&view=rev Log: [NTOS]: Yet another fix for KiEnterInterruptTrap: Set correct DS/ES before touching the TrapFrame. [NTOS]: Make this operation an inline so any possible future code will not make this mistake twice. Thanks to Physicus for the bug report.
Modified: trunk/reactos/ntoskrnl/include/internal/trap_x.h
Modified: trunk/reactos/ntoskrnl/include/internal/trap_x.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/t... ============================================================================== --- trunk/reactos/ntoskrnl/include/internal/trap_x.h [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/include/internal/trap_x.h [iso-8859-1] Tue Feb 2 23:56:13 2010 @@ -490,7 +490,31 @@ : "r"(TrapFrame->SegCs) ); } - + +VOID +FORCEINLINE +KiSetSaneSegments(IN PKTRAP_FRAME TrapFrame) +{ + ULONG Ds, Es; + + /* + * We really have to get a good DS/ES first before touching any data. + * + * These two reads will either go in a register (with optimizations ON) or + * a stack variable (which is on SS:ESP, guaranteed to be good/valid). + * + * Because the assembly is marked volatile, the order of instructions is + * as-is, otherwise the optimizer could simply get rid of our DS/ES. + * + */ + Ds = Ke386GetDs(); + Es = Ke386GetEs(); + Ke386SetDs(KGDT_R3_DATA | RPL_MASK); + Ke386SetEs(KGDT_R3_DATA | RPL_MASK); + TrapFrame->SegDs = Ds; + TrapFrame->SegEs = Es; +} + // // Generic Exit Routine // @@ -700,8 +724,6 @@ FORCEINLINE KiEnterInterruptTrap(IN PKTRAP_FRAME TrapFrame) { - ULONG Ds, Es; - /* Check for V86 mode, otherwise check for ring 3 code */ if (__builtin_expect(KiIsV8086TrapSafe(TrapFrame), 0)) { @@ -718,14 +740,9 @@ } else if (__builtin_expect(KiIsUserTrapSafe(TrapFrame), 1)) /* Ring 3 is more common */ { - /* Save DS/ES and load correct values */ - Es = Ke386GetEs(); - Ds = Ke386GetDs(); - TrapFrame->SegDs = Ds; - TrapFrame->SegEs = Es; - Ke386SetDs(KGDT_R3_DATA | RPL_MASK); - Ke386SetEs(KGDT_R3_DATA | RPL_MASK); - + /* Switch to sane segments */ + KiSetSaneSegments(TrapFrame); + /* Save FS/GS */ TrapFrame->SegFs = Ke386GetFs(); TrapFrame->SegGs = Ke386GetGs(); @@ -760,24 +777,8 @@ FORCEINLINE KiEnterTrap(IN PKTRAP_FRAME TrapFrame) { - ULONG Ds, Es; - - /* - * We really have to get a good DS/ES first before touching any data. - * - * These two reads will either go in a register (with optimizations ON) or - * a stack variable (which is on SS:ESP, guaranteed to be good/valid). - * - * Because the assembly is marked volatile, the order of instructions is - * as-is, otherwise the optimizer could simply get rid of our DS/ES. - * - */ - Ds = Ke386GetDs(); - Es = Ke386GetEs(); - Ke386SetDs(KGDT_R3_DATA | RPL_MASK); - Ke386SetEs(KGDT_R3_DATA | RPL_MASK); - TrapFrame->SegDs = Ds; - TrapFrame->SegEs = Es; + /* Switch to sane segments */ + KiSetSaneSegments(TrapFrame);
/* Now we can save the other segments and then switch to the correct FS */ TrapFrame->SegFs = Ke386GetFs();