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