Hi!
I have a problem with my FPU state saving changes and v86 mode.
In ke/i386/v86m_sup.S are the functions which enter/leave v86 mode...
Ki386RetToV86Mode enters v86 mode. It changes CurrentThread->InitialStack and
TSS->Esp0 to %esp to make the exception handler run below the used stack and
not overwrite it.
The exception handler (KeV86GPF) uses a PKV86M_TRAP_FRAME, which contains a
KTRAP_FRAME at the beginning and some additional info behind. This additional
info is the data on the stack of Ki386RetToV86Mode, since it sets TSS->Esp0
to %esp, the CPU will push the trap-frame below when an exception is raised
and the additional info will be after the trap-frame.
The problem is that for reserving a FX_SAVE_AREA at the top of the
kernel-stack (without changing the KTHREAD->InitialStack value) i changed
tskswitch.S to set TSS->Esp0 to NewThread->InitialStack -
sizeof(FX_SAVE_AREA), not NewThread->InitialStack. Now if it's switching away
and back to a v86 task TSS->Esp0 will be sizeof(FX_SAVE_AREA) less than
before, and the V86 exception handler will be unable to find the additional
info from Ki386RetToV86Mode's original stack.
I am not sure how to solve it. I think it could be done by
1) Adding another variable somewhere (or maybe there is already one somewhere
which is meant to be used for this) for the exception-handler stack of the
thread, which can then be used by tskswitch.S to update TSS->Esp0.
2) only substract sizeof(FX_SAVE_AREA) from InitalStack for setting up
TSS->Esp0 in tskswitch.S if the VM bit of the EFLAGS is not set. Problem is
that the CPU unsets the VM bit if using protected-mode exception handlers for
v86 tasks, so we would need to get a copy (or pointer to) the eflags pushed
by the CPU for the IRQ handler into tskswitch.S (change
PsDispatchThread/PsDispatchThreadNoLock prototypes)
All this assumes that the FPU would never be used in V86 mode (and I hope that
this assumption is correct ;-))
Any suggestions are welcome.
- blight