hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/kernel/crash_core.c
....@@ -1,9 +1,7 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * crash.c - kernel crash support code.
34 * Copyright (C) 2002-2004 Eric Biederman <ebiederm@xmission.com>
4
- *
5
- * This source code is licensed under the GNU General Public License,
6
- * Version 2. See the file COPYING for more details.
75 */
86
97 #include <linux/crash_core.h>
....@@ -12,6 +10,8 @@
1210
1311 #include <asm/page.h>
1412 #include <asm/sections.h>
13
+
14
+#include <crypto/sha.h>
1515
1616 /* vmcoreinfo stuff */
1717 unsigned char *vmcoreinfo_data;
....@@ -378,6 +378,53 @@
378378 }
379379 EXPORT_SYMBOL(paddr_vmcoreinfo_note);
380380
381
+#define NOTES_SIZE (&__stop_notes - &__start_notes)
382
+#define BUILD_ID_MAX SHA1_DIGEST_SIZE
383
+#define NT_GNU_BUILD_ID 3
384
+
385
+struct elf_note_section {
386
+ struct elf_note n_hdr;
387
+ u8 n_data[];
388
+};
389
+
390
+/*
391
+ * Add build ID from .notes section as generated by the GNU ld(1)
392
+ * or LLVM lld(1) --build-id option.
393
+ */
394
+static void add_build_id_vmcoreinfo(void)
395
+{
396
+ char build_id[BUILD_ID_MAX * 2 + 1];
397
+ int n_remain = NOTES_SIZE;
398
+
399
+ while (n_remain >= sizeof(struct elf_note)) {
400
+ const struct elf_note_section *note_sec =
401
+ &__start_notes + NOTES_SIZE - n_remain;
402
+ const u32 n_namesz = note_sec->n_hdr.n_namesz;
403
+
404
+ if (note_sec->n_hdr.n_type == NT_GNU_BUILD_ID &&
405
+ n_namesz != 0 &&
406
+ !strcmp((char *)&note_sec->n_data[0], "GNU")) {
407
+ if (note_sec->n_hdr.n_descsz <= BUILD_ID_MAX) {
408
+ const u32 n_descsz = note_sec->n_hdr.n_descsz;
409
+ const u8 *s = &note_sec->n_data[n_namesz];
410
+
411
+ s = PTR_ALIGN(s, 4);
412
+ bin2hex(build_id, s, n_descsz);
413
+ build_id[2 * n_descsz] = '\0';
414
+ VMCOREINFO_BUILD_ID(build_id);
415
+ return;
416
+ }
417
+ pr_warn("Build ID is too large to include in vmcoreinfo: %u > %u\n",
418
+ note_sec->n_hdr.n_descsz,
419
+ BUILD_ID_MAX);
420
+ return;
421
+ }
422
+ n_remain -= sizeof(struct elf_note) +
423
+ ALIGN(note_sec->n_hdr.n_namesz, 4) +
424
+ ALIGN(note_sec->n_hdr.n_descsz, 4);
425
+ }
426
+}
427
+
381428 static int __init crash_save_vmcoreinfo_init(void)
382429 {
383430 vmcoreinfo_data = (unsigned char *)get_zeroed_page(GFP_KERNEL);
....@@ -396,6 +443,7 @@
396443 }
397444
398445 VMCOREINFO_OSRELEASE(init_uts_ns.name.release);
446
+ add_build_id_vmcoreinfo();
399447 VMCOREINFO_PAGESIZE(PAGE_SIZE);
400448
401449 VMCOREINFO_SYMBOL(init_uts_ns);
....@@ -415,6 +463,8 @@
415463 VMCOREINFO_LENGTH(mem_section, NR_SECTION_ROOTS);
416464 VMCOREINFO_STRUCT_SIZE(mem_section);
417465 VMCOREINFO_OFFSET(mem_section, section_mem_map);
466
+ VMCOREINFO_NUMBER(SECTION_SIZE_BITS);
467
+ VMCOREINFO_NUMBER(MAX_PHYSMEM_BITS);
418468 #endif
419469 VMCOREINFO_STRUCT_SIZE(page);
420470 VMCOREINFO_STRUCT_SIZE(pglist_data);
....@@ -464,6 +514,8 @@
464514 VMCOREINFO_NUMBER(PAGE_BUDDY_MAPCOUNT_VALUE);
465515 #ifdef CONFIG_HUGETLB_PAGE
466516 VMCOREINFO_NUMBER(HUGETLB_PAGE_DTOR);
517
+#define PAGE_OFFLINE_MAPCOUNT_VALUE (~PG_offline)
518
+ VMCOREINFO_NUMBER(PAGE_OFFLINE_MAPCOUNT_VALUE);
467519 #endif
468520
469521 arch_crash_save_vmcoreinfo();