I've tracked this to an alignment issue in the initialization code. This
module uses a section(.features) directive to register all of its
features
into a portion of the .data section, and then defines a start and end
pointer via sections.lds which it pulls back into init.c. It then
iterates
over &_start_features_driver[i] to test all of the defined features, one
at
a time.
The failed paging request appears to be happening because of unexpected
linker behavior, possibly only on x86_64, and possibly due to a change in
GNU ld or gcc since 2007. I used objdump -t on omnibook.ko, and found
that
while the sizeof(omnibook_feature) was 104, the alignment was sometimes
104
and sometimes 108. This caused the array math in the feature loop to
misaddress the struct omnibook_feature found in the .feature section,
eventually leading to invalid calls and the above crash.
Now, I'm not a kernel hacker, and I haven't done any C programming since
college. I fixed this on my Toshiba Satellite L355D-S7901 running kernel
2.6.35 on arch x86_64 by padding struct omnibook_feature to 128 bytes,
via
a char pad[24] at the end of the struct. Perhaps someone who is a more
skilled C programmer or kernel hacker can think of a better way to make
this work, and to guarantee that it works on both 32 and 64 bit
architectures.
Patches available at https://bugzilla.redhat.com/show_bug.cgi?id=669239
Per Rolf Eike Beer's suggestion, I replaced char pad[24] with long pad[3]. This provides 12 bytes of padding in i686 and 24 bytes in x86_64, which should be optimal for both arches.
Patch for alignment issue causing invalid kernel paging requests, improved to work on 32 and 64 bit archs