module: deal with alignment issues in built-in module versions
Subsystems (2)
PATCH 1/3 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.
--- include/linux/module.h | 10 +++++----- kernel/params.c | 9 ++++++--- 2 files changed, 11 insertions(+), 8 deletions(-)
include/linux/module.h +5 -5
@@ -174,10 +174,7 @@ extern struct module __this_module;#define MODULE_VERSION (_version) \ extern ssize_t __modver_version_show(struct module_attribute *, \ struct module *, char *); \ - static struct module_version_attribute __modver_version_attr \ - __used \ - __attribute__ ((__section__ ("__modver"),aligned(sizeof(void *)))) \ - = { \ + static struct module_version_attribute ___modver_attr = { \ .mattr = { \ .attr = { \ .name = "version", \
@@ -187,7 +184,10 @@ extern struct module __this_module; }, \ .module_name = KBUILD_MODNAME, \ .version = _version, \ - } + }; \ +static const struct module_version_attribute \ + __used __attribute__ ((__section__ ("__modver"))) \ + * __moduleparam_const __modver_attr = &___modver_attr#endif /* Optional firmware file (or files) needed by the module
kernel/params.c +6 -3
@@ -821,15 +821,18 @@ ssize_t __modver_version_show(struct module_attribute *mattr,return sprintf (buf,"%s\n" , vattr->version); } -extern struct module_version_attribute __start___modver[], __stop___modver[]; +extern const struct module_version_attribute *__start___modver[]; +extern const struct module_version_attribute *__stop___modver[];static void __init version_sysfs_builtin (void ) { -const struct module_version_attribute *vattr; +const struct module_version_attribute **p;struct module_kobject *mk;int err; -for (vattr = __start___modver; vattr < __stop___modver; vattr++) { +for (p = __start___modver; p < __stop___modver; p++) { +const struct module_version_attribute *vattr = *p; + mk =locate_module_kobject (vattr->module_name);if (mk) { err =sysfs_create_file (&mk->kobj, &vattr->mattr.attr);
Signature · 1 line
1.7.3.2
PATCH 2/3 module: deal with alignment issues in built-in module parameters
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.
--- include/linux/moduleparam.h | 14 ++++++++------ kernel/params.c | 10 ++++++---- 2 files changed, 14 insertions(+), 10 deletions(-)
include/linux/moduleparam.h +8 -6
@@ -147,15 +147,17 @@ struct kparam_arrayBUILD_BUG_ON_ZERO ((perm) <0 || (perm) >0777 || ((perm) &2 )) \ +BUILD_BUG_ON_ZERO (sizeof ("" prefix) >MAX_PARAM_PREFIX_LEN ); \ static const char __param_str_##name[] = prefix #name; \ - static struct kernel_param __moduleparam_const __param_##name \ - __used \ - __attribute__ ((unused,__section__ ("__param"),aligned(sizeof(void *)))) \ - = { __param_str_##name, ops, perm, isbool ? KPARAM_ISBOOL : 0, \ - { arg } } + static const struct kernel_param ___param_##name = { \ + __param_str_##name, ops, perm, isbool ? KPARAM_ISBOOL : 0, \ + { arg } \ + }; \ + static const struct kernel_param \ + __used __attribute__ ((__section__ ("__param"))) \ + * __moduleparam_const __param_##name = &___param_##name/* Obsolete - use module_param_cb() */ #define module_param_call (name, set, get, arg, perm) \ - static struct kernel_param_ops __param_ops_##name = \ + static const struct kernel_param_ops __param_ops_##name = \ { (void *)set, (void *)get }; \ __module_param_call(MODULE_PARAM_PREFIX, \ name, &__param_ops_##name, arg, \
kernel/params.c +6 -4
@@ -498,7 +498,8 @@ EXPORT_SYMBOL(param_ops_string);#define to_module_attr (n) container_of(n, struct module_attribute, attr)#define to_module_kobject (n) container_of(n, struct module_kobject, kobj) -extern struct kernel_param __start___param[], __stop___param[]; +extern const struct kernel_param *__start___param[]; +extern const struct kernel_param *__stop___param[];struct param_attribute {
@@ -754,7 +755,7 @@ static struct module_kobject * __init locate_module_kobject(const char *name) }static void __init kernel_add_sysfs_param (const char *name, -struct kernel_param *kparam, +const struct kernel_param *kparam,unsigned int name_skip) {struct module_kobject *mk;
@@ -789,11 +790,12 @@ static void __init kernel_add_sysfs_param(const char *name,*/ static void __init param_sysfs_builtin (void ) { -struct kernel_param *kp; +const struct kernel_param **p;unsigned int name_len;char modname[MODULE_NAME_LEN ]; -for (kp = __start___param; kp < __stop___param; kp++) { +for (p = __start___param; p < __stop___param; p++) { +const struct kernel_param *kp = *p;char *dot;if (kp->perm ==0 )
Signature · 1 line
1.7.3.2
PATCH 3/3 module: do not hide __modver_version_show declaration behind ifdef
In reply to Dmitry TorokhovDoing so prevents the following warning from sparse:
CHECK kernel/params.ckernel/params.c:817:9: warning: symbol '__modver_version_show' was not declared. Should it be static?
since kernel/params.c is never compiled with MODULE being set.
--- include/linux/module.h | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-)
include/linux/module.h +3 -2
@@ -64,6 +64,9 @@ struct module_version_attribute {const char *version; }; +extern ssize_t __modver_version_show (struct module_attribute *, +struct module *,char *); +struct module_kobject {struct kobject kobj;
@@ -172,8 +175,6 @@ extern struct module __this_module;#define MODULE_VERSION (_version) MODULE_INFO(version, _version)#else #define MODULE_VERSION (_version) \ - extern ssize_t __modver_version_show(struct module_attribute *, \ - struct module *, char *); \ static struct module_version_attribute ___modver_attr = { \ .mattr = { \ .attr = { \
Signature · 1 line
1.7.3.2
Quoted 14 lines · Dmitry Torokhov
On m68k natural alignment is 2-byte boundary but we are trying to align structures in
__modversection onsizeof(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.
Quoted 2 lines
Reported-by Geert Uytterhoeven <[email protected]>Signed-off-by Dmitry Torokhov <[email protected]>
Thanks!
Quoted 67 lines
---
include/linux/module.h | 10 +++++-----
kernel/params.c | 9 ++++++---2 files changed, 11 insertions(+), 8 deletions(-)include/linux/module.h +5
-5@@ -174,10 +174,7 @@ extern struct module __this_module; #define MODULE_VERSION(_version) \ extern ssize_t __modver_version_show(struct module_attribute *, \ struct module *, char *); \ - static struct module_version_attribute __modver_version_attr \ - __used \ - __attribute__ ((__section__ ("__modver"),aligned(sizeof(void *)))) \ - = { \ + static struct module_version_attribute ___modver_attr = { \ .mattr = { \ .attr = { \ .name = "version", \@@ -187,7 +184,10 @@ extern struct module __this_module; }, \ .module_name = KBUILD_MODNAME, \ .version = _version, \ - } + }; \ + static const struct module_version_attribute \ + __used __attribute__ ((__section__ ("__modver"))) \ + * __moduleparam_const __modver_attr = &___modver_attr #endif /* Optional firmware file (or files) needed by the modulekernel/params.c +6
-4@@ -821,15 +821,18 @@ ssize_t __modver_version_show(struct module_attribute *mattr, return sprintf(buf, "%s\n", vattr->version); } -extern struct module_version_attribute __start___modver[], __stop___modver[]; +extern const struct module_version_attribute *__start___modver[]; +extern const struct module_version_attribute *__stop___modver[]; static void __init version_sysfs_builtin(void) { - const struct module_version_attribute *vattr; + const struct module_version_attribute **p; struct module_kobject *mk; int err; - for (vattr = __start___modver; vattr < __stop___modver; vattr++) { + for (p = __start___modver; p < __stop___modver; p++) { + const struct module_version_attribute *vattr = *p; + mk = locate_module_kobject(vattr->module_name); if (mk) { err = sysfs_create_file(&mk->kobj, &vattr->mattr.attr); --1.7.3.2
--
To unsubscribe from this list: send the line "unsubscribe linux-arch" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Signature · 10 lines
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus TorvaldsQuoted 15 lines · Geert Uytterhoeven
Quoted 14 lines · Dmitry Torokhov
On m68k natural alignment is 2-byte boundary but we are trying to align structures in
__modversection onsizeof(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.
Quoted 6 lines
Quoted 2 lines
Reported-by Geert Uytterhoeven <[email protected]>Signed-off-by Dmitry Torokhov <[email protected]>Thanks!
Tested-by Geert Uytterhoeven <[email protected]>
Can we please get this in? 2.6.38-rc5 still crashes on m68k.
Thx!
Quoted 52 lines
Quoted 52 lines
---
include/linux/module.h | 10 +++++-----
kernel/params.c | 9 ++++++---2 files changed, 11 insertions(+), 8 deletions(-)include/linux/module.h +5
-5@@ -174,10 +174,7 @@ extern struct module __this_module; #define MODULE_VERSION(_version) \ extern ssize_t __modver_version_show(struct module_attribute *, \ struct module *, char *); \ - static struct module_version_attribute __modver_version_attr \ - __used \ - __attribute__ ((__section__ ("__modver"),aligned(sizeof(void *)))) \ - = { \ + static struct module_version_attribute ___modver_attr = { \ .mattr = { \ .attr = { \ .name = "version", \@@ -187,7 +184,10 @@ extern struct module __this_module; }, \ .module_name = KBUILD_MODNAME, \ .version = _version, \ - } + }; \ + static const struct module_version_attribute \ + __used __attribute__ ((__section__ ("__modver"))) \ + * __moduleparam_const __modver_attr = &___modver_attr #endif /* Optional firmware file (or files) needed by the modulekernel/params.c +3
-2@@ -821,15 +821,18 @@ ssize_t __modver_version_show(struct module_attribute *mattr, return sprintf(buf, "%s\n", vattr->version); } -extern struct module_version_attribute __start___modver[], __stop___modver[]; +extern const struct module_version_attribute *__start___modver[]; +extern const struct module_version_attribute *__stop___modver[]; static void __init version_sysfs_builtin(void) { - const struct module_version_attribute *vattr; + const struct module_version_attribute **p; struct module_kobject *mk; int err;
Quoted 9 lines
Quoted 9 lines
kernel/params.c +3
-2- for (vattr = __start___modver; vattr < __stop___modver; vattr++) { + for (p = __start___modver; p < __stop___modver; p++) { + const struct module_version_attribute *vattr = *p; + mk = locate_module_kobject(vattr->module_name); if (mk) { err = sysfs_create_file(&mk->kobj, &vattr->mattr.attr); --1.7.3.2
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]
In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
PATCH v2 1/1 module: deal with alignment issues in built-in module parameters
In reply to Dmitry TorokhovQuoted 1 line
From
03f1332fc02af7af0d06ab409e3ec72107637845Mon Sep 17 00:00:00 2001
From: Dmitry Torokhov <[email protected]>
Date: Mon, 7 Feb 2011 13:47:20 -0800
Subject: [PATCH] module: deal with alignment issues in built-in module parameters
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.
---
This is v2 of the patch, hopefully fixing all the issues that were presented in the original submission, namely:
- fix for kparam_[un]block_sysfs_write() breakage;
- convert non-built-in module parameter case to expect array of pointers to struct kernel_param, not array of the structures themselves.
Thanks,
Dmitry
include/linux/module.h | 2 +- include/linux/moduleparam.h | 24 ++++++++++++---------- init/main.c | 2 +- kernel/module.c | 2 +- kernel/params.c | 45 +++++++++++++++++++++++------------------- 5 files changed, 41 insertions(+), 34 deletions(-)
include/linux/module.h +1 -1
@@ -292,7 +292,7 @@ struct moduleunsigned int num_syms;/* Kernel parameters. */ -struct kernel_param *kp; +const struct kernel_param **kp;unsigned int num_kp;/* GPL-only exported symbols. */
include/linux/moduleparam.h +13 -11
@@ -147,15 +147,17 @@ struct kparam_arrayBUILD_BUG_ON_ZERO ((perm) <0 || (perm) >0777 || ((perm) &2 )) \ +BUILD_BUG_ON_ZERO (sizeof ("" prefix) >MAX_PARAM_PREFIX_LEN ); \ static const char __param_str_##name[] = prefix #name; \ - static struct kernel_param __moduleparam_const __param_##name \ - __used \ - __attribute__ ((unused,__section__ ("__param"),aligned(sizeof(void *)))) \ - = { __param_str_##name, ops, perm, isbool ? KPARAM_ISBOOL : 0, \ - { arg } } + static const struct kernel_param __param_##name = { \ + __param_str_##name, ops, perm, isbool ? KPARAM_ISBOOL : 0, \ + { arg } \ + }; \ + static const struct kernel_param \ + __used __attribute__ ((__section__ ("__param"))) \ + * __moduleparam_const ___param_##name = &__param_##name/* Obsolete - use module_param_cb() */ #define module_param_call (name, set, get, arg, perm) \ - static struct kernel_param_ops __param_ops_##name = \ + static const struct kernel_param_ops __param_ops_##name = \ { (void *)set, (void *)get }; \ __module_param_call(MODULE_PARAM_PREFIX, \ name, &__param_ops_##name, arg, \
@@ -265,15 +267,15 @@ static inline void __kernel_param_unlock(void)/* Called on module insert or kernel boot */ extern int parse_args (const char *name,char *args, -const struct kernel_param *params, +const struct kernel_param **params,unsigned num,int (*unknown)(char *param,char *val));/* Called by module remove. */ #ifdef CONFIG_SYSFS -extern void destroy_params (const struct kernel_param *params,unsigned num); +extern void destroy_params (const struct kernel_param **params,unsigned num);#else -static inline void destroy_params (const struct kernel_param *params, +static inline void destroy_params (const struct kernel_param **params,unsigned num) { }
@@ -391,13 +393,13 @@ struct module;#if defined(CONFIG_SYSFS ) && defined(CONFIG_MODULES )extern int module_param_sysfs_setup (struct module *mod, -const struct kernel_param *kparam, +const struct kernel_param **kparam,unsigned int num_params);extern void module_param_sysfs_remove (struct module *mod);#else static inline int module_param_sysfs_setup (struct module *mod, -const struct kernel_param *kparam, +const struct kernel_param **kparam,unsigned int num_params) {return 0 ;
init/main.c +1 -1
@@ -544,7 +544,7 @@ static void __init mm_init(void) asmlinkage void __init start_kernel(void) {char * command_line; -extern const struct kernel_param __start___param[], __stop___param[]; +extern const struct kernel_param *__start___param[], *__stop___param[];smp_setup_processor_id ();
kernel/module.c +1 -1
@@ -1470,7 +1470,7 @@ out:static int mod_sysfs_setup (struct module *mod,const struct load_info *info, -struct kernel_param *kparam, +const struct kernel_param **kparam,unsigned int num_params) {int err;
kernel/params.c +25 -20
124 lines not on this page · raw message
Signature · 1 line
1.7.3.2
Re: [PATCH v2] module: deal with alignment issues in built-in module parameters
Quoted 5 lines · Dmitry Torokhov
Quoted 1 line
From
03f1332fc02af7af0d06ab409e3ec72107637845Mon Sep 17 00:00:00 2001From: Dmitry Torokhov <[email protected]>
Date: Mon, 7 Feb 2011 13:47:20 -0800
Subject: [PATCH] module: deal with alignment issues in built-in module parameters
Quoted 7 lines
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.
I've applied this, but won't put it to linux-next. I'll let it stew for a bit longer unless someone actually reports a problem with the current code.
Thanks,
Rusty.
Quoted 6 lines · Dmitry Torokhov
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.
Why not?
That's what we normally do. Just align the "__modver", and you should be all good. What's the problem?
Linus
Quoted 8 lines · Linus Torvalds
Quoted 6 lines · Dmitry Torokhov
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.
Quoted 4 lines
Why not?
That's what we normally do. Just align the "
__modver", and you should be all good. What's the problem?
From what I understand __attribute__ ((aligned(x))) only guarantees minimum alignment, not exact (gapless) alignment. GCC seems to lay out pointers in the section without gaps on all arches that we have.
Thanks.
Signature · 1 line
Dmitry
Quoted 4 lines · Dmitry Torokhov
From what I understand
__attribute__((aligned(x))) only guarantees minimum alignment, not exact (gapless) alignment. GCC seems to lay out pointers in the section without gaps on all arches that we have.
I still don't see the problem.
Have you actually _tried_ just adding the proper alignment to before the __modver thing in include/asm-generic/vmlinux.lds.h ?
As far as I can tell, the bug is really simple:
- the section is not aligned
- but we told the compiler that that structure is aligned
End result: there is a gap between the section start and the first structure.
And the fix seems obvious: just make sure that the section is sufficiently aligned.
IOW, why isn't the proper fix the obvious trivial one (attached)?
Linus
include/asm-generic/vmlinux.lds.h | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-)
include/asm-generic/vmlinux.lds.h +2 -0
@@ -358,6 +358,7 @@ } \ \/* Built-in module parameters. */ \ + STRUCT_ALIGN() \ __param : AT(ADDR(__param) - LOAD_OFFSET) { \ VMLINUX_SYMBOL(__start___param) = .; \ *(__param) \
@@ -365,6 +366,7 @@ } \ \/* Built-in module versions. */ \ + STRUCT_ALIGN() \ __modver : AT(ADDR(__modver) - LOAD_OFFSET) { \ VMLINUX_SYMBOL(__start___modver) = .; \ *(__modver) \
Quoted 15 lines · Linus Torvalds
Quoted 4 lines · Dmitry Torokhov
From what I understand
__attribute__((aligned(x))) only guarantees minimum alignment, not exact (gapless) alignment. GCC seems to lay out pointers in the section without gaps on all arches that we have.I still don't see the problem.
Have you actually _tried_ just adding the proper alignment to before the
__modverthing ininclude/asm-generic/vmlinux.lds.h?As far as I can tell, the bug is really simple:
- the section is not aligned
- but we told the compiler that that structure is aligned
Quoted 7 lines
End result: there is a gap between the section start and the first structure.
And the fix seems obvious: just make sure that the section is sufficiently aligned.
IOW, why isn't the proper fix the obvious trivial one (attached)?
The problem is that on m68k size of the struct module_version_attribute is not evenly divisible by sizeof(void *), thus when we lay out the __modver section we align on 4 bytes but when we iterate we think that the alignment is 2.
I/Geert tried adding __attribute__ (aligned(sizeof(void *))) to the type definition itself so we have matching alignment everywhere, but DaveM said that this only guarantees minimum alignment and that using structures like we do shown to break from time to time in kprobes and that only pointers worked reliably.
Thanks.
Signature · 1 line
Dmitry
Quoted 5 lines · Dmitry Torokhov
The problem is that on m68k size of the struct
module_version_attributeis not evenly divisible bysizeof(void *), thus when we lay out the__modversection we align on 4 bytes but when we iterate we think that the alignment is 2.
So mark the struct properly.
Quoted 5 lines
I/Geert tried adding
__attribute__(aligned(sizeof(void *))) to the type definition itself so we have matching alignment everywhere, but DaveM said that this only guarantees minimum alignment and that using structures like we do shown to break from time to time in kprobes and that only pointers worked reliably.
That sounds totally bogus. Minimum alignment is all it needs, and we do that in other places too. I really don't see the reason to add some broken indirection for totally broken reasons. We don't do that with anything else.
David, why are you saying that regular "just mark the structure alignment correctly" doesn't work?
Linus
From: Linus Torvalds <[email protected]>
Date: Thu, 17 Feb 2011 10:06:40 -0800
Quoted 2 lines
David, why are you saying that regular "just mark the structure alignment correctly" doesn't work?
Because it's been proven to not work:
http://marc.info/?l=linux-kernel&m=129674396021733&w=2
http://marc.info/?l=linux-kernel&m=129674399621795&w=2
http://marc.info/?l=linux-kernel&m=129674396121739&w=2
http://marc.info/?l=linux-kernel&m=129674396021735&w=2
GCC is very clever with "static" objects these days.
It thinks that, because you mark something "static", it can align it any way it wants because it controls the domain in which the object exists. It "knows" that the object can't be part of an array, and therefore no external entity can be concerned about the true "size" of the object (specifically wrt. side effects of the alignment of the object).
In these cases it takes the explicit alignment attribute as a minimum, not as an absolute requirement.
But we lie to the compiler, we mark things static then put them into a special a special section, then try to iterate over those objects globally as an array and expect the compiler to lay them all out with identical alignments and sizes everywhere.
And this doesn't work.
Quoted 2 lines · David Miller
GCC is very clever with "static" objects these days.
I'm sorry, but that simply isn't an acceptable excuse.
The thing is, we DO THIS THING ALL OVER. And the trick used in the original thing (to just turn it into a pointer array instead) _also_ does it. It just happens to do it with a pointer instead of a struct.
So no, I will not take this piece-of-crap patch based on "gcc is trying to be clever, but we can work around it by doing the same thing except now we take the drugs".
That's just stupid.
And I'm scared to see that you have apparently fed those drugs to the perf tree too.
EVERY SINGLE OF YOUR ARGUMENTS WORK FOR "pointer" TOO! It's pure happenstance that gcc doesn't decide to do clever things with them. So replacing that array of structs with array-of-pointers is just voodoo programming.
What is the crap-for-brains thing that gcc actually does, and how can we fix it _properly_ without this kind of voodoo?
Linus
From: Linus Torvalds <[email protected]>
Date: Thu, 17 Feb 2011 13:11:56 -0800
Quoted 1 line
EVERY SINGLE OF YOUR ARGUMENTS WORK FOR "pointer" TOO!
It at least will not happen at the current time, because GCC only plays these games on aggregates.
Also, for exception tables, we've avoided this problem because we emit the exception tables by hand using inline asm and therefore explicitly control all aspects of the alignment and size.
The GCC manual even documents the alignment attribute behavior.
Also, please don't shoot the messenger, I didn't make GCC behave this way but I doubt you'll have any luck undoing this behavior in the tools which therefore means as pragmatists we have to handle it one way or another.
Quoted 4 lines · David Miller
Quoted 1 line
EVERY SINGLE OF YOUR ARGUMENTS WORK FOR "pointer" TOO!
It at least will not happen at the current time, because GCC only plays these games on aggregates.
So? Do they actually promise to never do it for pointers? What makes aggregates so special? Rather than just happenstance?
I wouldn't be surprised if the structure alignment isn't even about something even subtler and totally random, like size of structure (ie "don't align small structures")
Quoted 3 lines
Also, for exception tables, we've avoided this problem because we emit the exception tables by hand using inline asm and therefore explicitly control all aspects of the alignment and size.
.. and maybe that's the right thing to do here too.
Quoted 1 line
The GCC manual even documents the alignment attribute behavior.
The gcc manual is worthless. Every time some gcc person wants to change behavior, they just change the manual. So you can't rely on it anyway. We've seen that with inline asm before etc.
Quoted 4 lines
Also, please don't shoot the messenger, I didn't make GCC behave this way but I doubt you'll have any luck undoing this behavior in the tools which therefore means as pragmatists we have to handle it one way or another.
I'm shooting not the messenger, but the people who make these kinds of really ugly changes with bad changelogs that don't even explain what the actual problem is. And apparently any gcc person is free to break it in the future _anyway_.
Is there a -fdata-align or something? Or would __attribute__((packed)) help? Something that explicitly tells gcc "don't do this", instead of "let's add indirection and hope gcc doesn't add alignment for _that_". Especially as the extra pointer makes the code even uglier.
And if we do have to use the pointer thing, let's at least then do the pointer with asms, so that gcc _really_ can't screw it up. Rather than just move the potential bug around.
Linus
From: Linus Torvalds <[email protected]>
Date: Thu, 17 Feb 2011 13:54:57 -0800
Quoted 4 lines
Is there a -fdata-align or something? Or would __attribute__((packed)) help? Something that explicitly tells gcc "don't do this", instead of "let's add indirection and hope gcc doesn't add alignment for _that_". Especially as the extra pointer makes the code even uglier.
The tracing folks went down the path of trying to use packed in various ways, to no avail, because no matter what they tried it broke other things.
Quoted 3 lines
And if we do have to use the pointer thing, let's at least then do the pointer with asms, so that gcc _really_ can't screw it up. Rather than just move the potential bug around.
That's fine with me.
Quoted 12 lines · David Miller
From: Linus Torvalds <[email protected]>
Date: Thu, 17 Feb 2011 13:54:57 -0800Quoted 4 lines
Is there a -fdata-align or something? Or would __attribute__((packed)) help? Something that explicitly tells gcc "don't do this", instead of "let's add indirection and hope gcc doesn't add alignment for _that_". Especially as the extra pointer makes the code even uglier.
The tracing folks went down the path of trying to use packed in various ways, to no avail, because no matter what they tried it broke other things.
Quoted 5 lines
Quoted 3 lines
And if we do have to use the pointer thing, let's at least then do the pointer with asms, so that gcc _really_ can't screw it up. Rather than just move the potential bug around.
That's fine with me.
Any pointers as to how to emit these pointers with asm?
Signature · 1 line
Dmitry
From: Dmitry Torokhov <[email protected]>
Date: Thu, 17 Feb 2011 14:19:57 -0800
Quoted 1 line
Any pointers as to how to emit these pointers with asm?
.section FOO_SECTION, "a"
.align SIZEOF_POINTER
.{,x}word POINTER
.previousWhere FOO_SECTION is your special section name, SIZEOF_POINTER is sizeof(void *), and POINTER is the pointer you want to add to the section.
You have to also pick .word vs. .xword, or whatever the appropriate sized pointer mnenomic is for a given architecture. I know .word works for 32-bit sparc, and .xword works for 64-bit sparc.
Quoted 4 lines · David Miller
You have to also pick .word vs. .xword, or whatever the appropriate sized pointer mnenomic is for a given architecture. I know .word works for 32-bit sparc, and .xword works for 64-bit sparc.
Gaah, I didn't realize that we've never had to do anything like this before, and that the exception table is all arch-specific code. So we don't have any way to "output that damned pointer and stop whining about it" model at all.
I really detest gcc sometimes. All these "clever" things that just make things harder to do. If the user explicitly tells it the section and the alignment, it should damn well not think that it knows better and change it. Damn.
Maybe we have to take the "just confuse gcc enough and pray" approach on those pointers after all.
Linus
Quoted 5 lines · Linus Torvalds
Gaah, I didn't realize that we've never had to do anything like this before, and that the exception table is all arch-specific code. So we don't have any way to "output that damned pointer and stop whining about it" model at all.
Actually, I don't think the problem is about ".word" vs ".xword". We should be able to just use ".long" everywhere.
But the symbol _name_ may have different prefixes, and when we use "asm()" at the top level, we can't use the expressions to fix it up. So a
asm(".long %0":'i" (symbol))
doesn't work (ignore the lack of section naming, that's not important), and neither can we just do something like
#define output_asm_pointer(section, symbol) \
asm(".long " #symbol)portably, because some linker formats want to see prepended underscores etc.
Grr.
Where in gcc is the alignment expansion logic? I'd like to see what the rules are, just for my own perverse satisfaction.
Linus
From: Linus Torvalds <[email protected]>
Date: Thu, 17 Feb 2011 15:08:52 -0800
Quoted 2 lines
Where in gcc is the alignment expansion logic? I'd like to see what the rules are, just for my own perverse satisfaction.
The magic that overrides the alignment various cases is in the x86 specific code:
gcc/config/i386/i386.c
ix86_data_alignment() and ix86_local_alignment()
Quoted 17 lines · Linus Torvalds
Quoted 5 lines · Linus Torvalds
Gaah, I didn't realize that we've never had to do anything like this before, and that the exception table is all arch-specific code. So we don't have any way to "output that damned pointer and stop whining about it" model at all.
Actually, I don't think the problem is about ".word" vs ".xword". We should be able to just use ".long" everywhere.
But the symbol _name_ may have different prefixes, and when we use "
asm()" at the top level, we can't use the expressions to fix it up. So a
asm(".long %0":'i" (symbol))
Quoted 7 lines
doesn't work (ignore the lack of section naming, that's not important), and neither can we just do something like
#define output_asm_pointer(section, symbol) \ asm(".long " #symbol)portably, because some linker formats want to see prepended underscores etc.
Except that .long is 32-bit on ppc64 :-( You need .llong for 64-bit.
Cheers,
Ben.
Quoted 1 line
Except that .long is 32-bit on ppc64 :-( You need .llong for 64-bit.
OK, all options suck. Do we want the workaround or not?
Cheers,
Rusty.
Subject: module: deal with alignment issues in built-in module versions
Date: Mon, 7 Feb 2011 16:02:25 -0800
From: Dmitry Torokhov <[email protected]>
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.
--- include/linux/module.h | 10 +++++----- kernel/params.c | 9 ++++++--- 2 files changed, 11 insertions(+), 8 deletions(-)
include/linux/module.h +5 -5
@@ -174,10 +174,7 @@ extern struct module __this_module;#define MODULE_VERSION (_version) \ extern ssize_t __modver_version_show(struct module_attribute *, \ struct module *, char *); \ - static struct module_version_attribute __modver_version_attr \ - __used \ - __attribute__ ((__section__ ("__modver"),aligned(sizeof(void *)))) \ - = { \ + static struct module_version_attribute ___modver_attr = { \ .mattr = { \ .attr = { \ .name = "version", \
@@ -187,7 +184,10 @@ extern struct module __this_module; }, \ .module_name = KBUILD_MODNAME, \ .version = _version, \ - } + }; \ +static const struct module_version_attribute \ + __used __attribute__ ((__section__ ("__modver"))) \ + * __moduleparam_const __modver_attr = &___modver_attr#endif /* Optional firmware file (or files) needed by the module
kernel/params.c +6 -3
@@ -821,15 +821,18 @@ ssize_t __modver_version_show(struct module_attribute *mattr,return sprintf (buf,"%s\n" , vattr->version); } -extern struct module_version_attribute __start___modver[], __stop___modver[]; +extern const struct module_version_attribute *__start___modver[]; +extern const struct module_version_attribute *__stop___modver[];static void __init version_sysfs_builtin (void ) { -const struct module_version_attribute *vattr; +const struct module_version_attribute **p;struct module_kobject *mk;int err; -for (vattr = __start___modver; vattr < __stop___modver; vattr++) { +for (p = __start___modver; p < __stop___modver; p++) { +const struct module_version_attribute *vattr = *p; + mk =locate_module_kobject (vattr->module_name);if (mk) { err =sysfs_create_file (&mk->kobj, &vattr->mattr.attr);
Quoted 3 lines · Rusty Russell
Quoted 1 line
Except that .long is 32-bit on ppc64 :-( You need .llong for 64-bit.
OK, all options suck. Do we want the workaround or not?
We can discuss about that until someone gets bitten by that.
But please fix the "aligned(sizeof(void *))"-in-one-place-only issue.
Quoted 73 lines
Cheers,
Rusty.Subject: module: deal with alignment issues in built-in module versions
Date: Mon, 7 Feb 2011 16:02:25 -0800
From: Dmitry Torokhov <[email protected]>On m68k natural alignment is 2-byte boundary but we are trying to align structures in
__modversection onsizeof(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 <[email protected]>Signed-off-by Dmitry Torokhov <[email protected]>Signed-off-by Rusty Russell <[email protected]>---
include/linux/module.h | 10 +++++-----
kernel/params.c | 9 ++++++---2 files changed, 11 insertions(+), 8 deletions(-)include/linux/module.h +5
-5@@ -174,10 +174,7 @@ extern struct module __this_module; #define MODULE_VERSION(_version) \ extern ssize_t __modver_version_show(struct module_attribute *, \ struct module *, char *); \ - static struct module_version_attribute __modver_version_attr \ - __used \ - __attribute__ ((__section__ ("__modver"),aligned(sizeof(void *)))) \ - = { \ + static struct module_version_attribute ___modver_attr = { \ .mattr = { \ .attr = { \ .name = "version", \@@ -187,7 +184,10 @@ extern struct module __this_module; }, \ .module_name = KBUILD_MODNAME, \ .version = _version, \ - } + }; \ + static const struct module_version_attribute \ + __used __attribute__ ((__section__ ("__modver"))) \ + * __moduleparam_const __modver_attr = &___modver_attr #endif /* Optional firmware file (or files) needed by the modulekernel/params.c +3
-2@@ -821,15 +821,18 @@ ssize_t __modver_version_show(struct module_attribute *mattr, return sprintf(buf, "%s\n", vattr->version); } -extern struct module_version_attribute __start___modver[], __stop___modver[]; +extern const struct module_version_attribute *__start___modver[]; +extern const struct module_version_attribute *__stop___modver[]; static void __init version_sysfs_builtin(void) { - const struct module_version_attribute *vattr; + const struct module_version_attribute **p;
kernel/params.c ssize_t __modver_version_show(struct module_attribute *mattr, · line 838
Quoted 10 lines
kernel/params.c +3
-1struct module_kobject *mk; int err; - for (vattr = __start___modver; vattr < __stop___modver; vattr++) { + for (p = __start___modver; p < __stop___modver; p++) { + const struct module_version_attribute *vattr = *p; + mk = locate_module_kobject(vattr->module_name); if (mk) { err = sysfs_create_file(&mk->kobj, &vattr->mattr.attr);
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]
In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
Quoted 9 lines · Geert Uytterhoeven
Quoted 3 lines · Rusty Russell
Quoted 1 line
Except that .long is 32-bit on ppc64 :-( You need .llong for 64-bit.
OK, all options suck. Do we want the workaround or not?
We can discuss about that until someone gets bitten by that.
But please fix the "
aligned(sizeof(void *))"-in-one-place-only issue.
How about this one then?
Thanks.
Signature · 18 lines
Dmitry From f0e0e10b58b22047e36e21a022abf5e86b5819c2 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov <[email protected]> Date: Fri, 4 Feb 2011 13:30:10 -0800 Subject: [PATCH] module: explicitly align module_version_attribute structure We force particular alignment when we generate attribute structures when generation MODULE_VERSION() data and we need to make sure that this alignment is followed when we iterate over these structures, otherwise we may crash on platforms whose natural alignment is not sizeof(void *), such as m68k. Reported-by: Geert Uytterhoeven <[email protected]> Signed-off-by: Dmitry Torokhov <[email protected]> --- include/linux/module.h | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
include/linux/module.h +1 -1
@@ -62,7 +62,7 @@ struct module_version_attribute {struct module_attribute mattr;const char *module_name;const char *version; -}; +} __attribute__ ((__aligned__(sizeof(void *))));struct module_kobject {
Signature · 1 line
1.7.3.2
Geert Uytterhoeven
Tested-byQuoted 4 lines · Dmitry Torokhov
Quoted 3 lines · Geert Uytterhoeven
Quoted 2 lines · Rusty Russell
Quoted 1 line
Except that .long is 32-bit on ppc64 :-( You need .llong for 64-bit.
Quoted 8 lines
Quoted 6 lines
Quoted 1 line
OK, all options suck. Do we want the workaround or not?
We can discuss about that until someone gets bitten by that.
But please fix the "
aligned(sizeof(void *))"-in-one-place-only issue.How about this one then?
Works.
Quoted 5 lines
From
f0e0e10b58b22047e36e21a022abf5e86b5819c2Mon Sep 17 00:00:00 2001
From: Dmitry Torokhov <[email protected]>
Date: Fri, 4 Feb 2011 13:30:10 -0800
Subject: [PATCH] module: explicitly alignmodule_version_attributestructure
Quoted 8 lines
We force particular alignment when we generate attribute structures when generation
MODULE_VERSION()data and we need to make sure that this alignment is followed when we iterate over these structures, otherwise we may crash on platforms whose natural alignment is notsizeof(void *), such as m68k.Reported-by Geert Uytterhoeven <[email protected]>Signed-off-by Dmitry Torokhov <[email protected]>
Quoted 15 lines
---
include/linux/module.h | 2 +-1 files changed, 1 insertions(+), 1 deletions(-)include/linux/module.h +1
-1@@ -62,7 +62,7 @@ struct module_version_attribute { struct module_attribute mattr; const char *module_name; const char *version; -}; +} __attribute__ ((__aligned__(sizeof(void *))));
Quoted 4 lines
struct
module_kobject
{
--
1.7.3.2
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]
In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
Quoted 3 lines · Rusty Russell
Quoted 1 line
Except that .long is 32-bit on ppc64 :-( You need .llong for 64-bit.
OK, all options suck. Do we want the workaround or not?
The only sane thing I can see is make sure that such structures that we put into sections "arrays" like that are naturally aligned with padding.
Cheers,
Ben.
Quoted 88 lines
Cheers,
Rusty.Subject: module: deal with alignment issues in built-in module versions
Date: Mon, 7 Feb 2011 16:02:25 -0800
From: Dmitry Torokhov <[email protected]>On m68k natural alignment is 2-byte boundary but we are trying to align structures in
__modversection onsizeof(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 <[email protected]>Signed-off-by Dmitry Torokhov <[email protected]>Signed-off-by Rusty Russell <[email protected]>--- include/linux/module.h | 10 +++++----- kernel/params.c | 9 ++++++--- 2 files changed, 11 insertions(+), 8 deletions(-)include/linux/module.h +5
-5@@ -174,10 +174,7 @@ extern struct module __this_module;#define MODULE_VERSION (_version) \ extern ssize_t __modver_version_show(struct module_attribute *, \ struct module *, char *); \ - static struct module_version_attribute __modver_version_attr \ - __used \ - __attribute__ ((__section__ ("__modver"),aligned(sizeof(void *)))) \ - = { \ + static struct module_version_attribute ___modver_attr = { \ .mattr = { \ .attr = { \ .name = "version", \@@ -187,7 +184,10 @@ extern struct module __this_module; }, \ .module_name = KBUILD_MODNAME, \ .version = _version, \ - } + }; \ +static const struct module_version_attribute \ + __used __attribute__ ((__section__ ("__modver"))) \ + * __moduleparam_const __modver_attr = &___modver_attr#endif /* Optional firmware file (or files) needed by the module kernel/params.c +6
-4@@ -821,15 +821,18 @@ ssize_t __modver_version_show(struct module_attribute *mattr,return sprintf (buf,"%s\n" , vattr->version); } -extern struct module_version_attribute __start___modver[], __stop___modver[]; +extern const struct module_version_attribute *__start___modver[]; +extern const struct module_version_attribute *__stop___modver[];static void __init version_sysfs_builtin (void ) { -const struct module_version_attribute *vattr; +const struct module_version_attribute **p;struct module_kobject *mk;int err; -for (vattr = __start___modver; vattr < __stop___modver; vattr++) { +for (p = __start___modver; p < __stop___modver; p++) { +const struct module_version_attribute *vattr = *p; + mk =locate_module_kobject (vattr->module_name);if (mk) { err =sysfs_create_file (&mk->kobj, &vattr->mattr.attr); --To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Quoted 4 lines · Benjamin Herrenschmidt
The only sane thing I can see is make sure that such structures that we put into sections "arrays" like that are naturally aligned with padding.
The sad part is, that assuming I read the gcc sources correctly (see the earlier emails where David pointed to it), that alignment is:
- architecture-specific
- depends on the size of the structure
- seems to depend on the version of gcc itself.
The _one_ safe case is likely to be "structure size is a power of two". And it does look like using a pointer is going to be safe, not only because the gcc auto-alignment only triggers for things like structs/unions/arrays, but because at least the x86 code only does it if the structure was bigger than the alignment size itself.
So using pointer indirection is likely to be safe. It's still ugly and annoying as heck, though.
Linus
Quoted 13 lines · Linus Torvalds
Quoted 4 lines · Benjamin Herrenschmidt
The only sane thing I can see is make sure that such structures that we put into sections "arrays" like that are naturally aligned with padding.
The sad part is, that assuming I read the gcc sources correctly (see the earlier emails where David pointed to it), that alignment is:
- architecture-specific
- depends on the size of the structure
- seems to depend on the version of gcc itself.
Quoted 9 lines
The _one_ safe case is likely to be "structure size is a power of two". And it does look like using a pointer is going to be safe, not only because the gcc auto-alignment only triggers for things like structs/unions/arrays, but because at least the x86 code only does it if the structure was bigger than the alignment size itself.
So using pointer indirection is likely to be safe. It's still ugly and annoying as heck, though.
Regardless the approach we'll take I think the following patch is also needed (for cris architecture). I am not sure why __param section is inly defined for one specific subarch but I they need __param they'll need __modev as well.
Thanks,
Dmitry
From a567280f900c15891a55e7ea4e2919b38e1d1a01 Mon Sep 17 00:00:00 2001
From: Dmitry Torokhov <[email protected]>
Date: Thu, 17 Feb 2011 13:12:26 -0800
Subject: [PATCH] cris: add missing __modver section
Commit e94965ed5beb23c6fabf7ed31f625e66d7ff28de added a new __modver section to store module version information for drivers built into the kernel, but missed the fact that cris does some additional steps to set up sections.
--- arch/cris/kernel/vmlinux.lds.S | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-)
arch/cris/kernel/vmlinux.lds.S +4 -0
@@ -73,6 +73,10 @@ SECTIONS .init.data : { INIT_DATA } .init.setup : { INIT_SETUP(16) } #ifdef CONFIG_ETRAX_ARCH_V32 + __start___modver = .; + __modver : { *(__modver) } + __stop___modver = .; + __start___param = .; __param : { *(__param) } __stop___param = .;
Signature · 1 line
1.7.3.2
Jesper Nilsson
Acked-byQuoted 20 lines · Dmitry Torokhov
Quoted 19 lines · Linus Torvalds
Quoted 4 lines · Benjamin Herrenschmidt
The only sane thing I can see is make sure that such structures that we put into sections "arrays" like that are naturally aligned with padding.
The sad part is, that assuming I read the gcc sources correctly (see the earlier emails where David pointed to it), that alignment is:
- architecture-specific
- depends on the size of the structure
- seems to depend on the version of gcc itself.The _one_ safe case is likely to be "structure size is a power of two". And it does look like using a pointer is going to be safe, not only because the gcc auto-alignment only triggers for things like structs/unions/arrays, but because at least the x86 code only does it if the structure was bigger than the alignment size itself.
Quoted 7 lines
Quoted 3 lines
So using pointer indirection is likely to be safe. It's still ugly and annoying as heck, though.
Regardless the approach we'll take I think the following patch is also needed (for cris architecture). I am not sure why
__paramsection is inly defined for one specific subarch
That's probably just a legacy from when I combined the linkscripts for the two architectures. If I remember correctly, RODATA brings in RO_DATA_SECTION which in turn brings in __param and __modver for both architectures. CRISv32 then duplicates the __param stuff for some historical reason.
Quoted 2 lines
but I they need
__paramthey'll
need__modevas well.
True, at least until I've made sure that there isn't any underlying reason for CRISv32 to put __param in a different place...
Quoted 3 lines
Thanks,
Dmitry
/Jesper
Quoted 32 lines
Quoted 1 line
From
a567280f900c15891a55e7ea4e2919b38e1d1a01Mon Sep 17 00:00:00 2001From: Dmitry Torokhov <[email protected]>
Date: Thu, 17 Feb 2011 13:12:26 -0800
Subject: [PATCH] cris: add missing__modversectionCommit
e94965ed5beb23c6fabf7ed31f625e66d7ff28deadded a new__modversection to store module version information for drivers built into the kernel, but missed the fact that cris does some additional steps to set up sections.Signed-off-by Dmitry Torokhov <[email protected]>--- arch/cris/kernel/vmlinux.lds.S | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-)arch/cris/kernel/vmlinux.lds.S +4
-0@@ -73,6 +73,10 @@ SECTIONS .init.data : { INIT_DATA } .init.setup : { INIT_SETUP(16) } #ifdef CONFIG_ETRAX_ARCH_V32 + __start___modver = .; + __modver : { *(__modver) } + __stop___modver = .; + __start___param = .; __param : { *(__param) } __stop___param = .;Signature · 1 line
1.7.3.2
/^JN - Jesper Nilsson
Signature · 1 line
Jesper Nilsson -- [email protected]
Quoted 6 lines · Jesper Nilsson
That's probably just a legacy from when I combined the linkscripts for the two architectures. If I remember correctly, RODATA brings in
RO_DATA_SECTIONwhich in turn brings in__paramand__modverfor both architectures. CRISv32 then duplicates the__paramstuff for some historical reason.
Hmm. This makes it sound like the patch should be to remove the __param thing rather than to add the _modver thing. And I can definitely confirm that cris seems to use RODATA, which brings in the RO_DATA_SECTION() thing with proper page alignment.
But:
Quoted 4 lines
True, at least until I've made sure that there isn't any underlying reason for CRISv32 to put
__paramin a different place...Acked-by Jesper Nilsson <[email protected]>
I really am not going to apply a patch that likely just adds another redundant field to the linker scripts. So the ack I'm just ignoring,
But it would be good to get the "remove the legacy __param thing because it's already there from the asm-generic version" confirmed by testing, and not just looking at the source code.
Linus
Quoted 8 lines · Linus Torvalds
Quoted 4 lines · Jesper Nilsson
True, at least until I've made sure that there isn't any underlying reason for CRISv32 to put
__paramin a different place...Acked-by Jesper Nilsson <[email protected]>I really am not going to apply a patch that likely just adds another redundant field to the linker scripts. So the ack I'm just ignoring,
:-)
Quoted 3 lines
But it would be good to get the "remove the legacy
__paramthing because it's already there from the asm-generic version" confirmed by testing, and not just looking at the source code.
Testing shows no problems with the below patch.
Quoted 1 line
From
f8c17a94940a012f237986b4f40ca557a88f9019Mon Sep 17 00:00:00 2001
From: Jesper Nilsson <[email protected]>
Date: Wed, 23 Feb 2011 13:04:25 +0100
Subject: [PATCH] Drop redundant __param section for CRISv32.
The __param section is already brought in by RODATA above.
--- arch/cris/kernel/vmlinux.lds.S | 5 ----- 1 files changed, 0 insertions(+), 5 deletions(-)
arch/cris/kernel/vmlinux.lds.S +0 -5
@@ -75,11 +75,6 @@ SECTIONS INIT_TEXT_SECTION(PAGE_SIZE) .init.data : { INIT_DATA } .init.setup : { INIT_SETUP(16) } -#ifdef CONFIG_ETRAX_ARCH_V32 - __start___param = .; - __param : { *(__param) } - __stop___param = .; -#endif .initcall.init : { INIT_CALLS }
Signature · 1 line
1.7.4
Quoted 1 line
Linus
/^JN - Jesper Nilsson
Signature · 1 line
Jesper Nilsson -- [email protected]