views:

61

answers:

2

Hi all,

I'm looking for information relating to implementing certain CPU extensions in a kernel module. I've found something related: http://www.mirrors.docunext.com/lxr/http/source/arch/mips/kernel/unaligned.c in fact, it's the only source code that I can find that is even close.

Basically, I have a binary only shared object built with certain CPU extensions, which I need to run on a slightly older CPU which has most of the instruction set, but not the fancy new stuff. Yeah, I know it'll be rather slow, but it's better than crashing with SIGILLs.

Thanks, j

+1  A: 

i don't think you can fix this problem using a kernel module. i think you either need to run this in a VM which allows the missing instructions (I would try using XEN) or recompile the object so that it doesn't use them.

luke
I think @joe means something like the old FP emulation tricks used on old processors without FP units. I'm not sure ANYONE is doing research on this now.
Chris Kaminski
The external FP unit is actually the 2nd part of the larger picture. But I'll mess with that when I come to it. Here's an x86 example (the target CPU is ARM): if the CPU did not have support for SSE2, when it encountered a ADDPD instruction, the kernel would throw (or something else like a filter, whichever is faster) an internal SIGILL to be caught by itself (kernel module, or etc.), which would then call the specific function that implemented ADDPD. It doesn't necessarily have to be a kernel module, it could be that the kernel framework for this would have to be written, which is fine.
joe
+1  A: 

I think you can do this in userland. Install a handler for SIGILL with sigaction() and specify SA_SIGINFO. The field si_code in the siginfo_t allows distinguishing between several causes of SIGILL. For example, trying to emulate an instruction when the signal came from kill() does not make sense. The third argument to the handler points to a structure containing the CPU context at the time of the fault (see documentation). You can likely modify this and return from the signal handler, the changes taking effect; if that does not work, try setcontext().

Obviously, it will be a bit less efficient than doing it in the kernel, but cleaner and safer.

jilles