In message: <[EMAIL PROTECTED]> "Daan Vreeken [PA4DAN]" <[EMAIL PROTECTED]> writes: : Hi Warner, : : On Wednesday 24 October 2007 23:15:13 you wrote: : > In message: <[EMAIL PROTECTED]> : > : > "Daan Vreeken [PA4DAN]" <[EMAIL PROTECTED]> writes: : > : But what I haven't found is a description of exactly what the kernel is : > : missing to allow floating point operations to be done there. : > : > FPU context is assumed to only change in user processes. You'd have : > to fix the FPU state saving code to cope with it changing everywhere, : > or you'd have to explicitly put the goo to save/restore it around the : > FP you want to do in the kernel. : : Issei Suzuki pointed me into the right direction in his reply. (The following : text is an exact copy of the reply I sent to Issei, but I'll just copy it : here to show the code) : If I understand the npx code correctly, there are 2 options when the kernel : arrives at hardclock() : : o The current process is using the FPU (fpcurthread != NULL) : o The current process hasn't used the FPU (yet) since it has been switched to : (fpcurthread == NULL) : In the first case, FPU instructions can be used and will not result in a trap, : but we should save/restore the FPU state before using them so userland : doesn't get confused. In the last case FPU instructions result in a trap, so : we need stop/start_emulating(), but as no one is using the FPU, there is no : need to save/restore it's state. : : With this in mind I've come up with the following code : : : At the start of the function : : // check FPU state on entry : if (PCPU_GET(fpcurthread) != NULL) { : // someone is using the FPU : // save it's state and remember to put it back later : restore = 1; : fpusave(&fpu_state); : } else { : // no one is using the FPU : // enable use of FPU instructions, no need to save it's state : restore = 0; : stop_emulating(); : } : // init FPU state every time we get here, as we don't know who has : // been playing with it in between calls : fninit(); : control = __INITIAL_NPXCW__; : fldcw(&control); : : Then we do some floating point arithmetic. : : And at the end of the function : : // restore FPU state before we leave : if (restore) { : // restore FPU registers to what they were : fpurstor(&fpu_state); : } else { : // no one was using the FPU, so re-enable the FPU trap : start_emulating(); : } : : With this code trap-22 has stopped to trigger within my function. The FPU : instructions still seem to be executed correctly in my function and when : adding a couple of printf()'s I can see it fpusave() and fpurstor() when : interrupting a userland process that uses the FPU. : Does this look reasonable to everyone?
My concern here would be to make sure that your code doesn't migrate from one CPU to another. Other than that, I think it is OK. Warner _______________________________________________ freebsd-hackers@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "[EMAIL PROTECTED]"