diff options
author | Dmitry Torokhov <dtor@vmware.com> | 2011-02-07 19:02:25 -0500 |
---|---|---|
committer | Rusty Russell <rusty@rustcorp.com.au> | 2011-05-19 03:25:24 -0400 |
commit | b4bc842802db3314f9a657094da0450a903ea619 (patch) | |
tree | db9cadf46624dcd7e780850e8bda34b569a229b0 /kernel/params.c | |
parent | 61c4f2c81c61f73549928dfd9f3e8f26aa36a8cf (diff) |
module: deal with alignment issues in built-in module versions
On m68k natural alignment is 2-byte boundary but we are trying to
align structures in __modver section on sizeof(void *) boundary.
This causes trouble when we try to access elements in this section
in array-like fashion when create "version" attributes for built-in
modules.
Moreover, as DaveM said, we can't reliably put structures into
independent objects, put them into a special section, and then expect
array access over them (via the section boundaries) after linking the
objects together to just "work" due to variable alignment choices in
different situations. The only solution that seems to work reliably
is to make an array of plain pointers to the objects in question and
put those pointers in the special section.
Reported-by: Geert Uytterhoeven <geert@linux-m68k.org>
Signed-off-by: Dmitry Torokhov <dtor@vmware.com>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'kernel/params.c')
-rw-r--r-- | kernel/params.c | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/kernel/params.c b/kernel/params.c index 7ab388a48a2e..28c5d5c83f6b 100644 --- a/kernel/params.c +++ b/kernel/params.c | |||
@@ -821,15 +821,18 @@ ssize_t __modver_version_show(struct module_attribute *mattr, | |||
821 | return sprintf(buf, "%s\n", vattr->version); | 821 | return sprintf(buf, "%s\n", vattr->version); |
822 | } | 822 | } |
823 | 823 | ||
824 | extern struct module_version_attribute __start___modver[], __stop___modver[]; | 824 | extern const struct module_version_attribute *__start___modver[]; |
825 | extern const struct module_version_attribute *__stop___modver[]; | ||
825 | 826 | ||
826 | static void __init version_sysfs_builtin(void) | 827 | static void __init version_sysfs_builtin(void) |
827 | { | 828 | { |
828 | const struct module_version_attribute *vattr; | 829 | const struct module_version_attribute **p; |
829 | struct module_kobject *mk; | 830 | struct module_kobject *mk; |
830 | int err; | 831 | int err; |
831 | 832 | ||
832 | for (vattr = __start___modver; vattr < __stop___modver; vattr++) { | 833 | for (p = __start___modver; p < __stop___modver; p++) { |
834 | const struct module_version_attribute *vattr = *p; | ||
835 | |||
833 | mk = locate_module_kobject(vattr->module_name); | 836 | mk = locate_module_kobject(vattr->module_name); |
834 | if (mk) { | 837 | if (mk) { |
835 | err = sysfs_create_file(&mk->kobj, &vattr->mattr.attr); | 838 | err = sysfs_create_file(&mk->kobj, &vattr->mattr.attr); |