kdebuginfo: Interface to set buildinfo
Bug: 154441754
Bug: 182735318
Change-Id: I2d6efccab9c8b0ee8a8f6c0d069205403d890296
Signed-off-by: Woody Lin <woodylin@google.com>
(cherry picked from commit a79a9d5aba6790859b725aaa8a0a618da867d62f)
diff --git a/kernel/kdebuginfo.c b/kernel/kdebuginfo.c
index ce977da..5cdd6d2 100644
--- a/kernel/kdebuginfo.c
+++ b/kernel/kdebuginfo.c
@@ -39,6 +39,8 @@
extern const unsigned long kallsyms_markers[] __weak;
+static phys_addr_t all_info_addr;
+
/*
* Header structure must be byte-packed, since the table is provided to
* bootloader.
@@ -81,6 +83,9 @@
/* For mmu table */
u64 swapper_pg_dir;
+
+ /* Info of running build */
+ char build_info[32];
} __packed;
struct kernel_all_info {
@@ -89,6 +94,24 @@
struct kernel_info info;
} __packed;
+static void update_all_info_toio(void __iomem *io_base,
+ struct kernel_all_info *all_info)
+{
+ int index;
+ struct kernel_info *info;
+ u32 *checksum_info;
+
+ all_info->magic_number = BOOT_DEBUG_MAGIC;
+ all_info->combined_checksum = 0;
+
+ info = &(all_info->info);
+ checksum_info = (u32 *)info;
+ for (index = 0; index < sizeof(*info)/sizeof(u32); index++)
+ all_info->combined_checksum ^= checksum_info[index];
+
+ memcpy_toio(io_base, all_info, sizeof(*all_info));
+}
+
static void backup_kernel_info(void)
{
struct device_node *np;
@@ -96,9 +119,8 @@
struct kernel_all_info all_info;
struct kernel_info *info;
void __iomem *info_base;
- u32 *checksum_info;
int num_reg = 0;
- int ret, index;
+ int ret;
np = of_find_compatible_node(NULL, NULL, "bootloader_kinfo");
if (!np) {
@@ -119,6 +141,8 @@
return;
}
+ all_info_addr = res.start;
+
info_base = ioremap(res.start, resource_size(&res));
if (!info_base) {
pr_warn("%s: bootloader kernel info offset mapping failed\n",
@@ -160,17 +184,48 @@
sizeof(info->last_uts_release));
info->swapper_pg_dir = (u64)swapper_pg_dir;
- checksum_info = (u32 *)info;
- for (index = 0; index < sizeof(struct kernel_info)/sizeof(u32);
- index++) {
- all_info.combined_checksum ^= checksum_info[index];
- }
-
- all_info.magic_number = BOOT_DEBUG_MAGIC;
- memcpy_toio(info_base, &all_info, sizeof(struct kernel_all_info));
+ update_all_info_toio(info_base, &all_info);
iounmap(info_base);
}
+static int build_info_set(const char *str, const struct kernel_param *kp)
+{
+ void __iomem *info_base;
+ struct kernel_all_info all_info;
+ const size_t build_info_size = sizeof(all_info.info.build_info);
+
+ if (all_info_addr == 0)
+ return -EPERM;
+
+ info_base = ioremap(all_info_addr, sizeof(all_info));
+ if (!info_base) {
+ pr_err("%s: Failed to map all_info\n", __func__);
+ return -EPERM;
+ }
+
+ memcpy_fromio(&all_info, info_base, sizeof(all_info));
+ memcpy(&all_info.info.build_info, str,
+ min(build_info_size, strlen(str)));
+ update_all_info_toio(info_base, &all_info);
+ iounmap(info_base);
+
+ if (strlen(str) > build_info_size) {
+ pr_warn("%s: buffer too small (%zd bytes) for string '%s'\n",
+ __func__, build_info_size, str);
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+static const struct kernel_param_ops build_info_op = {
+ .set = build_info_set,
+};
+
+module_param_cb(build_info, &build_info_op, NULL, 0200);
+MODULE_PARM_DESC(build_info,
+ "Write build info to field 'build_info' of kdebuginfo.");
+
static int __init kdebuginfo_init(void)
{
/* Backup kernel information for bootloader */