debug_kinfo.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * debug_kinfo.c - backup kernel information for bootloader usage
  4. *
  5. * Copyright 2002 Rusty Russell <[email protected]> IBM Corporation
  6. * Copyright 2021 Google LLC
  7. */
  8. #include <linux/platform_device.h>
  9. #include <linux/kallsyms.h>
  10. #include <linux/vmalloc.h>
  11. #include <linux/module.h>
  12. #include <linux/of_address.h>
  13. #include <linux/of_reserved_mem.h>
  14. #include <linux/pgtable.h>
  15. #include <asm/module.h>
  16. #include "debug_kinfo.h"
  17. /*
  18. * These will be re-linked against their real values
  19. * during the second link stage.
  20. */
  21. extern const unsigned long kallsyms_addresses[] __weak;
  22. extern const int kallsyms_offsets[] __weak;
  23. extern const u8 kallsyms_names[] __weak;
  24. /*
  25. * Tell the compiler that the count isn't in the small data section if the arch
  26. * has one (eg: FRV).
  27. */
  28. extern const unsigned int kallsyms_num_syms __weak
  29. __section(".rodata");
  30. extern const unsigned long kallsyms_relative_base __weak
  31. __section(".rodata");
  32. extern const u8 kallsyms_token_table[] __weak;
  33. extern const u16 kallsyms_token_index[] __weak;
  34. extern const unsigned int kallsyms_markers[] __weak;
  35. static void *all_info_addr;
  36. static u32 all_info_size;
  37. static void update_kernel_all_info(struct kernel_all_info *all_info)
  38. {
  39. int index;
  40. struct kernel_info *info;
  41. u32 *checksum_info;
  42. all_info->magic_number = DEBUG_KINFO_MAGIC;
  43. all_info->combined_checksum = 0;
  44. info = &(all_info->info);
  45. checksum_info = (u32 *)info;
  46. for (index = 0; index < sizeof(*info) / sizeof(u32); index++)
  47. all_info->combined_checksum ^= checksum_info[index];
  48. }
  49. static int build_info_set(const char *str, const struct kernel_param *kp)
  50. {
  51. struct kernel_all_info *all_info;
  52. size_t build_info_size;
  53. int ret = 0;
  54. if (all_info_addr == 0 || all_info_size == 0) {
  55. ret = -EPERM;
  56. goto Exit;
  57. }
  58. all_info = (struct kernel_all_info *)all_info_addr;
  59. build_info_size = sizeof(all_info->info.build_info);
  60. memcpy(&all_info->info.build_info, str, min(build_info_size - 1, strlen(str)));
  61. update_kernel_all_info(all_info);
  62. if (strlen(str) > build_info_size) {
  63. pr_warn("%s: Build info buffer (len: %zd) can't hold entire string '%s'\n",
  64. __func__, build_info_size, str);
  65. ret = -ENOMEM;
  66. }
  67. Exit:
  68. return ret;
  69. }
  70. static const struct kernel_param_ops build_info_op = {
  71. .set = build_info_set,
  72. };
  73. module_param_cb(build_info, &build_info_op, NULL, 0200);
  74. MODULE_PARM_DESC(build_info, "Write build info to field 'build_info' of debug kinfo.");
  75. static int debug_kinfo_probe(struct platform_device *pdev)
  76. {
  77. struct device_node *mem_region;
  78. struct reserved_mem *rmem;
  79. struct kernel_all_info *all_info;
  80. struct kernel_info *info;
  81. mem_region = of_parse_phandle(pdev->dev.of_node, "memory-region", 0);
  82. if (!mem_region) {
  83. dev_warn(&pdev->dev, "no such memory-region\n");
  84. return -ENODEV;
  85. }
  86. rmem = of_reserved_mem_lookup(mem_region);
  87. if (!rmem) {
  88. dev_warn(&pdev->dev, "no such reserved mem of node name %s\n",
  89. pdev->dev.of_node->name);
  90. return -ENODEV;
  91. }
  92. /* Need to wait for reserved memory to be mapped */
  93. if (!rmem->priv) {
  94. return -EPROBE_DEFER;
  95. }
  96. if (!rmem->base || !rmem->size) {
  97. dev_warn(&pdev->dev, "unexpected reserved memory\n");
  98. return -EINVAL;
  99. }
  100. if (rmem->size < sizeof(struct kernel_all_info)) {
  101. dev_warn(&pdev->dev, "unexpected reserved memory size\n");
  102. return -EINVAL;
  103. }
  104. all_info_addr = rmem->priv;
  105. all_info_size = rmem->size;
  106. memset(all_info_addr, 0, sizeof(struct kernel_all_info));
  107. all_info = (struct kernel_all_info *)all_info_addr;
  108. info = &(all_info->info);
  109. info->enabled_all = IS_ENABLED(CONFIG_KALLSYMS_ALL);
  110. info->enabled_base_relative = IS_ENABLED(CONFIG_KALLSYMS_BASE_RELATIVE);
  111. info->enabled_absolute_percpu = IS_ENABLED(CONFIG_KALLSYMS_ABSOLUTE_PERCPU);
  112. info->enabled_cfi_clang = IS_ENABLED(CONFIG_CFI_CLANG);
  113. info->num_syms = kallsyms_num_syms;
  114. info->name_len = KSYM_NAME_LEN;
  115. info->bit_per_long = BITS_PER_LONG;
  116. info->module_name_len = MODULE_NAME_LEN;
  117. info->symbol_len = KSYM_SYMBOL_LEN;
  118. if (!info->enabled_base_relative)
  119. info->_addresses_pa = (u64)__pa_symbol((volatile void *)kallsyms_addresses);
  120. else {
  121. info->_relative_pa = (u64)__pa_symbol((volatile void *)kallsyms_relative_base);
  122. info->_offsets_pa = (u64)__pa_symbol((volatile void *)kallsyms_offsets);
  123. }
  124. info->_stext_pa = (u64)__pa_symbol(_stext);
  125. info->_etext_pa = (u64)__pa_symbol(_etext);
  126. info->_sinittext_pa = (u64)__pa_symbol(_sinittext);
  127. info->_einittext_pa = (u64)__pa_symbol(_einittext);
  128. info->_end_pa = (u64)__pa_symbol(_end);
  129. info->_names_pa = (u64)__pa_symbol((volatile void *)kallsyms_names);
  130. info->_token_table_pa = (u64)__pa_symbol((volatile void *)kallsyms_token_table);
  131. info->_token_index_pa = (u64)__pa_symbol((volatile void *)kallsyms_token_index);
  132. info->_markers_pa = (u64)__pa_symbol((volatile void *)kallsyms_markers);
  133. info->thread_size = THREAD_SIZE;
  134. info->swapper_pg_dir_pa = (u64)__pa_symbol(swapper_pg_dir);
  135. strlcpy(info->last_uts_release, init_utsname()->release, sizeof(info->last_uts_release));
  136. info->enabled_modules_tree_lookup = IS_ENABLED(CONFIG_MODULES_TREE_LOOKUP);
  137. info->mod_core_layout_offset = offsetof(struct module, core_layout);
  138. info->mod_init_layout_offset = offsetof(struct module, init_layout);
  139. info->mod_kallsyms_offset = offsetof(struct module, kallsyms);
  140. #if defined(CONFIG_RANDOMIZE_BASE) && defined(MODULES_VSIZE)
  141. info->module_start_va = module_alloc_base;
  142. info->module_end_va = info->module_start_va + MODULES_VSIZE;
  143. #elif defined(CONFIG_MODULES) && defined(MODULES_VADDR)
  144. info->module_start_va = MODULES_VADDR;
  145. info->module_end_va = MODULES_END;
  146. #else
  147. info->module_start_va = VMALLOC_START;
  148. info->module_end_va = VMALLOC_END;
  149. #endif
  150. update_kernel_all_info(all_info);
  151. return 0;
  152. }
  153. static const struct of_device_id debug_kinfo_of_match[] = {
  154. { .compatible = "google,debug-kinfo" },
  155. {},
  156. };
  157. MODULE_DEVICE_TABLE(of, debug_kinfo_of_match);
  158. static struct platform_driver debug_kinfo_driver = {
  159. .probe = debug_kinfo_probe,
  160. .driver = {
  161. .name = "debug-kinfo",
  162. .of_match_table = of_match_ptr(debug_kinfo_of_match),
  163. },
  164. };
  165. module_platform_driver(debug_kinfo_driver);
  166. MODULE_AUTHOR("Jone Chou <[email protected]>");
  167. MODULE_DESCRIPTION("Debug Kinfo Driver");
  168. MODULE_LICENSE("GPL v2");