mirror of
https://github.com/reactos/reactos.git
synced 2024-10-18 15:07:43 +00:00
[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. svn path=/trunk/; revision=45381
This commit is contained in:
parent
d25de563d3
commit
66bdab40af
|
@ -491,6 +491,30 @@ KiUserSystemCall(IN PKTRAP_FRAME TrapFrame)
|
|||
);
|
||||
}
|
||||
|
||||
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 @@ VOID
|
|||
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,13 +740,8 @@ KiEnterInterruptTrap(IN PKTRAP_FRAME TrapFrame)
|
|||
}
|
||||
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();
|
||||
|
@ -760,24 +777,8 @@ VOID
|
|||
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();
|
||||
|
|
Loading…
Reference in a new issue