aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/serial_core.h
diff options
context:
space:
mode:
authorDaniel Kurtz <djkurtz@chromium.org>2018-04-06 19:21:53 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-04-23 04:06:59 -0400
commitdd709e72cb934eefd44de8d9969097173fbf45dc (patch)
tree3933ff4050296ee7c63f984cd114c6deae36a7bf /include/linux/serial_core.h
parentef9604b622ce3b77e0ec6b566a016ddd64c5deb0 (diff)
earlycon: Use a pointer table to fix __earlycon_table stride
Commit 99492c39f39f ("earlycon: Fix __earlycon_table stride") tried to fix __earlycon_table stride by forcing the earlycon_id struct alignment to 32 and asking the linker to 32-byte align the __earlycon_table symbol. This fix was based on commit 07fca0e57fca92 ("tracing: Properly align linker defined symbols") which tried a similar fix for the tracing subsystem. However, this fix doesn't quite work because there is no guarantee that gcc will place structures packed into an array format. In fact, gcc 4.9 chooses to 64-byte align these structs by inserting additional padding between the entries because it has no clue that they are supposed to be in an array. If we are unlucky, the linker will assign symbol "__earlycon_table" to a 32-byte aligned address which does not correspond to the 64-byte aligned contents of section "__earlycon_table". To address this same problem, the fix to the tracing system was subsequently re-implemented using a more robust table of pointers approach by commits: 3d56e331b653 ("tracing: Replace syscall_meta_data struct array with pointer array") 654986462939 ("tracepoints: Fix section alignment using pointer array") e4a9ea5ee7c8 ("tracing: Replace trace_event struct array with pointer array") Let's use this same "array of pointers to structs" approach for EARLYCON_TABLE. Fixes: 99492c39f39f ("earlycon: Fix __earlycon_table stride") Signed-off-by: Daniel Kurtz <djkurtz@chromium.org> Suggested-by: Aaron Durbin <adurbin@chromium.org> Reviewed-by: Rob Herring <robh@kernel.org> Tested-by: Guenter Roeck <groeck@chromium.org> Reviewed-by: Guenter Roeck <groeck@chromium.org> Cc: stable <stable@vger.kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'include/linux/serial_core.h')
-rw-r--r--include/linux/serial_core.h21
1 files changed, 14 insertions, 7 deletions
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index 1d356105f25a..b4c9fda9d833 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -351,10 +351,10 @@ struct earlycon_id {
351 char name[16]; 351 char name[16];
352 char compatible[128]; 352 char compatible[128];
353 int (*setup)(struct earlycon_device *, const char *options); 353 int (*setup)(struct earlycon_device *, const char *options);
354} __aligned(32); 354};
355 355
356extern const struct earlycon_id __earlycon_table[]; 356extern const struct earlycon_id *__earlycon_table[];
357extern const struct earlycon_id __earlycon_table_end[]; 357extern const struct earlycon_id *__earlycon_table_end[];
358 358
359#if defined(CONFIG_SERIAL_EARLYCON) && !defined(MODULE) 359#if defined(CONFIG_SERIAL_EARLYCON) && !defined(MODULE)
360#define EARLYCON_USED_OR_UNUSED __used 360#define EARLYCON_USED_OR_UNUSED __used
@@ -362,12 +362,19 @@ extern const struct earlycon_id __earlycon_table_end[];
362#define EARLYCON_USED_OR_UNUSED __maybe_unused 362#define EARLYCON_USED_OR_UNUSED __maybe_unused
363#endif 363#endif
364 364
365#define OF_EARLYCON_DECLARE(_name, compat, fn) \ 365#define _OF_EARLYCON_DECLARE(_name, compat, fn, unique_id) \
366 static const struct earlycon_id __UNIQUE_ID(__earlycon_##_name) \ 366 static const struct earlycon_id unique_id \
367 EARLYCON_USED_OR_UNUSED __section(__earlycon_table) \ 367 EARLYCON_USED_OR_UNUSED __initconst \
368 = { .name = __stringify(_name), \ 368 = { .name = __stringify(_name), \
369 .compatible = compat, \ 369 .compatible = compat, \
370 .setup = fn } 370 .setup = fn }; \
371 static const struct earlycon_id EARLYCON_USED_OR_UNUSED \
372 __section(__earlycon_table) \
373 * const __PASTE(__p, unique_id) = &unique_id
374
375#define OF_EARLYCON_DECLARE(_name, compat, fn) \
376 _OF_EARLYCON_DECLARE(_name, compat, fn, \
377 __UNIQUE_ID(__earlycon_##_name))
371 378
372#define EARLYCON_DECLARE(_name, fn) OF_EARLYCON_DECLARE(_name, "", fn) 379#define EARLYCON_DECLARE(_name, fn) OF_EARLYCON_DECLARE(_name, "", fn)
373 380