kbuild: soften modpost checks when doing cross builds

The module alias support in the kernel have a consistency
check where it is checked that the size of a structure
in the kernel and on the build host are the same.
For cross builds this check does not make sense so detect
when we do cross builds and silently skip the check in these
situations.
This fixes a build bug for a wireless driver when cross building
for arm.

Acked-by: Michael Buesch <mb@bu3sch.de>
Tested-by: Gordon Farquharson <gordonfarquharson@gmail.com>
Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
Cc: stable@kernel.org

+15 -3
+1 -1
Makefile
··· 189 # Alternatively CROSS_COMPILE can be set in the environment. 190 # Default value for CROSS_COMPILE is not to prefix executables 191 # Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile 192 - 193 ARCH ?= $(SUBARCH) 194 CROSS_COMPILE ?= 195
··· 189 # Alternatively CROSS_COMPILE can be set in the environment. 190 # Default value for CROSS_COMPILE is not to prefix executables 191 # Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile 192 + export KBUILD_BUILDHOST := $(SUBARCH) 193 ARCH ?= $(SUBARCH) 194 CROSS_COMPILE ?= 195
+5 -1
scripts/Makefile.modpost
··· 58 # Stop after building .o files if NOFINAL is set. Makes compile tests quicker 59 _modpost: $(if $(KBUILD_MODPOST_NOFINAL), $(modules:.ko:.o),$(modules)) 60 61 62 # Step 2), invoke modpost 63 # Includes step 3,4 ··· 73 $(if $(CONFIG_DEBUG_SECTION_MISMATCH),,-S) \ 74 $(if $(CONFIG_MARKERS),-K $(kernelmarkersfile)) \ 75 $(if $(CONFIG_MARKERS),-M $(markersfile)) \ 76 - $(if $(KBUILD_EXTMOD)$(KBUILD_MODPOST_WARN),-w) 77 78 quiet_cmd_modpost = MODPOST $(words $(filter-out vmlinux FORCE, $^)) modules 79 cmd_modpost = $(modpost) -s
··· 58 # Stop after building .o files if NOFINAL is set. Makes compile tests quicker 59 _modpost: $(if $(KBUILD_MODPOST_NOFINAL), $(modules:.ko:.o),$(modules)) 60 61 + ifneq ($(KBUILD_BUILDHOST),$(ARCH)) 62 + cross_build := 1 63 + endif 64 65 # Step 2), invoke modpost 66 # Includes step 3,4 ··· 70 $(if $(CONFIG_DEBUG_SECTION_MISMATCH),,-S) \ 71 $(if $(CONFIG_MARKERS),-K $(kernelmarkersfile)) \ 72 $(if $(CONFIG_MARKERS),-M $(markersfile)) \ 73 + $(if $(KBUILD_EXTMOD)$(KBUILD_MODPOST_WARN),-w) \ 74 + $(if $(cross_build),-c) 75 76 quiet_cmd_modpost = MODPOST $(words $(filter-out vmlinux FORCE, $^)) modules 77 cmd_modpost = $(modpost) -s
+4
scripts/mod/file2alias.c
··· 51 sprintf(str + strlen(str), "*"); \ 52 } while(0) 53 54 /** 55 * Check that sizeof(device_id type) are consistent with size of section 56 * in .o file. If in-consistent then userspace and kernel does not agree 57 * on actual size which is a bug. 58 * Also verify that the final entry in the table is all zeros. 59 **/ 60 static void device_id_check(const char *modname, const char *device_id, 61 unsigned long size, unsigned long id_size, ··· 66 int i; 67 68 if (size % id_size || size < id_size) { 69 fatal("%s: sizeof(struct %s_device_id)=%lu is not a modulo " 70 "of the size of section __mod_%s_device_table=%lu.\n" 71 "Fix definition of struct %s_device_id "
··· 51 sprintf(str + strlen(str), "*"); \ 52 } while(0) 53 54 + unsigned int cross_build = 0; 55 /** 56 * Check that sizeof(device_id type) are consistent with size of section 57 * in .o file. If in-consistent then userspace and kernel does not agree 58 * on actual size which is a bug. 59 * Also verify that the final entry in the table is all zeros. 60 + * Ignore both checks if build host differ from target host and size differs. 61 **/ 62 static void device_id_check(const char *modname, const char *device_id, 63 unsigned long size, unsigned long id_size, ··· 64 int i; 65 66 if (size % id_size || size < id_size) { 67 + if (cross_build != 0) 68 + return; 69 fatal("%s: sizeof(struct %s_device_id)=%lu is not a modulo " 70 "of the size of section __mod_%s_device_table=%lu.\n" 71 "Fix definition of struct %s_device_id "
+4 -1
scripts/mod/modpost.c
··· 2026 int opt; 2027 int err; 2028 2029 - while ((opt = getopt(argc, argv, "i:I:msSo:awM:K:")) != -1) { 2030 switch (opt) { 2031 case 'i': 2032 kernel_read = optarg; ··· 2034 case 'I': 2035 module_read = optarg; 2036 external_module = 1; 2037 break; 2038 case 'm': 2039 modversions = 1;
··· 2026 int opt; 2027 int err; 2028 2029 + while ((opt = getopt(argc, argv, "i:I:cmsSo:awM:K:")) != -1) { 2030 switch (opt) { 2031 case 'i': 2032 kernel_read = optarg; ··· 2034 case 'I': 2035 module_read = optarg; 2036 external_module = 1; 2037 + break; 2038 + case 'c': 2039 + cross_build = 1; 2040 break; 2041 case 'm': 2042 modversions = 1;
+1
scripts/mod/modpost.h
··· 135 }; 136 137 /* file2alias.c */ 138 void handle_moddevtable(struct module *mod, struct elf_info *info, 139 Elf_Sym *sym, const char *symname); 140 void add_moddevtable(struct buffer *buf, struct module *mod);
··· 135 }; 136 137 /* file2alias.c */ 138 + extern unsigned int cross_build; 139 void handle_moddevtable(struct module *mod, struct elf_info *info, 140 Elf_Sym *sym, const char *symname); 141 void add_moddevtable(struct buffer *buf, struct module *mod);