Hi,
Running the piece of code from the URL below is generating errors on various UML kernels:
http://downloads.rimuhosting.com/memtest.c
Kernels tested are: 2.4.27, 2.4.27-bs1, 2.6.9-bb4.
Different UML host servers have been tried too, and only UMLs running on SMP (dual Xeon) servers seem to have the problem (P4s with HT are fine).
Can anyone else reproduce the errors? Any ideas?
Thanks, Carl
After having found a bug in SKAS-signal-handling, I modified memtest.c to trigger that bug (attached: memtest2.c). This probably is the same problem, Carl saw. If so, Carl's problem shouldn't happen in TT-mode.
That's the problem:
In SKAS userspace(), when the kernel is entered, all regs including fpregs are saved by save_registers() to skas_regs and restored on exit by restore_registers() from skas_regs. If an signal handler has to be started, the original fpstate is saved in the sigcontext and must be restored, when sys_sigreturn is called. When the kernel is entered for sys_sigreturn on return from the signal handler, the fpregs again are saved with save_registers(). Thus skas_regs hold the fpstate from the end of the signal handler. Now copy_sc_from_user_skas() tries to restore the original state. But the fpstate from the sigcontext isn't written to skas_regs, but directly to the fp-registers of the userspace process with set_fpregs(). When exit from kernel is done after that, restore_registers() overwrites the fp-registers of the userspace-process with the fpstate from skas_regs, which is the wrong one that comes from the signal handler!
There is another problem in UML-signal-handling, that makes the problem very hard to reproduce: Normally, on sighandler-entry, the fpu-registers should be cleared. But UML doesn't clear the fpu. So, the original values in the fpu-registers stay alive, if the signal-handler doesn't push to many new values. In most cases, even if the sighandler uses the fpu, only the compare-result-flags have changed after return from sighandler. If fp-values have to be compared, AFAICS an fp-compare-instruction is used, followed immediately by a move of the compare-result-flags to the ax-register. So, only a sighandler hitting exactly between those two instructions, will hurt in most cases!
Solution:
I started to do a patch, but stopped, since it will need a big patch to make this area clean (and I will be offline for about 2 weeks ...):
1) In SKAS, copy_sc_from_user_skas() should build the _fpstate in sigcontext from skas_regs, not from new values read in by get_fpregs(). The current code even lacks writing i387_fsave_struct.status containing the magic which flags the _fpstate format. The "format" of the written _fpstate should depend on have_fpx_regs. This means, convert_fxsr_to_user_tt() should be modified and made generally available to help cover the case of (have_fpx_regs == 1), where skas_regs don't contain fsave, but fxsave only. 2) When having created a sigcontext, UML should clear the fpregs in skas_regs resp. tt_regs.sc->_fpstate, to make the sighandler see a cleared fpu. 3) copy_sc_from_user_skas() should copy the _fpstate from sigcontext to skas_regs. To handle the different formats of the _fpstate, convert_fxsr_from_user_tt() should be modified and made available. copy_sc_from_user_skas() should check sigcontext->_fpstate. If this is NULL, skas_regs.fp/fpx should be cleared. (SKAS doesn't write that NULL, but on the host or in TT, the kernel sometimes writes it. So, I would like to have SKAS tolerate a NULL here instead of segfaulting). 4) set_fpregs, get_fpregs, set_fpxregs, get_fpxregs currently support TT-mode only. set_fpxregs and get_fpxregs should return -EIO, if (!have_fpx_regs). Therefore, the check for availability of PTRACE_GET_FPXREGS should be done in SKAS and TT, and have_fpx_regs should be available in both modes. 5) get_fpregs in TT mode simply should copy the first (fp-reg) part of tt_regs.sc->fpstatus to user without converting. This part of fpstate always is written correctly by the host kernel. Also set_fpregs has to copy that part from user. If (have_fpx_regs == 1) the fpx-parts of fpstatus should be reconstructed from that, to have them available for the next possible get_fpxregs. 6) get_fpxregs and set_fpxregs in TT for (have_fpx_regs == 1) may work immediately with the fpx-part of tt_regs.sc->fpstatus, but set_fpxregs also has to write the fp-part accordingly. 7) get_fpregs, set_fpregs, get_fpxregs and set_fpxregs should support SKAS. This could be done by simply ripping code or method from i386. SKAS holds the data needed in skas_regs.fp or skas_regs.fpx
I hope, this helps a bit. Sorry for not having the time to do the patch by myself.
Bodo
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now. http://productguide.itmanagersjournal.com/
_______________________________________________
User-mode-linux-devel mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel