Allow the initcall tables to be emitted using relative references that are only half the size on 64-bit architectures and don't require fixups at runtime on relocatable kernels.
Unified · Split
| @@ -116,8 +116,24 @@ · 115 unmodified lines | ||
| 116 | 116 | typedef int (*initcall_t)(void); |
| 117 | 117 | typedef void (*exitcall_t)(void); |
| 118 | 118 | |
| 119 | −extern initcall_t __con_initcall_start[], __con_initcall_end[]; | |
| 120 | −extern initcall_t __security_initcall_start[], __security_initcall_end[]; | |
| 119 | +#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS | |
| 120 | +typedef int initcall_entry_t; | |
| 121 | + | |
| 122 | +static inline initcall_t initcall_from_entry(initcall_entry_t *entry) | |
| 123 | +{ | |
| 124 | + return offset_to_ptr(entry); | |
| 125 | +} | |
| 126 | +#else | |
| 127 | +typedef initcall_t initcall_entry_t; | |
| 128 | + | |
| 129 | +static inline initcall_t initcall_from_entry(initcall_entry_t *entry) | |
| 130 | +{ | |
| 131 | + return *entry; | |
| 132 | +} | |
| 133 | +#endif | |
| 134 | + | |
| 135 | +extern initcall_entry_t __con_initcall_start[], __con_initcall_end[]; | |
| 136 | +extern initcall_entry_t __security_initcall_start[], __security_initcall_end[]; | |
| 121 | 137 | |
| 122 | 138 | /* Used for contructor calls. */ |
| 123 | 139 | typedef void (*ctor_fn_t)(void); |
| @@ -167,9 +183,20 @@ extern bool initcall_debug; · 43 unmodified lines | ||
| 167 | 183 | * as KEEP() in the linker script. |
| 168 | 184 | */ |
| 169 | 185 | |
| 170 | −#define __define_initcall(fn, id) \ | |
| 186 | +#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS | |
| 187 | +#define ___define_initcall(fn, id, __sec) \ | |
| 188 | + __ADDRESSABLE(fn) \ | |
| 189 | + asm(".section \"" #__sec ".init\", \"a\" \n" \ | |
| 190 | + "__initcall_" #fn #id ": \n" \ | |
| 191 | + ".long " #fn " - . \n" \ | |
| 192 | + ".previous \n"); | |
| 193 | +#else | |
| 194 | +#define ___define_initcall(fn, id, __sec) \ | |
| 171 | 195 | static initcall_t __initcall_##fn##id __used \ |
| 172 | − __attribute__((__section__(".initcall" #id ".init"))) = fn; | |
| 196 | + __attribute__((__section__(#__sec ".init"))) = fn; | |
| 197 | +#endif | |
| 198 | + | |
| 199 | +#define __define_initcall(fn, id) ___define_initcall(fn, id, .initcall##id) | |
| 173 | 200 | |
| 174 | 201 | /* |
| 175 | 202 | * Early initcalls run before initializing SMP. |
| @@ -208,13 +235,8 @@ extern bool initcall_debug; · 32 unmodified lines | ||
| 208 | 235 | #define __exitcall(fn) \ |
| 209 | 236 | static exitcall_t __exitcall_##fn __exit_call = fn |
| 210 | 237 | |
| 211 | −#define console_initcall(fn) \ | |
| 212 | − static initcall_t __initcall_##fn \ | |
| 213 | − __used __section(.con_initcall.init) = fn | |
| 214 | − | |
| 215 | −#define security_initcall(fn) \ | |
| 216 | − static initcall_t __initcall_##fn \ | |
| 217 | − __used __section(.security_initcall.init) = fn | |
| 238 | +#define console_initcall(fn) ___define_initcall(fn,, .con_initcall) | |
| 239 | +#define security_initcall(fn) ___define_initcall(fn,, .security_initcall) | |
| 218 | 240 | |
| 219 | 241 | struct obs_kernel_param { |
| 220 | 242 | const char *str; |
| @@ -902,18 +902,18 @@ int __init_or_module do_one_initcall(initcall_t fn) · 901 unmodified lines | ||
| 902 | 902 | } |
| 903 | 903 | |
| 904 | 904 | |
| 905 | −extern initcall_t __initcall_start[]; | |
| 906 | −extern initcall_t __initcall0_start[]; | |
| 907 | −extern initcall_t __initcall1_start[]; | |
| 908 | −extern initcall_t __initcall2_start[]; | |
| 909 | −extern initcall_t __initcall3_start[]; | |
| 910 | −extern initcall_t __initcall4_start[]; | |
| 911 | −extern initcall_t __initcall5_start[]; | |
| 912 | −extern initcall_t __initcall6_start[]; | |
| 913 | −extern initcall_t __initcall7_start[]; | |
| 914 | −extern initcall_t __initcall_end[]; | |
| 915 | − | |
| 916 | −static initcall_t *initcall_levels[] __initdata = { | |
| 905 | +extern initcall_entry_t __initcall_start[]; | |
| 906 | +extern initcall_entry_t __initcall0_start[]; | |
| 907 | +extern initcall_entry_t __initcall1_start[]; | |
| 908 | +extern initcall_entry_t __initcall2_start[]; | |
| 909 | +extern initcall_entry_t __initcall3_start[]; | |
| 910 | +extern initcall_entry_t __initcall4_start[]; | |
| 911 | +extern initcall_entry_t __initcall5_start[]; | |
| 912 | +extern initcall_entry_t __initcall6_start[]; | |
| 913 | +extern initcall_entry_t __initcall7_start[]; | |
| 914 | +extern initcall_entry_t __initcall_end[]; | |
| 915 | + | |
| 916 | +static initcall_entry_t *initcall_levels[] __initdata = { | |
| 917 | 917 | __initcall0_start, |
| 918 | 918 | __initcall1_start, |
| 919 | 919 | __initcall2_start, |
| @@ -939,7 +939,7 @@ static char *initcall_level_names[] __initdata = { · 19 unmodified lines | ||
| 939 | 939 | |
| 940 | 940 | static void __init do_initcall_level(int level) |
| 941 | 941 | { |
| 942 | − initcall_t *fn; | |
| 942 | + initcall_entry_t *fn; | |
| 943 | 943 | |
| 944 | 944 | strcpy(initcall_command_line, saved_command_line); |
| 945 | 945 | parse_args(initcall_level_names[level], |
| @@ -950,7 +950,7 @@ static void __init do_initcall_level(int level) · 4 unmodified lines | ||
| 950 | 950 | |
| 951 | 951 | trace_initcall_level(initcall_level_names[level]); |
| 952 | 952 | for (fn = initcall_levels[level]; fn < initcall_levels[level+1]; fn++) |
| 953 | − do_one_initcall(*fn); | |
| 953 | + do_one_initcall(initcall_from_entry(fn)); | |
| 954 | 954 | } |
| 955 | 955 | |
| 956 | 956 | static void __init do_initcalls(void) |
| @@ -981,11 +981,11 @@ static void __init do_basic_setup(void) · 24 unmodified lines | ||
| 981 | 981 | |
| 982 | 982 | static void __init do_pre_smp_initcalls(void) |
| 983 | 983 | { |
| 984 | − initcall_t *fn; | |
| 984 | + initcall_entry_t *fn; | |
| 985 | 985 | |
| 986 | 986 | trace_initcall_level("early"); |
| 987 | 987 | for (fn = __initcall_start; fn < __initcall0_start; fn++) |
| 988 | − do_one_initcall(*fn); | |
| 988 | + do_one_initcall(initcall_from_entry(fn)); | |
| 989 | 989 | } |
| 990 | 990 | |
| 991 | 991 | /* |
| @@ -2788,7 +2788,8 @@ EXPORT_SYMBOL(unregister_console); · 2787 unmodified lines | ||
| 2788 | 2788 | void __init console_init(void) |
| 2789 | 2789 | { |
| 2790 | 2790 | int ret; |
| 2791 | − initcall_t *call; | |
| 2791 | + initcall_t call; | |
| 2792 | + initcall_entry_t *ce; | |
| 2792 | 2793 | |
| 2793 | 2794 | /* Setup the default TTY line discipline. */ |
| 2794 | 2795 | n_tty_init(); |
| @@ -2797,13 +2798,14 @@ void __init console_init(void) · 2 unmodified lines | ||
| 2797 | 2798 | * set up the console device so that later boot sequences can |
| 2798 | 2799 | * inform about problems etc.. |
| 2799 | 2800 | */ |
| 2800 | − call = __con_initcall_start; | |
| 2801 | + ce = __con_initcall_start; | |
| 2801 | 2802 | trace_initcall_level("console"); |
| 2802 | − while (call < __con_initcall_end) { | |
| 2803 | − trace_initcall_start((*call)); | |
| 2804 | − ret = (*call)(); | |
| 2805 | − trace_initcall_finish((*call), ret); | |
| 2806 | − call++; | |
| 2803 | + while (ce < __con_initcall_end) { | |
| 2804 | + call = initcall_from_entry(ce); | |
| 2805 | + trace_initcall_start(call); | |
| 2806 | + ret = call(); | |
| 2807 | + trace_initcall_finish(call, ret); | |
| 2808 | + ce++; | |
| 2807 | 2809 | } |
| 2808 | 2810 | } |
| 2809 | 2811 | |
| @@ -48,14 +48,17 @@ static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1] = · 47 unmodified lines | ||
| 48 | 48 | static void __init do_security_initcalls(void) |
| 49 | 49 | { |
| 50 | 50 | int ret; |
| 51 | − initcall_t *call; | |
| 52 | − call = __security_initcall_start; | |
| 51 | + initcall_t call; | |
| 52 | + initcall_entry_t *ce; | |
| 53 | + | |
| 54 | + ce = __security_initcall_start; | |
| 53 | 55 | trace_initcall_level("security"); |
| 54 | − while (call < __security_initcall_end) { | |
| 55 | − trace_initcall_start((*call)); | |
| 56 | − ret = (*call) (); | |
| 57 | − trace_initcall_finish((*call), ret); | |
| 58 | − call++; | |
| 56 | + while (ce < __security_initcall_end) { | |
| 57 | + call = initcall_from_entry(ce); | |
| 58 | + trace_initcall_start(call); | |
| 59 | + ret = call(); | |
| 60 | + trace_initcall_finish(call, ret); | |
| 61 | + ce++; | |
| 59 | 62 | } |
| 60 | 63 | } |
| 61 | 64 | |