Comment 9 for bug 624787

Revision history for this message
In , Ryan (ryan-redhat-bugs) wrote :

Created attachment 473162
Patch that fixes this module on x86_64 by padding struct omnibook_feature to 128 bytes. Also includes some cleanup of declarations and extra dprintks for debugging above issue

Description of problem:
Package: kernel
Latest Crash: Mon 10 Jan 2011 11:14:04 AM
Command: not_applicable
Reason: BUG: unable to handle kernel paging request at 000000000000b800
Comment: This has apparently been an issue with the omnibook module since kernel 2.6.33. Without this module, I'm unable to use laptop-specific keys and functions, or to get suspend/hibernate to work. What's worse is that without this module the fan speed control is broken, and so my laptop can easily overheat and shut down under high CPU loads.
Bug Reports: Kernel oops report was uploaded

Version-Release number of selected component (if applicable):
kmod-omnibook-2.6.35.10-74.fc14.x86_64.x86_64 and akmod-omnibook

How reproducible:
# modprobe omnibook

Steps to Reproduce:
1. Install akmod- or kmod-omnibook
2. Attempt to load it via modprobe
3. Module crashes during init, generates kernel oops

Actual results:
Crashed module, cannot be removed via modprobe -r

Expected results:
Omnibook laptop functionality enabled

Additional info:
 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.