One of the problems I’ve run into while trying to get a PMC driver up-and-running is that several fundamental operations used to set up the counters have to be run at ring-0. In Minix, only the kernel can do this (my driver runs as a user-level process), so I have to request the kernel carry out these operations for me. Even the kernel only runs the code it has to at ring-0, using a function called level0(). This function takes a single function pointer, and runs it at ring-0.
My problem with this is that the function you hand in can’t have any arguements with it. There was no way I was going to make new functions for every event or value I might set a counter to, so I modified it in such a way as to allow arguements to be passed in as well. Many thanks go out to Tomas Hruby for coming up with this and working with me through the details of it.
The old version would go as follows:
level0(foo);
Where foo() is some function that you want to run at ring-0. Notice it doesn’t have any ()’s after it; thats because its a function pointer, and function pointers cant take arguements. This is how the new version goes:
level0(foo, args);
Where args is a pointer (void*) to a structure containing your arguements. foo() will need to know how to dereference this pointer, but for example you could point to a structure that has multiple arguements, allowing you to effectively pass in multiple arguements.
Yes, I understand there is a security concern with this, so I wouldnt expect to see it in the trunk soon (if at all). My arguement is that having an anonymous arguements pointer is no less secure than the anonymous function pointer, but it may be dereferencing arguements that aren’t well secured. For now I’m not *too* worried about the security implications of this, as my branch is not as destined for merging to the general populace as the other GSoC projects (as its kind of processor-specific), but it’s something I’ll look into in the future.
Right now my new level0() function is sitting beside the old one, but it will eventually replace it. It is level0_ajray and level0_call_ajr respectively in my trunk (check out kernel/arch/i386/klib386.s and mpx386.s).