Message ID | 20240105103305.557273-2-bhe@redhat.com (mailing list archive) |
---|---|
State | Handled Elsewhere, archived |
Headers | show |
Series | crash: clean up kdump related config items | expand |
Context | Check | Description |
---|---|---|
conchuod/vmtest-fixes-PR | fail | merge-conflict |
Hi Baoquan, kernel test robot noticed the following build errors: [auto build test ERROR on linus/master] [also build test ERROR on v6.7-rc8] [cannot apply to powerpc/next powerpc/fixes tip/x86/core arm64/for-next/core next-20240105] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Baoquan-He/kexec_core-move-kdump-related-codes-from-crash_core-c-to-kexec_core-c/20240105-223735 base: linus/master patch link: https://lore.kernel.org/r/20240105103305.557273-2-bhe%40redhat.com patch subject: [PATCH 1/5] kexec_core: move kdump related codes from crash_core.c to kexec_core.c config: x86_64-randconfig-104-20240106 (https://download.01.org/0day-ci/archive/20240106/202401061800.3XPSaPsa-lkp@intel.com/config) compiler: gcc-12 (Debian 12.2.0-14) 12.2.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240106/202401061800.3XPSaPsa-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202401061800.3XPSaPsa-lkp@intel.com/ All errors (new ones prefixed by >>): In file included from include/linux/string.h:11, from include/linux/bitmap.h:12, from include/linux/cpumask.h:12, from include/linux/smp.h:13, from arch/x86/kernel/crash.c:18: arch/x86/kernel/crash.c: In function 'fill_up_crash_elf_data': >> include/linux/overflow.h:293:23: error: invalid application of 'sizeof' to incomplete type 'struct crash_mem' 293 | sizeof(*(p)) + flex_array_size(p, member, count), \ | ^ arch/x86/kernel/crash.c:154:24: note: in expansion of macro 'struct_size' 154 | cmem = vzalloc(struct_size(cmem, ranges, nr_ranges)); | ^~~~~~~~~~~ >> include/linux/overflow.h:277:38: error: invalid use of undefined type 'struct crash_mem' 277 | (count) * sizeof(*(p)->member) + __must_be_array((p)->member), \ | ^~ include/linux/overflow.h:293:32: note: in expansion of macro 'flex_array_size' 293 | sizeof(*(p)) + flex_array_size(p, member, count), \ | ^~~~~~~~~~~~~~~ arch/x86/kernel/crash.c:154:24: note: in expansion of macro 'struct_size' 154 | cmem = vzalloc(struct_size(cmem, ranges, nr_ranges)); | ^~~~~~~~~~~ In file included from include/linux/container_of.h:5, from include/linux/kernel.h:22, from arch/x86/kernel/crash.c:17: include/linux/overflow.h:277:69: error: invalid use of undefined type 'struct crash_mem' 277 | (count) * sizeof(*(p)->member) + __must_be_array((p)->member), \ | ^~ include/linux/build_bug.h:16:62: note: in definition of macro 'BUILD_BUG_ON_ZERO' 16 | #define BUILD_BUG_ON_ZERO(e) ((int)(sizeof(struct { int:(-!!(e)); }))) | ^ include/linux/compiler.h:228:51: note: in expansion of macro '__same_type' 228 | #define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0])) | ^~~~~~~~~~~ include/linux/overflow.h:277:50: note: in expansion of macro '__must_be_array' 277 | (count) * sizeof(*(p)->member) + __must_be_array((p)->member), \ | ^~~~~~~~~~~~~~~ include/linux/overflow.h:293:32: note: in expansion of macro 'flex_array_size' 293 | sizeof(*(p)) + flex_array_size(p, member, count), \ | ^~~~~~~~~~~~~~~ arch/x86/kernel/crash.c:154:24: note: in expansion of macro 'struct_size' 154 | cmem = vzalloc(struct_size(cmem, ranges, nr_ranges)); | ^~~~~~~~~~~ include/linux/overflow.h:277:69: error: invalid use of undefined type 'struct crash_mem' 277 | (count) * sizeof(*(p)->member) + __must_be_array((p)->member), \ | ^~ include/linux/build_bug.h:16:62: note: in definition of macro 'BUILD_BUG_ON_ZERO' 16 | #define BUILD_BUG_ON_ZERO(e) ((int)(sizeof(struct { int:(-!!(e)); }))) | ^ include/linux/compiler.h:228:51: note: in expansion of macro '__same_type' 228 | #define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0])) | ^~~~~~~~~~~ include/linux/overflow.h:277:50: note: in expansion of macro '__must_be_array' 277 | (count) * sizeof(*(p)->member) + __must_be_array((p)->member), \ | ^~~~~~~~~~~~~~~ include/linux/overflow.h:293:32: note: in expansion of macro 'flex_array_size' 293 | sizeof(*(p)) + flex_array_size(p, member, count), \ | ^~~~~~~~~~~~~~~ arch/x86/kernel/crash.c:154:24: note: in expansion of macro 'struct_size' 154 | cmem = vzalloc(struct_size(cmem, ranges, nr_ranges)); | ^~~~~~~~~~~ include/linux/build_bug.h:16:51: error: bit-field '<anonymous>' width not an integer constant 16 | #define BUILD_BUG_ON_ZERO(e) ((int)(sizeof(struct { int:(-!!(e)); }))) | ^ include/linux/compiler.h:228:33: note: in expansion of macro 'BUILD_BUG_ON_ZERO' 228 | #define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0])) | ^~~~~~~~~~~~~~~~~ include/linux/overflow.h:277:50: note: in expansion of macro '__must_be_array' 277 | (count) * sizeof(*(p)->member) + __must_be_array((p)->member), \ | ^~~~~~~~~~~~~~~ include/linux/overflow.h:293:32: note: in expansion of macro 'flex_array_size' 293 | sizeof(*(p)) + flex_array_size(p, member, count), \ | ^~~~~~~~~~~~~~~ arch/x86/kernel/crash.c:154:24: note: in expansion of macro 'struct_size' 154 | cmem = vzalloc(struct_size(cmem, ranges, nr_ranges)); | ^~~~~~~~~~~ include/linux/overflow.h:278:44: error: invalid use of undefined type 'struct crash_mem' 278 | size_mul(count, sizeof(*(p)->member) + __must_be_array((p)->member))) | ^~ include/linux/overflow.h:293:32: note: in expansion of macro 'flex_array_size' 293 | sizeof(*(p)) + flex_array_size(p, member, count), \ | ^~~~~~~~~~~~~~~ arch/x86/kernel/crash.c:154:24: note: in expansion of macro 'struct_size' 154 | cmem = vzalloc(struct_size(cmem, ranges, nr_ranges)); | ^~~~~~~~~~~ include/linux/overflow.h:278:75: error: invalid use of undefined type 'struct crash_mem' 278 | size_mul(count, sizeof(*(p)->member) + __must_be_array((p)->member))) | ^~ include/linux/build_bug.h:16:62: note: in definition of macro 'BUILD_BUG_ON_ZERO' 16 | #define BUILD_BUG_ON_ZERO(e) ((int)(sizeof(struct { int:(-!!(e)); }))) | ^ include/linux/compiler.h:228:51: note: in expansion of macro '__same_type' 228 | #define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0])) | ^~~~~~~~~~~ include/linux/overflow.h:278:56: note: in expansion of macro '__must_be_array' 278 | size_mul(count, sizeof(*(p)->member) + __must_be_array((p)->member))) | ^~~~~~~~~~~~~~~ include/linux/overflow.h:293:32: note: in expansion of macro 'flex_array_size' 293 | sizeof(*(p)) + flex_array_size(p, member, count), \ | ^~~~~~~~~~~~~~~ arch/x86/kernel/crash.c:154:24: note: in expansion of macro 'struct_size' 154 | cmem = vzalloc(struct_size(cmem, ranges, nr_ranges)); | ^~~~~~~~~~~ include/linux/overflow.h:278:75: error: invalid use of undefined type 'struct crash_mem' 278 | size_mul(count, sizeof(*(p)->member) + __must_be_array((p)->member))) | ^~ include/linux/build_bug.h:16:62: note: in definition of macro 'BUILD_BUG_ON_ZERO' 16 | #define BUILD_BUG_ON_ZERO(e) ((int)(sizeof(struct { int:(-!!(e)); }))) | ^ include/linux/compiler.h:228:51: note: in expansion of macro '__same_type' 228 | #define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0])) | ^~~~~~~~~~~ include/linux/overflow.h:278:56: note: in expansion of macro '__must_be_array' 278 | size_mul(count, sizeof(*(p)->member) + __must_be_array((p)->member))) | ^~~~~~~~~~~~~~~ include/linux/overflow.h:293:32: note: in expansion of macro 'flex_array_size' 293 | sizeof(*(p)) + flex_array_size(p, member, count), \ | ^~~~~~~~~~~~~~~ arch/x86/kernel/crash.c:154:24: note: in expansion of macro 'struct_size' 154 | cmem = vzalloc(struct_size(cmem, ranges, nr_ranges)); | ^~~~~~~~~~~ include/linux/build_bug.h:16:51: error: bit-field '<anonymous>' width not an integer constant 16 | #define BUILD_BUG_ON_ZERO(e) ((int)(sizeof(struct { int:(-!!(e)); }))) | ^ include/linux/compiler.h:228:33: note: in expansion of macro 'BUILD_BUG_ON_ZERO' 228 | #define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0])) | ^~~~~~~~~~~~~~~~~ include/linux/overflow.h:278:56: note: in expansion of macro '__must_be_array' 278 | size_mul(count, sizeof(*(p)->member) + __must_be_array((p)->member))) | ^~~~~~~~~~~~~~~ include/linux/overflow.h:293:32: note: in expansion of macro 'flex_array_size' 293 | sizeof(*(p)) + flex_array_size(p, member, count), \ | ^~~~~~~~~~~~~~~ arch/x86/kernel/crash.c:154:24: note: in expansion of macro 'struct_size' 154 | cmem = vzalloc(struct_size(cmem, ranges, nr_ranges)); | ^~~~~~~~~~~ include/linux/overflow.h:294:32: error: invalid application of 'sizeof' to incomplete type 'struct crash_mem' 294 | size_add(sizeof(*(p)), flex_array_size(p, member, count))) | ^ arch/x86/kernel/crash.c:154:24: note: in expansion of macro 'struct_size' 154 | cmem = vzalloc(struct_size(cmem, ranges, nr_ranges)); | ^~~~~~~~~~~ >> include/linux/overflow.h:277:38: error: invalid use of undefined type 'struct crash_mem' 277 | (count) * sizeof(*(p)->member) + __must_be_array((p)->member), \ | ^~ include/linux/overflow.h:294:40: note: in expansion of macro 'flex_array_size' 294 | size_add(sizeof(*(p)), flex_array_size(p, member, count))) | ^~~~~~~~~~~~~~~ arch/x86/kernel/crash.c:154:24: note: in expansion of macro 'struct_size' 154 | cmem = vzalloc(struct_size(cmem, ranges, nr_ranges)); | ^~~~~~~~~~~ include/linux/overflow.h:277:69: error: invalid use of undefined type 'struct crash_mem' 277 | (count) * sizeof(*(p)->member) + __must_be_array((p)->member), \ | ^~ include/linux/build_bug.h:16:62: note: in definition of macro 'BUILD_BUG_ON_ZERO' 16 | #define BUILD_BUG_ON_ZERO(e) ((int)(sizeof(struct { int:(-!!(e)); }))) | ^ include/linux/compiler.h:228:51: note: in expansion of macro '__same_type' 228 | #define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0])) | ^~~~~~~~~~~ include/linux/overflow.h:277:50: note: in expansion of macro '__must_be_array' 277 | (count) * sizeof(*(p)->member) + __must_be_array((p)->member), \ | ^~~~~~~~~~~~~~~ include/linux/overflow.h:294:40: note: in expansion of macro 'flex_array_size' 294 | size_add(sizeof(*(p)), flex_array_size(p, member, count))) | ^~~~~~~~~~~~~~~ arch/x86/kernel/crash.c:154:24: note: in expansion of macro 'struct_size' 154 | cmem = vzalloc(struct_size(cmem, ranges, nr_ranges)); | ^~~~~~~~~~~ include/linux/overflow.h:277:69: error: invalid use of undefined type 'struct crash_mem' 277 | (count) * sizeof(*(p)->member) + __must_be_array((p)->member), \ | ^~ include/linux/build_bug.h:16:62: note: in definition of macro 'BUILD_BUG_ON_ZERO' 16 | #define BUILD_BUG_ON_ZERO(e) ((int)(sizeof(struct { int:(-!!(e)); }))) | ^ include/linux/compiler.h:228:51: note: in expansion of macro '__same_type' 228 | #define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0])) | ^~~~~~~~~~~ include/linux/overflow.h:277:50: note: in expansion of macro '__must_be_array' 277 | (count) * sizeof(*(p)->member) + __must_be_array((p)->member), \ | ^~~~~~~~~~~~~~~ include/linux/overflow.h:294:40: note: in expansion of macro 'flex_array_size' 294 | size_add(sizeof(*(p)), flex_array_size(p, member, count))) | ^~~~~~~~~~~~~~~ arch/x86/kernel/crash.c:154:24: note: in expansion of macro 'struct_size' 154 | cmem = vzalloc(struct_size(cmem, ranges, nr_ranges)); | ^~~~~~~~~~~ include/linux/build_bug.h:16:51: error: bit-field '<anonymous>' width not an integer constant 16 | #define BUILD_BUG_ON_ZERO(e) ((int)(sizeof(struct { int:(-!!(e)); }))) | ^ include/linux/compiler.h:228:33: note: in expansion of macro 'BUILD_BUG_ON_ZERO' 228 | #define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0])) | ^~~~~~~~~~~~~~~~~ include/linux/overflow.h:277:50: note: in expansion of macro '__must_be_array' 277 | (count) * sizeof(*(p)->member) + __must_be_array((p)->member), \ | ^~~~~~~~~~~~~~~ include/linux/overflow.h:294:40: note: in expansion of macro 'flex_array_size' 294 | size_add(sizeof(*(p)), flex_array_size(p, member, count))) | ^~~~~~~~~~~~~~~ arch/x86/kernel/crash.c:154:24: note: in expansion of macro 'struct_size' 154 | cmem = vzalloc(struct_size(cmem, ranges, nr_ranges)); | ^~~~~~~~~~~ include/linux/overflow.h:278:44: error: invalid use of undefined type 'struct crash_mem' 278 | size_mul(count, sizeof(*(p)->member) + __must_be_array((p)->member))) | ^~ include/linux/overflow.h:294:40: note: in expansion of macro 'flex_array_size' 294 | size_add(sizeof(*(p)), flex_array_size(p, member, count))) | ^~~~~~~~~~~~~~~ arch/x86/kernel/crash.c:154:24: note: in expansion of macro 'struct_size' 154 | cmem = vzalloc(struct_size(cmem, ranges, nr_ranges)); | ^~~~~~~~~~~ include/linux/overflow.h:278:75: error: invalid use of undefined type 'struct crash_mem' 278 | size_mul(count, sizeof(*(p)->member) + __must_be_array((p)->member))) | ^~ include/linux/build_bug.h:16:62: note: in definition of macro 'BUILD_BUG_ON_ZERO' 16 | #define BUILD_BUG_ON_ZERO(e) ((int)(sizeof(struct { int:(-!!(e)); }))) | ^ include/linux/compiler.h:228:51: note: in expansion of macro '__same_type' 228 | #define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0])) | ^~~~~~~~~~~ include/linux/overflow.h:278:56: note: in expansion of macro '__must_be_array' 278 | size_mul(count, sizeof(*(p)->member) + __must_be_array((p)->member))) | ^~~~~~~~~~~~~~~ include/linux/overflow.h:294:40: note: in expansion of macro 'flex_array_size' 294 | size_add(sizeof(*(p)), flex_array_size(p, member, count))) | ^~~~~~~~~~~~~~~ arch/x86/kernel/crash.c:154:24: note: in expansion of macro 'struct_size' 154 | cmem = vzalloc(struct_size(cmem, ranges, nr_ranges)); | ^~~~~~~~~~~ include/linux/overflow.h:278:75: error: invalid use of undefined type 'struct crash_mem' 278 | size_mul(count, sizeof(*(p)->member) + __must_be_array((p)->member))) | ^~ include/linux/build_bug.h:16:62: note: in definition of macro 'BUILD_BUG_ON_ZERO' 16 | #define BUILD_BUG_ON_ZERO(e) ((int)(sizeof(struct { int:(-!!(e)); }))) | ^ include/linux/compiler.h:228:51: note: in expansion of macro '__same_type' 228 | #define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0])) | ^~~~~~~~~~~ include/linux/overflow.h:278:56: note: in expansion of macro '__must_be_array' 278 | size_mul(count, sizeof(*(p)->member) + __must_be_array((p)->member))) | ^~~~~~~~~~~~~~~ include/linux/overflow.h:294:40: note: in expansion of macro 'flex_array_size' 294 | size_add(sizeof(*(p)), flex_array_size(p, member, count))) | ^~~~~~~~~~~~~~~ arch/x86/kernel/crash.c:154:24: note: in expansion of macro 'struct_size' 154 | cmem = vzalloc(struct_size(cmem, ranges, nr_ranges)); | ^~~~~~~~~~~ include/linux/build_bug.h:16:51: error: bit-field '<anonymous>' width not an integer constant 16 | #define BUILD_BUG_ON_ZERO(e) ((int)(sizeof(struct { int:(-!!(e)); }))) | ^ include/linux/compiler.h:228:33: note: in expansion of macro 'BUILD_BUG_ON_ZERO' 228 | #define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0])) | ^~~~~~~~~~~~~~~~~ include/linux/overflow.h:278:56: note: in expansion of macro '__must_be_array' 278 | size_mul(count, sizeof(*(p)->member) + __must_be_array((p)->member))) | ^~~~~~~~~~~~~~~ include/linux/overflow.h:294:40: note: in expansion of macro 'flex_array_size' 294 | size_add(sizeof(*(p)), flex_array_size(p, member, count))) | ^~~~~~~~~~~~~~~ arch/x86/kernel/crash.c:154:24: note: in expansion of macro 'struct_size' 154 | cmem = vzalloc(struct_size(cmem, ranges, nr_ranges)); | ^~~~~~~~~~~ >> arch/x86/kernel/crash.c:158:13: error: invalid use of undefined type 'struct crash_mem' 158 | cmem->max_nr_ranges = nr_ranges; | ^~ arch/x86/kernel/crash.c:159:13: error: invalid use of undefined type 'struct crash_mem' 159 | cmem->nr_ranges = 0; | ^~ arch/x86/kernel/crash.c: In function 'elf_header_exclude_ranges': >> arch/x86/kernel/crash.c:173:15: error: implicit declaration of function 'crash_exclude_mem_range' [-Werror=implicit-function-declaration] 173 | ret = crash_exclude_mem_range(cmem, 0, (1<<20)-1); | ^~~~~~~~~~~~~~~~~~~~~~~ arch/x86/kernel/crash.c: In function 'prepare_elf64_ram_headers_callback': arch/x86/kernel/crash.c:193:13: error: invalid use of undefined type 'struct crash_mem' 193 | cmem->ranges[cmem->nr_ranges].start = res->start; | ^~ arch/x86/kernel/crash.c:193:26: error: invalid use of undefined type 'struct crash_mem' 193 | cmem->ranges[cmem->nr_ranges].start = res->start; | ^~ arch/x86/kernel/crash.c:194:13: error: invalid use of undefined type 'struct crash_mem' 194 | cmem->ranges[cmem->nr_ranges].end = res->end; | ^~ arch/x86/kernel/crash.c:194:26: error: invalid use of undefined type 'struct crash_mem' 194 | cmem->ranges[cmem->nr_ranges].end = res->end; | ^~ arch/x86/kernel/crash.c:195:13: error: invalid use of undefined type 'struct crash_mem' 195 | cmem->nr_ranges++; | ^~ arch/x86/kernel/crash.c: In function 'prepare_elf_headers': arch/x86/kernel/crash.c:221:30: error: invalid use of undefined type 'struct crash_mem' 221 | *nr_mem_ranges = cmem->nr_ranges; | ^~ >> arch/x86/kernel/crash.c:224:16: error: implicit declaration of function 'crash_prepare_elf64_headers'; did you mean 'prepare_elf_headers'? [-Werror=implicit-function-declaration] 224 | ret = crash_prepare_elf64_headers(cmem, IS_ENABLED(CONFIG_X86_64), addr, sz); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~ | prepare_elf_headers cc1: some warnings being treated as errors vim +293 include/linux/overflow.h 610b15c50e86eb Kees Cook 2018-05-07 262 b19d57d0f3cc6f Gustavo A. R. Silva 2020-06-08 263 /** b19d57d0f3cc6f Gustavo A. R. Silva 2020-06-08 264 * flex_array_size() - Calculate size of a flexible array member b19d57d0f3cc6f Gustavo A. R. Silva 2020-06-08 265 * within an enclosing structure. b19d57d0f3cc6f Gustavo A. R. Silva 2020-06-08 266 * @p: Pointer to the structure. b19d57d0f3cc6f Gustavo A. R. Silva 2020-06-08 267 * @member: Name of the flexible array member. b19d57d0f3cc6f Gustavo A. R. Silva 2020-06-08 268 * @count: Number of elements in the array. b19d57d0f3cc6f Gustavo A. R. Silva 2020-06-08 269 * b19d57d0f3cc6f Gustavo A. R. Silva 2020-06-08 270 * Calculates size of a flexible array of @count number of @member b19d57d0f3cc6f Gustavo A. R. Silva 2020-06-08 271 * elements, at the end of structure @p. b19d57d0f3cc6f Gustavo A. R. Silva 2020-06-08 272 * b19d57d0f3cc6f Gustavo A. R. Silva 2020-06-08 273 * Return: number of bytes needed or SIZE_MAX on overflow. b19d57d0f3cc6f Gustavo A. R. Silva 2020-06-08 274 */ b19d57d0f3cc6f Gustavo A. R. Silva 2020-06-08 275 #define flex_array_size(p, member, count) \ 230f6fa2c1db6a Kees Cook 2022-02-09 276 __builtin_choose_expr(__is_constexpr(count), \ 230f6fa2c1db6a Kees Cook 2022-02-09 @277 (count) * sizeof(*(p)->member) + __must_be_array((p)->member), \ 230f6fa2c1db6a Kees Cook 2022-02-09 278 size_mul(count, sizeof(*(p)->member) + __must_be_array((p)->member))) b19d57d0f3cc6f Gustavo A. R. Silva 2020-06-08 279 e1be43d9b5d0d1 Kees Cook 2021-09-18 280 /** e1be43d9b5d0d1 Kees Cook 2021-09-18 281 * struct_size() - Calculate size of structure with trailing flexible array. e1be43d9b5d0d1 Kees Cook 2021-09-18 282 * @p: Pointer to the structure. e1be43d9b5d0d1 Kees Cook 2021-09-18 283 * @member: Name of the array member. e1be43d9b5d0d1 Kees Cook 2021-09-18 284 * @count: Number of elements in the array. e1be43d9b5d0d1 Kees Cook 2021-09-18 285 * d67790ddf0219a Kees Cook 2023-05-22 286 * Calculates size of memory needed for structure of @p followed by an e1be43d9b5d0d1 Kees Cook 2021-09-18 287 * array of @count number of @member elements. e1be43d9b5d0d1 Kees Cook 2021-09-18 288 * e1be43d9b5d0d1 Kees Cook 2021-09-18 289 * Return: number of bytes needed or SIZE_MAX on overflow. e1be43d9b5d0d1 Kees Cook 2021-09-18 290 */ e1be43d9b5d0d1 Kees Cook 2021-09-18 291 #define struct_size(p, member, count) \ 230f6fa2c1db6a Kees Cook 2022-02-09 292 __builtin_choose_expr(__is_constexpr(count), \ 230f6fa2c1db6a Kees Cook 2022-02-09 @293 sizeof(*(p)) + flex_array_size(p, member, count), \ 230f6fa2c1db6a Kees Cook 2022-02-09 294 size_add(sizeof(*(p)), flex_array_size(p, member, count))) e1be43d9b5d0d1 Kees Cook 2021-09-18 295
Hi Baoquan, kernel test robot noticed the following build errors: [auto build test ERROR on linus/master] [also build test ERROR on v6.7-rc8] [cannot apply to powerpc/next powerpc/fixes tip/x86/core arm64/for-next/core next-20240105] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Baoquan-He/kexec_core-move-kdump-related-codes-from-crash_core-c-to-kexec_core-c/20240105-223735 base: linus/master patch link: https://lore.kernel.org/r/20240105103305.557273-2-bhe%40redhat.com patch subject: [PATCH 1/5] kexec_core: move kdump related codes from crash_core.c to kexec_core.c config: i386-allmodconfig (https://download.01.org/0day-ci/archive/20240106/202401062212.LXqinfjE-lkp@intel.com/config) compiler: ClangBuiltLinux clang version 17.0.6 (https://github.com/llvm/llvm-project 6009708b4367171ccdbf4b5905cb6a803753fe18) reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240106/202401062212.LXqinfjE-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202401062212.LXqinfjE-lkp@intel.com/ All errors (new ones prefixed by >>): >> arch/x86/kernel/crash.c:154:17: error: invalid application of 'sizeof' to an incomplete type 'struct crash_mem' 154 | cmem = vzalloc(struct_size(cmem, ranges, nr_ranges)); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/overflow.h:293:9: note: expanded from macro 'struct_size' 293 | sizeof(*(p)) + flex_array_size(p, member, count), \ | ^~~~~~ arch/x86/kernel/crash.c:140:15: note: forward declaration of 'struct crash_mem' 140 | static struct crash_mem *fill_up_crash_elf_data(void) | ^ >> arch/x86/kernel/crash.c:154:17: error: incomplete definition of type 'struct crash_mem' 154 | cmem = vzalloc(struct_size(cmem, ranges, nr_ranges)); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/overflow.h:293:18: note: expanded from macro 'struct_size' 293 | sizeof(*(p)) + flex_array_size(p, member, count), \ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/overflow.h:277:24: note: expanded from macro 'flex_array_size' 277 | (count) * sizeof(*(p)->member) + __must_be_array((p)->member), \ | ~~~^ arch/x86/kernel/crash.c:140:15: note: forward declaration of 'struct crash_mem' 140 | static struct crash_mem *fill_up_crash_elf_data(void) | ^ >> arch/x86/kernel/crash.c:154:17: error: incomplete definition of type 'struct crash_mem' 154 | cmem = vzalloc(struct_size(cmem, ranges, nr_ranges)); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/overflow.h:293:18: note: expanded from macro 'struct_size' 293 | sizeof(*(p)) + flex_array_size(p, member, count), \ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/overflow.h:277:55: note: expanded from macro 'flex_array_size' 277 | (count) * sizeof(*(p)->member) + __must_be_array((p)->member), \ | ~~~~~~~~~~~~~~~~~~~^~~~~~~~~ include/linux/compiler.h:228:59: note: expanded from macro '__must_be_array' 228 | #define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0])) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~ include/linux/compiler_types.h:376:63: note: expanded from macro '__same_type' 376 | #define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b)) | ^ include/linux/build_bug.h:16:62: note: expanded from macro 'BUILD_BUG_ON_ZERO' 16 | #define BUILD_BUG_ON_ZERO(e) ((int)(sizeof(struct { int:(-!!(e)); }))) | ^ arch/x86/kernel/crash.c:140:15: note: forward declaration of 'struct crash_mem' 140 | static struct crash_mem *fill_up_crash_elf_data(void) | ^ >> arch/x86/kernel/crash.c:154:17: error: incomplete definition of type 'struct crash_mem' 154 | cmem = vzalloc(struct_size(cmem, ranges, nr_ranges)); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/overflow.h:293:18: note: expanded from macro 'struct_size' 293 | sizeof(*(p)) + flex_array_size(p, member, count), \ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/overflow.h:278:30: note: expanded from macro 'flex_array_size' 278 | size_mul(count, sizeof(*(p)->member) + __must_be_array((p)->member))) | ~~~^ arch/x86/kernel/crash.c:140:15: note: forward declaration of 'struct crash_mem' 140 | static struct crash_mem *fill_up_crash_elf_data(void) | ^ >> arch/x86/kernel/crash.c:154:17: error: incomplete definition of type 'struct crash_mem' 154 | cmem = vzalloc(struct_size(cmem, ranges, nr_ranges)); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/overflow.h:293:18: note: expanded from macro 'struct_size' 293 | sizeof(*(p)) + flex_array_size(p, member, count), \ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/overflow.h:278:61: note: expanded from macro 'flex_array_size' 278 | size_mul(count, sizeof(*(p)->member) + __must_be_array((p)->member))) | ~~~~~~~~~~~~~~~~~~~^~~~~~~~~ include/linux/compiler.h:228:59: note: expanded from macro '__must_be_array' 228 | #define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0])) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~ include/linux/compiler_types.h:376:63: note: expanded from macro '__same_type' 376 | #define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b)) | ^ include/linux/build_bug.h:16:62: note: expanded from macro 'BUILD_BUG_ON_ZERO' 16 | #define BUILD_BUG_ON_ZERO(e) ((int)(sizeof(struct { int:(-!!(e)); }))) | ^ arch/x86/kernel/crash.c:140:15: note: forward declaration of 'struct crash_mem' 140 | static struct crash_mem *fill_up_crash_elf_data(void) | ^ arch/x86/kernel/crash.c:158:6: error: incomplete definition of type 'struct crash_mem' 158 | cmem->max_nr_ranges = nr_ranges; | ~~~~^ arch/x86/kernel/crash.c:140:15: note: forward declaration of 'struct crash_mem' 140 | static struct crash_mem *fill_up_crash_elf_data(void) | ^ arch/x86/kernel/crash.c:159:6: error: incomplete definition of type 'struct crash_mem' 159 | cmem->nr_ranges = 0; | ~~~~^ arch/x86/kernel/crash.c:140:15: note: forward declaration of 'struct crash_mem' 140 | static struct crash_mem *fill_up_crash_elf_data(void) | ^ >> arch/x86/kernel/crash.c:173:8: error: call to undeclared function 'crash_exclude_mem_range'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration] 173 | ret = crash_exclude_mem_range(cmem, 0, (1<<20)-1); | ^ arch/x86/kernel/crash.c:193:6: error: incomplete definition of type 'struct crash_mem' 193 | cmem->ranges[cmem->nr_ranges].start = res->start; | ~~~~^ arch/x86/kernel/crash.c:140:15: note: forward declaration of 'struct crash_mem' 140 | static struct crash_mem *fill_up_crash_elf_data(void) | ^ arch/x86/kernel/crash.c:193:19: error: incomplete definition of type 'struct crash_mem' 193 | cmem->ranges[cmem->nr_ranges].start = res->start; | ~~~~^ arch/x86/kernel/crash.c:140:15: note: forward declaration of 'struct crash_mem' 140 | static struct crash_mem *fill_up_crash_elf_data(void) | ^ arch/x86/kernel/crash.c:194:6: error: incomplete definition of type 'struct crash_mem' 194 | cmem->ranges[cmem->nr_ranges].end = res->end; | ~~~~^ arch/x86/kernel/crash.c:140:15: note: forward declaration of 'struct crash_mem' 140 | static struct crash_mem *fill_up_crash_elf_data(void) | ^ arch/x86/kernel/crash.c:194:19: error: incomplete definition of type 'struct crash_mem' 194 | cmem->ranges[cmem->nr_ranges].end = res->end; | ~~~~^ arch/x86/kernel/crash.c:140:15: note: forward declaration of 'struct crash_mem' 140 | static struct crash_mem *fill_up_crash_elf_data(void) | ^ arch/x86/kernel/crash.c:195:6: error: incomplete definition of type 'struct crash_mem' 195 | cmem->nr_ranges++; | ~~~~^ arch/x86/kernel/crash.c:140:15: note: forward declaration of 'struct crash_mem' 140 | static struct crash_mem *fill_up_crash_elf_data(void) | ^ arch/x86/kernel/crash.c:221:23: error: incomplete definition of type 'struct crash_mem' 221 | *nr_mem_ranges = cmem->nr_ranges; | ~~~~^ arch/x86/kernel/crash.c:140:15: note: forward declaration of 'struct crash_mem' 140 | static struct crash_mem *fill_up_crash_elf_data(void) | ^ >> arch/x86/kernel/crash.c:224:9: error: call to undeclared function 'crash_prepare_elf64_headers'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration] 224 | ret = crash_prepare_elf64_headers(cmem, IS_ENABLED(CONFIG_X86_64), addr, sz); | ^ arch/x86/kernel/crash.c:224:9: note: did you mean 'prepare_elf_headers'? arch/x86/kernel/crash.c:201:12: note: 'prepare_elf_headers' declared here 201 | static int prepare_elf_headers(struct kimage *image, void **addr, | ^ 15 errors generated. vim +154 arch/x86/kernel/crash.c dd5f726076cc76 Vivek Goyal 2014-08-08 138 dd5f726076cc76 Vivek Goyal 2014-08-08 139 /* Gather all the required information to prepare elf headers for ram regions */ 8d5f894a3108ac AKASHI Takahiro 2018-04-13 @140 static struct crash_mem *fill_up_crash_elf_data(void) dd5f726076cc76 Vivek Goyal 2014-08-08 141 { dd5f726076cc76 Vivek Goyal 2014-08-08 142 unsigned int nr_ranges = 0; 8d5f894a3108ac AKASHI Takahiro 2018-04-13 143 struct crash_mem *cmem; dd5f726076cc76 Vivek Goyal 2014-08-08 144 9eff303725da65 Borislav Petkov 2019-11-14 145 walk_system_ram_res(0, -1, &nr_ranges, get_nr_ram_ranges_callback); 8d5f894a3108ac AKASHI Takahiro 2018-04-13 146 if (!nr_ranges) 8d5f894a3108ac AKASHI Takahiro 2018-04-13 147 return NULL; dd5f726076cc76 Vivek Goyal 2014-08-08 148 8d5f894a3108ac AKASHI Takahiro 2018-04-13 149 /* 8d5f894a3108ac AKASHI Takahiro 2018-04-13 150 * Exclusion of crash region and/or crashk_low_res may cause 8d5f894a3108ac AKASHI Takahiro 2018-04-13 151 * another range split. So add extra two slots here. 8d5f894a3108ac AKASHI Takahiro 2018-04-13 152 */ 8d5f894a3108ac AKASHI Takahiro 2018-04-13 153 nr_ranges += 2; 4df4309587e18a Gustavo A. R. Silva 2019-04-03 @154 cmem = vzalloc(struct_size(cmem, ranges, nr_ranges)); 8d5f894a3108ac AKASHI Takahiro 2018-04-13 155 if (!cmem) 8d5f894a3108ac AKASHI Takahiro 2018-04-13 156 return NULL; dd5f726076cc76 Vivek Goyal 2014-08-08 157 8d5f894a3108ac AKASHI Takahiro 2018-04-13 158 cmem->max_nr_ranges = nr_ranges; 8d5f894a3108ac AKASHI Takahiro 2018-04-13 159 cmem->nr_ranges = 0; dd5f726076cc76 Vivek Goyal 2014-08-08 160 8d5f894a3108ac AKASHI Takahiro 2018-04-13 161 return cmem; dd5f726076cc76 Vivek Goyal 2014-08-08 162 } dd5f726076cc76 Vivek Goyal 2014-08-08 163 dd5f726076cc76 Vivek Goyal 2014-08-08 164 /* dd5f726076cc76 Vivek Goyal 2014-08-08 165 * Look for any unwanted ranges between mstart, mend and remove them. This 8d5f894a3108ac AKASHI Takahiro 2018-04-13 166 * might lead to split and split ranges are put in cmem->ranges[] array dd5f726076cc76 Vivek Goyal 2014-08-08 167 */ 8d5f894a3108ac AKASHI Takahiro 2018-04-13 168 static int elf_header_exclude_ranges(struct crash_mem *cmem) dd5f726076cc76 Vivek Goyal 2014-08-08 169 { dd5f726076cc76 Vivek Goyal 2014-08-08 170 int ret = 0; dd5f726076cc76 Vivek Goyal 2014-08-08 171 7c321eb2b843bf Lianbo Jiang 2019-11-08 172 /* Exclude the low 1M because it is always reserved */ a3e1c3bb24e2ff Lianbo Jiang 2020-08-04 @173 ret = crash_exclude_mem_range(cmem, 0, (1<<20)-1); 7c321eb2b843bf Lianbo Jiang 2019-11-08 174 if (ret) 7c321eb2b843bf Lianbo Jiang 2019-11-08 175 return ret; 7c321eb2b843bf Lianbo Jiang 2019-11-08 176 dd5f726076cc76 Vivek Goyal 2014-08-08 177 /* Exclude crashkernel region */ babac4a84a8884 AKASHI Takahiro 2018-04-13 178 ret = crash_exclude_mem_range(cmem, crashk_res.start, crashk_res.end); dd5f726076cc76 Vivek Goyal 2014-08-08 179 if (ret) dd5f726076cc76 Vivek Goyal 2014-08-08 180 return ret; dd5f726076cc76 Vivek Goyal 2014-08-08 181 9eff303725da65 Borislav Petkov 2019-11-14 182 if (crashk_low_res.end) babac4a84a8884 AKASHI Takahiro 2018-04-13 183 ret = crash_exclude_mem_range(cmem, crashk_low_res.start, babac4a84a8884 AKASHI Takahiro 2018-04-13 184 crashk_low_res.end); dd5f726076cc76 Vivek Goyal 2014-08-08 185 dd5f726076cc76 Vivek Goyal 2014-08-08 186 return ret; dd5f726076cc76 Vivek Goyal 2014-08-08 187 } dd5f726076cc76 Vivek Goyal 2014-08-08 188 1d2e733b13b450 Tom Lendacky 2017-10-20 189 static int prepare_elf64_ram_headers_callback(struct resource *res, void *arg) dd5f726076cc76 Vivek Goyal 2014-08-08 190 { 8d5f894a3108ac AKASHI Takahiro 2018-04-13 191 struct crash_mem *cmem = arg; dd5f726076cc76 Vivek Goyal 2014-08-08 192 cbe6601617302b AKASHI Takahiro 2018-04-13 193 cmem->ranges[cmem->nr_ranges].start = res->start; cbe6601617302b AKASHI Takahiro 2018-04-13 194 cmem->ranges[cmem->nr_ranges].end = res->end; cbe6601617302b AKASHI Takahiro 2018-04-13 195 cmem->nr_ranges++; dd5f726076cc76 Vivek Goyal 2014-08-08 196 cbe6601617302b AKASHI Takahiro 2018-04-13 197 return 0; dd5f726076cc76 Vivek Goyal 2014-08-08 198 } dd5f726076cc76 Vivek Goyal 2014-08-08 199 dd5f726076cc76 Vivek Goyal 2014-08-08 200 /* Prepare elf headers. Return addr and size */ dd5f726076cc76 Vivek Goyal 2014-08-08 201 static int prepare_elf_headers(struct kimage *image, void **addr, ea53ad9cf73b6b Eric DeVolder 2023-08-14 202 unsigned long *sz, unsigned long *nr_mem_ranges) dd5f726076cc76 Vivek Goyal 2014-08-08 203 { 8d5f894a3108ac AKASHI Takahiro 2018-04-13 204 struct crash_mem *cmem; 7c321eb2b843bf Lianbo Jiang 2019-11-08 205 int ret; dd5f726076cc76 Vivek Goyal 2014-08-08 206 8d5f894a3108ac AKASHI Takahiro 2018-04-13 207 cmem = fill_up_crash_elf_data(); 8d5f894a3108ac AKASHI Takahiro 2018-04-13 208 if (!cmem) dd5f726076cc76 Vivek Goyal 2014-08-08 209 return -ENOMEM; dd5f726076cc76 Vivek Goyal 2014-08-08 210 9eff303725da65 Borislav Petkov 2019-11-14 211 ret = walk_system_ram_res(0, -1, cmem, prepare_elf64_ram_headers_callback); cbe6601617302b AKASHI Takahiro 2018-04-13 212 if (ret) cbe6601617302b AKASHI Takahiro 2018-04-13 213 goto out; cbe6601617302b AKASHI Takahiro 2018-04-13 214 cbe6601617302b AKASHI Takahiro 2018-04-13 215 /* Exclude unwanted mem ranges */ 8d5f894a3108ac AKASHI Takahiro 2018-04-13 216 ret = elf_header_exclude_ranges(cmem); cbe6601617302b AKASHI Takahiro 2018-04-13 217 if (ret) cbe6601617302b AKASHI Takahiro 2018-04-13 218 goto out; cbe6601617302b AKASHI Takahiro 2018-04-13 219 ea53ad9cf73b6b Eric DeVolder 2023-08-14 220 /* Return the computed number of memory ranges, for hotplug usage */ ea53ad9cf73b6b Eric DeVolder 2023-08-14 221 *nr_mem_ranges = cmem->nr_ranges; ea53ad9cf73b6b Eric DeVolder 2023-08-14 222 dd5f726076cc76 Vivek Goyal 2014-08-08 223 /* By default prepare 64bit headers */ 9eff303725da65 Borislav Petkov 2019-11-14 @224 ret = crash_prepare_elf64_headers(cmem, IS_ENABLED(CONFIG_X86_64), addr, sz); cbe6601617302b AKASHI Takahiro 2018-04-13 225 cbe6601617302b AKASHI Takahiro 2018-04-13 226 out: 8d5f894a3108ac AKASHI Takahiro 2018-04-13 227 vfree(cmem); dd5f726076cc76 Vivek Goyal 2014-08-08 228 return ret; dd5f726076cc76 Vivek Goyal 2014-08-08 229 } ea53ad9cf73b6b Eric DeVolder 2023-08-14 230 #endif dd5f726076cc76 Vivek Goyal 2014-08-08 231
On 01/06/24 at 10:58pm, kernel test robot wrote: > Hi Baoquan, > > kernel test robot noticed the following build errors: > > [auto build test ERROR on linus/master] > [also build test ERROR on v6.7-rc8] > [cannot apply to powerpc/next powerpc/fixes tip/x86/core arm64/for-next/core next-20240105] > [If your patch is applied to the wrong git tree, kindly drop us a note. > And when submitting patch, we suggest to use '--base' as documented in > https://git-scm.com/docs/git-format-patch#_base_tree_information] > > url: https://github.com/intel-lab-lkp/linux/commits/Baoquan-He/kexec_core-move-kdump-related-codes-from-crash_core-c-to-kexec_core-c/20240105-223735 > base: linus/master > patch link: https://lore.kernel.org/r/20240105103305.557273-2-bhe%40redhat.com > patch subject: [PATCH 1/5] kexec_core: move kdump related codes from crash_core.c to kexec_core.c > config: i386-allmodconfig (https://download.01.org/0day-ci/archive/20240106/202401062212.LXqinfjE-lkp@intel.com/config) > compiler: ClangBuiltLinux clang version 17.0.6 (https://github.com/llvm/llvm-project 6009708b4367171ccdbf4b5905cb6a803753fe18) > reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240106/202401062212.LXqinfjE-lkp@intel.com/reproduce) > > If you fix the issue in a separate patch/commit (i.e. not just a new version of > the same patch/commit), kindly add following tags > | Reported-by: kernel test robot <lkp@intel.com> > | Closes: https://lore.kernel.org/oe-kbuild-all/202401062212.LXqinfjE-lkp@intel.com/ > > All errors (new ones prefixed by >>): > > >> arch/x86/kernel/crash.c:154:17: error: invalid application of 'sizeof' to an incomplete type 'struct crash_mem' > 154 | cmem = vzalloc(struct_size(cmem, ranges, nr_ranges)); > | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Thanks for reporting. I mistakenly put the struct crash_mem definition and the two function delcarations inside CONFIG_KEXEC_FILE ifdeffery scope, so with the lkp's config as below, the compiling failed. The code change at bottom can fix it. Will update patch in v2. # # Kexec and crash features # CONFIG_CRASH_CORE=y CONFIG_KEXEC_CORE=y CONFIG_KEXEC=y # CONFIG_KEXEC_FILE is not set CONFIG_CRASH_DUMP=y CONFIG_CRASH_HOTPLUG=y CONFIG_CRASH_MAX_MEMORY_RANGES=8192 --- include/linux/kexec.h | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/include/linux/kexec.h b/include/linux/kexec.h index be1e5c2fdbdc..4df6ef72db84 100644 --- a/include/linux/kexec.h +++ b/include/linux/kexec.h @@ -228,21 +228,6 @@ static inline int arch_kexec_locate_mem_hole(struct kexec_buf *kbuf) } #endif -/* Alignment required for elf header segment */ -#define ELF_CORE_HEADER_ALIGN 4096 - -struct crash_mem { - unsigned int max_nr_ranges; - unsigned int nr_ranges; - struct range ranges[] __counted_by(max_nr_ranges); -}; - -extern int crash_exclude_mem_range(struct crash_mem *mem, - unsigned long long mstart, - unsigned long long mend); -extern int crash_prepare_elf64_headers(struct crash_mem *mem, int need_kernel_map, - void **addr, unsigned long *sz); - #ifndef arch_kexec_apply_relocations_add /* * arch_kexec_apply_relocations_add - apply relocations of type RELA @@ -525,6 +510,20 @@ static inline unsigned int crash_get_elfcorehdr_size(void) { return 0; } #define KEXEC_CRASH_HP_INVALID_CPU -1U #endif +/* Alignment required for elf header segment */ +#define ELF_CORE_HEADER_ALIGN 4096 + +struct crash_mem { + unsigned int max_nr_ranges; + unsigned int nr_ranges; + struct range ranges[] __counted_by(max_nr_ranges); +}; + +extern int crash_exclude_mem_range(struct crash_mem *mem, + unsigned long long mstart, + unsigned long long mend); +extern int crash_prepare_elf64_headers(struct crash_mem *mem, int need_kernel_map, + void **addr, unsigned long *sz); #else /* !CONFIG_KEXEC_CORE */ struct pt_regs; struct task_struct; @@ -541,6 +540,7 @@ void set_kexec_sig_enforced(void); static inline void set_kexec_sig_enforced(void) {} #endif + #endif /* !defined(__ASSEBMLY__) */ #endif /* LINUX_KEXEC_H */
On 01/06/24 at 06:59pm, kernel test robot wrote: > Hi Baoquan, > > kernel test robot noticed the following build errors: > > [auto build test ERROR on linus/master] > [also build test ERROR on v6.7-rc8] > [cannot apply to powerpc/next powerpc/fixes tip/x86/core arm64/for-next/core next-20240105] > [If your patch is applied to the wrong git tree, kindly drop us a note. > And when submitting patch, we suggest to use '--base' as documented in > https://git-scm.com/docs/git-format-patch#_base_tree_information] > > url: https://github.com/intel-lab-lkp/linux/commits/Baoquan-He/kexec_core-move-kdump-related-codes-from-crash_core-c-to-kexec_core-c/20240105-223735 > base: linus/master > patch link: https://lore.kernel.org/r/20240105103305.557273-2-bhe%40redhat.com > patch subject: [PATCH 1/5] kexec_core: move kdump related codes from crash_core.c to kexec_core.c > config: x86_64-randconfig-104-20240106 (https://download.01.org/0day-ci/archive/20240106/202401061800.3XPSaPsa-lkp@intel.com/config) > compiler: gcc-12 (Debian 12.2.0-14) 12.2.0 > reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240106/202401061800.3XPSaPsa-lkp@intel.com/reproduce) > > If you fix the issue in a separate patch/commit (i.e. not just a new version of > the same patch/commit), kindly add following tags > | Reported-by: kernel test robot <lkp@intel.com> > | Closes: https://lore.kernel.org/oe-kbuild-all/202401061800.3XPSaPsa-lkp@intel.com/ > > All errors (new ones prefixed by >>): > > In file included from include/linux/string.h:11, > from include/linux/bitmap.h:12, > from include/linux/cpumask.h:12, > from include/linux/smp.h:13, > from arch/x86/kernel/crash.c:18: > arch/x86/kernel/crash.c: In function 'fill_up_crash_elf_data': > >> include/linux/overflow.h:293:23: error: invalid application of 'sizeof' to incomplete type 'struct crash_mem' > 293 | sizeof(*(p)) + flex_array_size(p, member, count), \ Thanks for reporting. This is the same as the one reported and fixed in below link: https://lore.kernel.org/oe-kbuild-all/ZZpmP5QeH+VigqXw@MiWiFi-R3L-srv/
diff --git a/include/linux/crash_core.h b/include/linux/crash_core.h index 5126a4fecb44..af304259afa3 100644 --- a/include/linux/crash_core.h +++ b/include/linux/crash_core.h @@ -124,30 +124,4 @@ static inline void __init reserve_crashkernel_generic(char *cmdline, bool high) {} #endif - -/* Alignment required for elf header segment */ -#define ELF_CORE_HEADER_ALIGN 4096 - -struct crash_mem { - unsigned int max_nr_ranges; - unsigned int nr_ranges; - struct range ranges[] __counted_by(max_nr_ranges); -}; - -extern int crash_exclude_mem_range(struct crash_mem *mem, - unsigned long long mstart, - unsigned long long mend); -extern int crash_prepare_elf64_headers(struct crash_mem *mem, int need_kernel_map, - void **addr, unsigned long *sz); - -struct kimage; -struct kexec_segment; - -#define KEXEC_CRASH_HP_NONE 0 -#define KEXEC_CRASH_HP_ADD_CPU 1 -#define KEXEC_CRASH_HP_REMOVE_CPU 2 -#define KEXEC_CRASH_HP_ADD_MEMORY 3 -#define KEXEC_CRASH_HP_REMOVE_MEMORY 4 -#define KEXEC_CRASH_HP_INVALID_CPU -1U - #endif /* LINUX_CRASH_CORE_H */ diff --git a/include/linux/kexec.h b/include/linux/kexec.h index 8227455192b7..6705812f07f5 100644 --- a/include/linux/kexec.h +++ b/include/linux/kexec.h @@ -227,6 +227,21 @@ static inline int arch_kexec_locate_mem_hole(struct kexec_buf *kbuf) } #endif +/* Alignment required for elf header segment */ +#define ELF_CORE_HEADER_ALIGN 4096 + +struct crash_mem { + unsigned int max_nr_ranges; + unsigned int nr_ranges; + struct range ranges[] __counted_by(max_nr_ranges); +}; + +extern int crash_exclude_mem_range(struct crash_mem *mem, + unsigned long long mstart, + unsigned long long mend); +extern int crash_prepare_elf64_headers(struct crash_mem *mem, int need_kernel_map, + void **addr, unsigned long *sz); + #ifndef arch_kexec_apply_relocations_add /* * arch_kexec_apply_relocations_add - apply relocations of type RELA @@ -500,6 +515,15 @@ static inline int crash_hotplug_memory_support(void) { return 0; } static inline unsigned int crash_get_elfcorehdr_size(void) { return 0; } #endif +#ifdef CONFIG_CRASH_HOTPLUG +#define KEXEC_CRASH_HP_NONE 0 +#define KEXEC_CRASH_HP_ADD_CPU 1 +#define KEXEC_CRASH_HP_REMOVE_CPU 2 +#define KEXEC_CRASH_HP_ADD_MEMORY 3 +#define KEXEC_CRASH_HP_REMOVE_MEMORY 4 +#define KEXEC_CRASH_HP_INVALID_CPU -1U +#endif + #else /* !CONFIG_KEXEC_CORE */ struct pt_regs; struct task_struct; diff --git a/kernel/crash_core.c b/kernel/crash_core.c index d4313b53837e..b4f3fdecbe26 100644 --- a/kernel/crash_core.c +++ b/kernel/crash_core.c @@ -24,9 +24,6 @@ #include "kallsyms_internal.h" #include "kexec_internal.h" -/* Per cpu memory for storing cpu states in case of system crash. */ -note_buf_t __percpu *crash_notes; - /* vmcoreinfo stuff */ unsigned char *vmcoreinfo_data; size_t vmcoreinfo_size; @@ -463,187 +460,6 @@ void __init reserve_crashkernel_generic(char *cmdline, } #endif -int crash_prepare_elf64_headers(struct crash_mem *mem, int need_kernel_map, - void **addr, unsigned long *sz) -{ - Elf64_Ehdr *ehdr; - Elf64_Phdr *phdr; - unsigned long nr_cpus = num_possible_cpus(), nr_phdr, elf_sz; - unsigned char *buf; - unsigned int cpu, i; - unsigned long long notes_addr; - unsigned long mstart, mend; - - /* extra phdr for vmcoreinfo ELF note */ - nr_phdr = nr_cpus + 1; - nr_phdr += mem->nr_ranges; - - /* - * kexec-tools creates an extra PT_LOAD phdr for kernel text mapping - * area (for example, ffffffff80000000 - ffffffffa0000000 on x86_64). - * I think this is required by tools like gdb. So same physical - * memory will be mapped in two ELF headers. One will contain kernel - * text virtual addresses and other will have __va(physical) addresses. - */ - - nr_phdr++; - elf_sz = sizeof(Elf64_Ehdr) + nr_phdr * sizeof(Elf64_Phdr); - elf_sz = ALIGN(elf_sz, ELF_CORE_HEADER_ALIGN); - - buf = vzalloc(elf_sz); - if (!buf) - return -ENOMEM; - - ehdr = (Elf64_Ehdr *)buf; - phdr = (Elf64_Phdr *)(ehdr + 1); - memcpy(ehdr->e_ident, ELFMAG, SELFMAG); - ehdr->e_ident[EI_CLASS] = ELFCLASS64; - ehdr->e_ident[EI_DATA] = ELFDATA2LSB; - ehdr->e_ident[EI_VERSION] = EV_CURRENT; - ehdr->e_ident[EI_OSABI] = ELF_OSABI; - memset(ehdr->e_ident + EI_PAD, 0, EI_NIDENT - EI_PAD); - ehdr->e_type = ET_CORE; - ehdr->e_machine = ELF_ARCH; - ehdr->e_version = EV_CURRENT; - ehdr->e_phoff = sizeof(Elf64_Ehdr); - ehdr->e_ehsize = sizeof(Elf64_Ehdr); - ehdr->e_phentsize = sizeof(Elf64_Phdr); - - /* Prepare one phdr of type PT_NOTE for each possible CPU */ - for_each_possible_cpu(cpu) { - phdr->p_type = PT_NOTE; - notes_addr = per_cpu_ptr_to_phys(per_cpu_ptr(crash_notes, cpu)); - phdr->p_offset = phdr->p_paddr = notes_addr; - phdr->p_filesz = phdr->p_memsz = sizeof(note_buf_t); - (ehdr->e_phnum)++; - phdr++; - } - - /* Prepare one PT_NOTE header for vmcoreinfo */ - phdr->p_type = PT_NOTE; - phdr->p_offset = phdr->p_paddr = paddr_vmcoreinfo_note(); - phdr->p_filesz = phdr->p_memsz = VMCOREINFO_NOTE_SIZE; - (ehdr->e_phnum)++; - phdr++; - - /* Prepare PT_LOAD type program header for kernel text region */ - if (need_kernel_map) { - phdr->p_type = PT_LOAD; - phdr->p_flags = PF_R|PF_W|PF_X; - phdr->p_vaddr = (unsigned long) _text; - phdr->p_filesz = phdr->p_memsz = _end - _text; - phdr->p_offset = phdr->p_paddr = __pa_symbol(_text); - ehdr->e_phnum++; - phdr++; - } - - /* Go through all the ranges in mem->ranges[] and prepare phdr */ - for (i = 0; i < mem->nr_ranges; i++) { - mstart = mem->ranges[i].start; - mend = mem->ranges[i].end; - - phdr->p_type = PT_LOAD; - phdr->p_flags = PF_R|PF_W|PF_X; - phdr->p_offset = mstart; - - phdr->p_paddr = mstart; - phdr->p_vaddr = (unsigned long) __va(mstart); - phdr->p_filesz = phdr->p_memsz = mend - mstart + 1; - phdr->p_align = 0; - ehdr->e_phnum++; - pr_debug("Crash PT_LOAD ELF header. phdr=%p vaddr=0x%llx, paddr=0x%llx, sz=0x%llx e_phnum=%d p_offset=0x%llx\n", - phdr, phdr->p_vaddr, phdr->p_paddr, phdr->p_filesz, - ehdr->e_phnum, phdr->p_offset); - phdr++; - } - - *addr = buf; - *sz = elf_sz; - return 0; -} - -int crash_exclude_mem_range(struct crash_mem *mem, - unsigned long long mstart, unsigned long long mend) -{ - int i, j; - unsigned long long start, end, p_start, p_end; - struct range temp_range = {0, 0}; - - for (i = 0; i < mem->nr_ranges; i++) { - start = mem->ranges[i].start; - end = mem->ranges[i].end; - p_start = mstart; - p_end = mend; - - if (mstart > end || mend < start) - continue; - - /* Truncate any area outside of range */ - if (mstart < start) - p_start = start; - if (mend > end) - p_end = end; - - /* Found completely overlapping range */ - if (p_start == start && p_end == end) { - mem->ranges[i].start = 0; - mem->ranges[i].end = 0; - if (i < mem->nr_ranges - 1) { - /* Shift rest of the ranges to left */ - for (j = i; j < mem->nr_ranges - 1; j++) { - mem->ranges[j].start = - mem->ranges[j+1].start; - mem->ranges[j].end = - mem->ranges[j+1].end; - } - - /* - * Continue to check if there are another overlapping ranges - * from the current position because of shifting the above - * mem ranges. - */ - i--; - mem->nr_ranges--; - continue; - } - mem->nr_ranges--; - return 0; - } - - if (p_start > start && p_end < end) { - /* Split original range */ - mem->ranges[i].end = p_start - 1; - temp_range.start = p_end + 1; - temp_range.end = end; - } else if (p_start != start) - mem->ranges[i].end = p_start - 1; - else - mem->ranges[i].start = p_end + 1; - break; - } - - /* If a split happened, add the split to array */ - if (!temp_range.end) - return 0; - - /* Split happened */ - if (i == mem->max_nr_ranges - 1) - return -ENOMEM; - - /* Location where new range should go */ - j = i + 1; - if (j < mem->nr_ranges) { - /* Move over all ranges one slot towards the end */ - for (i = mem->nr_ranges - 1; i >= j; i--) - mem->ranges[i + 1] = mem->ranges[i]; - } - - mem->ranges[j].start = temp_range.start; - mem->ranges[j].end = temp_range.end; - mem->nr_ranges++; - return 0; -} - Elf_Word *append_elf_note(Elf_Word *buf, char *name, unsigned int type, void *data, size_t data_len) { @@ -843,223 +659,3 @@ static int __init crash_save_vmcoreinfo_init(void) } subsys_initcall(crash_save_vmcoreinfo_init); - -static int __init crash_notes_memory_init(void) -{ - /* Allocate memory for saving cpu registers. */ - size_t size, align; - - /* - * crash_notes could be allocated across 2 vmalloc pages when percpu - * is vmalloc based . vmalloc doesn't guarantee 2 continuous vmalloc - * pages are also on 2 continuous physical pages. In this case the - * 2nd part of crash_notes in 2nd page could be lost since only the - * starting address and size of crash_notes are exported through sysfs. - * Here round up the size of crash_notes to the nearest power of two - * and pass it to __alloc_percpu as align value. This can make sure - * crash_notes is allocated inside one physical page. - */ - size = sizeof(note_buf_t); - align = min(roundup_pow_of_two(sizeof(note_buf_t)), PAGE_SIZE); - - /* - * Break compile if size is bigger than PAGE_SIZE since crash_notes - * definitely will be in 2 pages with that. - */ - BUILD_BUG_ON(size > PAGE_SIZE); - - crash_notes = __alloc_percpu(size, align); - if (!crash_notes) { - pr_warn("Memory allocation for saving cpu register states failed\n"); - return -ENOMEM; - } - return 0; -} -subsys_initcall(crash_notes_memory_init); - -#ifdef CONFIG_CRASH_HOTPLUG -#undef pr_fmt -#define pr_fmt(fmt) "crash hp: " fmt - -/* - * Different than kexec/kdump loading/unloading/jumping/shrinking which - * usually rarely happen, there will be many crash hotplug events notified - * during one short period, e.g one memory board is hot added and memory - * regions are online. So mutex lock __crash_hotplug_lock is used to - * serialize the crash hotplug handling specifically. - */ -DEFINE_MUTEX(__crash_hotplug_lock); -#define crash_hotplug_lock() mutex_lock(&__crash_hotplug_lock) -#define crash_hotplug_unlock() mutex_unlock(&__crash_hotplug_lock) - -/* - * This routine utilized when the crash_hotplug sysfs node is read. - * It reflects the kernel's ability/permission to update the crash - * elfcorehdr directly. - */ -int crash_check_update_elfcorehdr(void) -{ - int rc = 0; - - crash_hotplug_lock(); - /* Obtain lock while reading crash information */ - if (!kexec_trylock()) { - pr_info("kexec_trylock() failed, elfcorehdr may be inaccurate\n"); - crash_hotplug_unlock(); - return 0; - } - if (kexec_crash_image) { - if (kexec_crash_image->file_mode) - rc = 1; - else - rc = kexec_crash_image->update_elfcorehdr; - } - /* Release lock now that update complete */ - kexec_unlock(); - crash_hotplug_unlock(); - - return rc; -} - -/* - * To accurately reflect hot un/plug changes of cpu and memory resources - * (including onling and offlining of those resources), the elfcorehdr - * (which is passed to the crash kernel via the elfcorehdr= parameter) - * must be updated with the new list of CPUs and memories. - * - * In order to make changes to elfcorehdr, two conditions are needed: - * First, the segment containing the elfcorehdr must be large enough - * to permit a growing number of resources; the elfcorehdr memory size - * is based on NR_CPUS_DEFAULT and CRASH_MAX_MEMORY_RANGES. - * Second, purgatory must explicitly exclude the elfcorehdr from the - * list of segments it checks (since the elfcorehdr changes and thus - * would require an update to purgatory itself to update the digest). - */ -static void crash_handle_hotplug_event(unsigned int hp_action, unsigned int cpu) -{ - struct kimage *image; - - crash_hotplug_lock(); - /* Obtain lock while changing crash information */ - if (!kexec_trylock()) { - pr_info("kexec_trylock() failed, elfcorehdr may be inaccurate\n"); - crash_hotplug_unlock(); - return; - } - - /* Check kdump is not loaded */ - if (!kexec_crash_image) - goto out; - - image = kexec_crash_image; - - /* Check that updating elfcorehdr is permitted */ - if (!(image->file_mode || image->update_elfcorehdr)) - goto out; - - if (hp_action == KEXEC_CRASH_HP_ADD_CPU || - hp_action == KEXEC_CRASH_HP_REMOVE_CPU) - pr_debug("hp_action %u, cpu %u\n", hp_action, cpu); - else - pr_debug("hp_action %u\n", hp_action); - - /* - * The elfcorehdr_index is set to -1 when the struct kimage - * is allocated. Find the segment containing the elfcorehdr, - * if not already found. - */ - if (image->elfcorehdr_index < 0) { - unsigned long mem; - unsigned char *ptr; - unsigned int n; - - for (n = 0; n < image->nr_segments; n++) { - mem = image->segment[n].mem; - ptr = kmap_local_page(pfn_to_page(mem >> PAGE_SHIFT)); - if (ptr) { - /* The segment containing elfcorehdr */ - if (memcmp(ptr, ELFMAG, SELFMAG) == 0) - image->elfcorehdr_index = (int)n; - kunmap_local(ptr); - } - } - } - - if (image->elfcorehdr_index < 0) { - pr_err("unable to locate elfcorehdr segment"); - goto out; - } - - /* Needed in order for the segments to be updated */ - arch_kexec_unprotect_crashkres(); - - /* Differentiate between normal load and hotplug update */ - image->hp_action = hp_action; - - /* Now invoke arch-specific update handler */ - arch_crash_handle_hotplug_event(image); - - /* No longer handling a hotplug event */ - image->hp_action = KEXEC_CRASH_HP_NONE; - image->elfcorehdr_updated = true; - - /* Change back to read-only */ - arch_kexec_protect_crashkres(); - - /* Errors in the callback is not a reason to rollback state */ -out: - /* Release lock now that update complete */ - kexec_unlock(); - crash_hotplug_unlock(); -} - -static int crash_memhp_notifier(struct notifier_block *nb, unsigned long val, void *v) -{ - switch (val) { - case MEM_ONLINE: - crash_handle_hotplug_event(KEXEC_CRASH_HP_ADD_MEMORY, - KEXEC_CRASH_HP_INVALID_CPU); - break; - - case MEM_OFFLINE: - crash_handle_hotplug_event(KEXEC_CRASH_HP_REMOVE_MEMORY, - KEXEC_CRASH_HP_INVALID_CPU); - break; - } - return NOTIFY_OK; -} - -static struct notifier_block crash_memhp_nb = { - .notifier_call = crash_memhp_notifier, - .priority = 0 -}; - -static int crash_cpuhp_online(unsigned int cpu) -{ - crash_handle_hotplug_event(KEXEC_CRASH_HP_ADD_CPU, cpu); - return 0; -} - -static int crash_cpuhp_offline(unsigned int cpu) -{ - crash_handle_hotplug_event(KEXEC_CRASH_HP_REMOVE_CPU, cpu); - return 0; -} - -static int __init crash_hotplug_init(void) -{ - int result = 0; - - if (IS_ENABLED(CONFIG_MEMORY_HOTPLUG)) - register_memory_notifier(&crash_memhp_nb); - - if (IS_ENABLED(CONFIG_HOTPLUG_CPU)) { - result = cpuhp_setup_state_nocalls(CPUHP_BP_PREPARE_DYN, - "crash/cpuhp", crash_cpuhp_online, crash_cpuhp_offline); - } - - return result; -} - -subsys_initcall(crash_hotplug_init); -#endif diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c index be5642a4ec49..ec481e5a9330 100644 --- a/kernel/kexec_core.c +++ b/kernel/kexec_core.c @@ -40,6 +40,8 @@ #include <linux/hugetlb.h> #include <linux/objtool.h> #include <linux/kmsg_dump.h> +#include <linux/memory.h> +#include <linux/cpuhotplug.h> #include <asm/page.h> #include <asm/sections.h> @@ -49,6 +51,9 @@ atomic_t __kexec_lock = ATOMIC_INIT(0); +/* Per cpu memory for storing cpu states in case of system crash. */ +note_buf_t __percpu *crash_notes; + /* Flag to indicate we are going to kexec a new kernel */ bool kexec_in_progress = false; @@ -1082,6 +1087,189 @@ static inline resource_size_t crash_resource_size(const struct resource *res) return !res->end ? 0 : resource_size(res); } +int crash_prepare_elf64_headers(struct crash_mem *mem, int need_kernel_map, + void **addr, unsigned long *sz) +{ + Elf64_Ehdr *ehdr; + Elf64_Phdr *phdr; + unsigned long nr_cpus = num_possible_cpus(), nr_phdr, elf_sz; + unsigned char *buf; + unsigned int cpu, i; + unsigned long long notes_addr; + unsigned long mstart, mend; + + /* extra phdr for vmcoreinfo ELF note */ + nr_phdr = nr_cpus + 1; + nr_phdr += mem->nr_ranges; + + /* + * kexec-tools creates an extra PT_LOAD phdr for kernel text mapping + * area (for example, ffffffff80000000 - ffffffffa0000000 on x86_64). + * I think this is required by tools like gdb. So same physical + * memory will be mapped in two ELF headers. One will contain kernel + * text virtual addresses and other will have __va(physical) addresses. + */ + + nr_phdr++; + elf_sz = sizeof(Elf64_Ehdr) + nr_phdr * sizeof(Elf64_Phdr); + elf_sz = ALIGN(elf_sz, ELF_CORE_HEADER_ALIGN); + + buf = vzalloc(elf_sz); + if (!buf) + return -ENOMEM; + + ehdr = (Elf64_Ehdr *)buf; + phdr = (Elf64_Phdr *)(ehdr + 1); + memcpy(ehdr->e_ident, ELFMAG, SELFMAG); + ehdr->e_ident[EI_CLASS] = ELFCLASS64; + ehdr->e_ident[EI_DATA] = ELFDATA2LSB; + ehdr->e_ident[EI_VERSION] = EV_CURRENT; + ehdr->e_ident[EI_OSABI] = ELF_OSABI; + memset(ehdr->e_ident + EI_PAD, 0, EI_NIDENT - EI_PAD); + ehdr->e_type = ET_CORE; + ehdr->e_machine = ELF_ARCH; + ehdr->e_version = EV_CURRENT; + ehdr->e_phoff = sizeof(Elf64_Ehdr); + ehdr->e_ehsize = sizeof(Elf64_Ehdr); + ehdr->e_phentsize = sizeof(Elf64_Phdr); + + /* Prepare one phdr of type PT_NOTE for each possible CPU */ + for_each_possible_cpu(cpu) { + phdr->p_type = PT_NOTE; + notes_addr = per_cpu_ptr_to_phys(per_cpu_ptr(crash_notes, cpu)); + phdr->p_offset = phdr->p_paddr = notes_addr; + phdr->p_filesz = phdr->p_memsz = sizeof(note_buf_t); + (ehdr->e_phnum)++; + phdr++; + } + + /* Prepare one PT_NOTE header for vmcoreinfo */ + phdr->p_type = PT_NOTE; + phdr->p_offset = phdr->p_paddr = paddr_vmcoreinfo_note(); + phdr->p_filesz = phdr->p_memsz = VMCOREINFO_NOTE_SIZE; + (ehdr->e_phnum)++; + phdr++; + + /* Prepare PT_LOAD type program header for kernel text region */ + if (need_kernel_map) { + phdr->p_type = PT_LOAD; + phdr->p_flags = PF_R|PF_W|PF_X; + phdr->p_vaddr = (unsigned long) _text; + phdr->p_filesz = phdr->p_memsz = _end - _text; + phdr->p_offset = phdr->p_paddr = __pa_symbol(_text); + ehdr->e_phnum++; + phdr++; + } + + /* Go through all the ranges in mem->ranges[] and prepare phdr */ + for (i = 0; i < mem->nr_ranges; i++) { + mstart = mem->ranges[i].start; + mend = mem->ranges[i].end; + + phdr->p_type = PT_LOAD; + phdr->p_flags = PF_R|PF_W|PF_X; + phdr->p_offset = mstart; + + phdr->p_paddr = mstart; + phdr->p_vaddr = (unsigned long) __va(mstart); + phdr->p_filesz = phdr->p_memsz = mend - mstart + 1; + phdr->p_align = 0; + ehdr->e_phnum++; + pr_debug("Crash PT_LOAD ELF header. phdr=%p vaddr=0x%llx, paddr=0x%llx, sz=0x%llx e_phnum=%d p_offset=0x%llx\n", + phdr, phdr->p_vaddr, phdr->p_paddr, phdr->p_filesz, + ehdr->e_phnum, phdr->p_offset); + phdr++; + } + + *addr = buf; + *sz = elf_sz; + return 0; +} + +int crash_exclude_mem_range(struct crash_mem *mem, + unsigned long long mstart, unsigned long long mend) +{ + int i, j; + unsigned long long start, end, p_start, p_end; + struct range temp_range = {0, 0}; + + for (i = 0; i < mem->nr_ranges; i++) { + start = mem->ranges[i].start; + end = mem->ranges[i].end; + p_start = mstart; + p_end = mend; + + if (mstart > end || mend < start) + continue; + + /* Truncate any area outside of range */ + if (mstart < start) + p_start = start; + if (mend > end) + p_end = end; + + /* Found completely overlapping range */ + if (p_start == start && p_end == end) { + mem->ranges[i].start = 0; + mem->ranges[i].end = 0; + if (i < mem->nr_ranges - 1) { + /* Shift rest of the ranges to left */ + for (j = i; j < mem->nr_ranges - 1; j++) { + mem->ranges[j].start = + mem->ranges[j+1].start; + mem->ranges[j].end = + mem->ranges[j+1].end; + } + + /* + * Continue to check if there are another overlapping ranges + * from the current position because of shifting the above + * mem ranges. + */ + i--; + mem->nr_ranges--; + continue; + } + mem->nr_ranges--; + return 0; + } + + if (p_start > start && p_end < end) { + /* Split original range */ + mem->ranges[i].end = p_start - 1; + temp_range.start = p_end + 1; + temp_range.end = end; + } else if (p_start != start) + mem->ranges[i].end = p_start - 1; + else + mem->ranges[i].start = p_end + 1; + break; + } + + /* If a split happened, add the split to array */ + if (!temp_range.end) + return 0; + + /* Split happened */ + if (i == mem->max_nr_ranges - 1) + return -ENOMEM; + + /* Location where new range should go */ + j = i + 1; + if (j < mem->nr_ranges) { + /* Move over all ranges one slot towards the end */ + for (i = mem->nr_ranges - 1; i >= j; i--) + mem->ranges[i + 1] = mem->ranges[i]; + } + + mem->ranges[j].start = temp_range.start; + mem->ranges[j].end = temp_range.end; + mem->nr_ranges++; + return 0; +} + + + ssize_t crash_get_memory_size(void) { ssize_t size = 0; @@ -1204,6 +1392,226 @@ void crash_save_cpu(struct pt_regs *regs, int cpu) final_note(buf); } +static int __init crash_notes_memory_init(void) +{ + /* Allocate memory for saving cpu registers. */ + size_t size, align; + + /* + * crash_notes could be allocated across 2 vmalloc pages when percpu + * is vmalloc based . vmalloc doesn't guarantee 2 continuous vmalloc + * pages are also on 2 continuous physical pages. In this case the + * 2nd part of crash_notes in 2nd page could be lost since only the + * starting address and size of crash_notes are exported through sysfs. + * Here round up the size of crash_notes to the nearest power of two + * and pass it to __alloc_percpu as align value. This can make sure + * crash_notes is allocated inside one physical page. + */ + size = sizeof(note_buf_t); + align = min(roundup_pow_of_two(sizeof(note_buf_t)), PAGE_SIZE); + + /* + * Break compile if size is bigger than PAGE_SIZE since crash_notes + * definitely will be in 2 pages with that. + */ + BUILD_BUG_ON(size > PAGE_SIZE); + + crash_notes = __alloc_percpu(size, align); + if (!crash_notes) { + pr_warn("Memory allocation for saving cpu register states failed\n"); + return -ENOMEM; + } + return 0; +} +subsys_initcall(crash_notes_memory_init); + +#ifdef CONFIG_CRASH_HOTPLUG +#undef pr_fmt +#define pr_fmt(fmt) "crash hp: " fmt + +/* + * Different than kexec/kdump loading/unloading/jumping/shrinking which + * usually rarely happen, there will be many crash hotplug events notified + * during one short period, e.g one memory board is hot added and memory + * regions are online. So mutex lock __crash_hotplug_lock is used to + * serialize the crash hotplug handling specifically. + */ +DEFINE_MUTEX(__crash_hotplug_lock); +#define crash_hotplug_lock() mutex_lock(&__crash_hotplug_lock) +#define crash_hotplug_unlock() mutex_unlock(&__crash_hotplug_lock) + +/* + * This routine utilized when the crash_hotplug sysfs node is read. + * It reflects the kernel's ability/permission to update the crash + * elfcorehdr directly. + */ +int crash_check_update_elfcorehdr(void) +{ + int rc = 0; + + crash_hotplug_lock(); + /* Obtain lock while reading crash information */ + if (!kexec_trylock()) { + pr_info("kexec_trylock() failed, elfcorehdr may be inaccurate\n"); + crash_hotplug_unlock(); + return 0; + } + if (kexec_crash_image) { + if (kexec_crash_image->file_mode) + rc = 1; + else + rc = kexec_crash_image->update_elfcorehdr; + } + /* Release lock now that update complete */ + kexec_unlock(); + crash_hotplug_unlock(); + + return rc; +} + +/* + * To accurately reflect hot un/plug changes of cpu and memory resources + * (including onling and offlining of those resources), the elfcorehdr + * (which is passed to the crash kernel via the elfcorehdr= parameter) + * must be updated with the new list of CPUs and memories. + * + * In order to make changes to elfcorehdr, two conditions are needed: + * First, the segment containing the elfcorehdr must be large enough + * to permit a growing number of resources; the elfcorehdr memory size + * is based on NR_CPUS_DEFAULT and CRASH_MAX_MEMORY_RANGES. + * Second, purgatory must explicitly exclude the elfcorehdr from the + * list of segments it checks (since the elfcorehdr changes and thus + * would require an update to purgatory itself to update the digest). + */ +static void crash_handle_hotplug_event(unsigned int hp_action, unsigned int cpu) +{ + struct kimage *image; + + crash_hotplug_lock(); + /* Obtain lock while changing crash information */ + if (!kexec_trylock()) { + pr_info("kexec_trylock() failed, elfcorehdr may be inaccurate\n"); + crash_hotplug_unlock(); + return; + } + + /* Check kdump is not loaded */ + if (!kexec_crash_image) + goto out; + + image = kexec_crash_image; + + /* Check that updating elfcorehdr is permitted */ + if (!(image->file_mode || image->update_elfcorehdr)) + goto out; + + if (hp_action == KEXEC_CRASH_HP_ADD_CPU || + hp_action == KEXEC_CRASH_HP_REMOVE_CPU) + pr_debug("hp_action %u, cpu %u\n", hp_action, cpu); + else + pr_debug("hp_action %u\n", hp_action); + + /* + * The elfcorehdr_index is set to -1 when the struct kimage + * is allocated. Find the segment containing the elfcorehdr, + * if not already found. + */ + if (image->elfcorehdr_index < 0) { + unsigned long mem; + unsigned char *ptr; + unsigned int n; + + for (n = 0; n < image->nr_segments; n++) { + mem = image->segment[n].mem; + ptr = kmap_local_page(pfn_to_page(mem >> PAGE_SHIFT)); + if (ptr) { + /* The segment containing elfcorehdr */ + if (memcmp(ptr, ELFMAG, SELFMAG) == 0) + image->elfcorehdr_index = (int)n; + kunmap_local(ptr); + } + } + } + + if (image->elfcorehdr_index < 0) { + pr_err("unable to locate elfcorehdr segment"); + goto out; + } + + /* Needed in order for the segments to be updated */ + arch_kexec_unprotect_crashkres(); + + /* Differentiate between normal load and hotplug update */ + image->hp_action = hp_action; + + /* Now invoke arch-specific update handler */ + arch_crash_handle_hotplug_event(image); + + /* No longer handling a hotplug event */ + image->hp_action = KEXEC_CRASH_HP_NONE; + image->elfcorehdr_updated = true; + + /* Change back to read-only */ + arch_kexec_protect_crashkres(); + + /* Errors in the callback is not a reason to rollback state */ +out: + /* Release lock now that update complete */ + kexec_unlock(); + crash_hotplug_unlock(); +} + +static int crash_memhp_notifier(struct notifier_block *nb, unsigned long val, void *v) +{ + switch (val) { + case MEM_ONLINE: + crash_handle_hotplug_event(KEXEC_CRASH_HP_ADD_MEMORY, + KEXEC_CRASH_HP_INVALID_CPU); + break; + + case MEM_OFFLINE: + crash_handle_hotplug_event(KEXEC_CRASH_HP_REMOVE_MEMORY, + KEXEC_CRASH_HP_INVALID_CPU); + break; + } + return NOTIFY_OK; +} + +static struct notifier_block crash_memhp_nb = { + .notifier_call = crash_memhp_notifier, + .priority = 0 +}; + +static int crash_cpuhp_online(unsigned int cpu) +{ + crash_handle_hotplug_event(KEXEC_CRASH_HP_ADD_CPU, cpu); + return 0; +} + +static int crash_cpuhp_offline(unsigned int cpu) +{ + crash_handle_hotplug_event(KEXEC_CRASH_HP_REMOVE_CPU, cpu); + return 0; +} + +static int __init crash_hotplug_init(void) +{ + int result = 0; + + if (IS_ENABLED(CONFIG_MEMORY_HOTPLUG)) + register_memory_notifier(&crash_memhp_nb); + + if (IS_ENABLED(CONFIG_HOTPLUG_CPU)) { + result = cpuhp_setup_state_nocalls(CPUHP_BP_PREPARE_DYN, + "crash/cpuhp", crash_cpuhp_online, crash_cpuhp_offline); + } + + return result; +} + +subsys_initcall(crash_hotplug_init); +#endif + /* * Move into place and start executing a preloaded standalone * executable. If nothing was preloaded return an error.
In commit 6f991cc363a3 ("crash: move a few code bits to setup support of crash hotplug"), some elfcorehdr processing codes were moved to kernel/crash_core.c so that they can be shared by kexec_load and kexec_file_load interface. And later in commit 247262756121 ("crash: add generic infrastructure for crash hotplug support"), generic code for crash hotplug support codes were added into kernel/crash_core.c. In fact, these codes should be put in kernel/kexec_core.c because both kexec_load and kexec_file_load need them. So move them from kernel/crash_core.c to kernel/kexec_core.c. No functionality change is introduced. Signed-off-by: Baoquan He <bhe@redhat.com> --- include/linux/crash_core.h | 26 --- include/linux/kexec.h | 24 +++ kernel/crash_core.c | 404 ------------------------------------ kernel/kexec_core.c | 408 +++++++++++++++++++++++++++++++++++++ 4 files changed, 432 insertions(+), 430 deletions(-)