The test in this loop: for (b_fw = __start_builtin_fw; b_fw != __end_builtin_fw; b_fw++) { was getting completely compiled out by my gcc, 7.0.0 20160520. The result was that the loop was going beyond the end of the builtin_fw array and giving me a page fault when trying to dereference b_fw->name inside strcmp(). By using the new external array helper macros we get the expected behaviour. Reported-by: Jiri Slaby <jslaby@xxxxxxx> Cc: Dmitry Torokhov <dmitry.torokhov@xxxxxxxxx> Cc: Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx> Cc: stable@xxxxxxxxxxxxxxx Signed-off-by: Vegard Nossum <vegard.nossum@xxxxxxxxxx> --- arch/x86/kernel/cpu/microcode/core.c | 5 ++--- drivers/base/firmware_class.c | 9 +++++---- include/asm-generic/vmlinux.lds.h | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c index 5ce5155..6669746 100644 --- a/arch/x86/kernel/cpu/microcode/core.c +++ b/arch/x86/kernel/cpu/microcode/core.c @@ -91,15 +91,14 @@ static bool __init check_loader_disabled_bsp(void) return *res; } -extern struct builtin_fw __start_builtin_fw[]; -extern struct builtin_fw __end_builtin_fw[]; +DECLARE_EXTARRAY(struct builtin_fw, builtin_fw); bool get_builtin_firmware(struct cpio_data *cd, const char *name) { #ifdef CONFIG_FW_LOADER struct builtin_fw *b_fw; - for (b_fw = __start_builtin_fw; b_fw != __end_builtin_fw; b_fw++) { + ext_for_each(b_fw, builtin_fw) { if (!strcmp(name, b_fw->name)) { cd->size = b_fw->size; cd->data = b_fw->data; diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 22d1760..b85d943e6 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -9,6 +9,7 @@ #include <linux/capability.h> #include <linux/device.h> +#include <linux/extarray.h> #include <linux/module.h> #include <linux/init.h> #include <linux/timer.h> @@ -43,15 +44,14 @@ MODULE_LICENSE("GPL"); #ifdef CONFIG_FW_LOADER -extern struct builtin_fw __start_builtin_fw[]; -extern struct builtin_fw __end_builtin_fw[]; +DECLARE_EXTARRAY(struct builtin_fw, builtin_fw) static bool fw_get_builtin_firmware(struct firmware *fw, const char *name, void *buf, size_t size) { struct builtin_fw *b_fw; - for (b_fw = __start_builtin_fw; b_fw != __end_builtin_fw; b_fw++) { + ext_for_each(b_fw, builtin_fw) { if (strcmp(name, b_fw->name) == 0) { fw->size = b_fw->size; fw->data = b_fw->data; @@ -69,9 +69,10 @@ static bool fw_is_builtin_firmware(const struct firmware *fw) { struct builtin_fw *b_fw; - for (b_fw = __start_builtin_fw; b_fw != __end_builtin_fw; b_fw++) + ext_for_each(b_fw, builtin_fw) { if (fw->data == b_fw->data) return true; + } return false; } diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index 3074796..d6121ac 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -317,7 +317,7 @@ .builtin_fw : AT(ADDR(.builtin_fw) - LOAD_OFFSET) { \ VMLINUX_SYMBOL(__start_builtin_fw) = .; \ *(.builtin_fw) \ - VMLINUX_SYMBOL(__end_builtin_fw) = .; \ + VMLINUX_SYMBOL(__stop_builtin_fw) = .; \ } \ \ TRACEDATA \ -- 2.10.0.479.g221bd91 -- To unsubscribe from this list: send the line "unsubscribe stable" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html