Merge "arm64: defconfig: Enable minidump for pineapple"

This commit is contained in:
qctecmdr 2022-12-02 15:12:43 -08:00 committed by Gerrit - the friendly Code Review server
commit 441740dd53
8 changed files with 287 additions and 11 deletions

View File

@ -62,6 +62,8 @@ CONFIG_MHI_BUS=m
CONFIG_MHI_BUS_MISC=y
CONFIG_MHI_SATELLITE=m
CONFIG_MHI_UCI=m
# CONFIG_MINIDUMP_ALL_TASK_INFO is not set
CONFIG_MINIDUMP_MAX_ENTRIES=200
CONFIG_MMC_SDHCI_MSM=m
# CONFIG_MODULE_SIG_ALL is not set
CONFIG_MSM_BOOT_STATS=m
@ -102,6 +104,7 @@ CONFIG_QCOM_CRM=m
CONFIG_QCOM_DCC_V2=m
CONFIG_QCOM_DCVS=m
CONFIG_QCOM_DCVS_FP=m
CONFIG_QCOM_DEBUG_SYMBOL=m
CONFIG_QCOM_DMABUF_HEAPS=m
CONFIG_QCOM_DMABUF_HEAPS_CARVEOUT=y
CONFIG_QCOM_DMABUF_HEAPS_CMA=y
@ -109,6 +112,7 @@ CONFIG_QCOM_DMABUF_HEAPS_PAGE_POOL_REFILL=y
CONFIG_QCOM_DMABUF_HEAPS_SYSTEM=y
CONFIG_QCOM_DMABUF_HEAPS_SYSTEM_SECURE=y
CONFIG_QCOM_DMABUF_HEAPS_UBWCP=y
# CONFIG_QCOM_DYN_MINIDUMP_STACK is not set
CONFIG_QCOM_EUD=m
CONFIG_QCOM_FORCE_WDOG_BITE_ON_PANIC=y
CONFIG_QCOM_GDSC_REGULATOR=m
@ -132,7 +136,10 @@ CONFIG_QCOM_MEM_BUF_DEV_GH=y
CONFIG_QCOM_MEM_BUF_GH=y
CONFIG_QCOM_MEM_BUF_MSGQ=m
CONFIG_QCOM_MEM_OFFLINE=m
# CONFIG_QCOM_MINIDUMP is not set
CONFIG_QCOM_MINIDUMP=m
# CONFIG_QCOM_MINIDUMP_FTRACE is not set
# CONFIG_QCOM_MINIDUMP_PANIC_DUMP is not set
# CONFIG_QCOM_MINIDUMP_PSTORE is not set
CONFIG_QCOM_PANEL_EVENT_NOTIFIER=m
CONFIG_QCOM_PANIC_ON_NOTIF_TIMEOUT=y
CONFIG_QCOM_PANIC_ON_PDR_NOTIF_TIMEOUT=y
@ -168,6 +175,7 @@ CONFIG_QCOM_SPSS=m
CONFIG_QCOM_STATS=m
CONFIG_QCOM_TSENS=m
CONFIG_QCOM_VADC_COMMON=m
# CONFIG_QCOM_VA_MINIDUMP is not set
CONFIG_QCOM_WATCHDOG_BARK_TIME=11000
CONFIG_QCOM_WATCHDOG_IPI_PING=y
CONFIG_QCOM_WATCHDOG_PET_TIME=9360

View File

@ -825,6 +825,14 @@ config QCOM_ICC_BWMON
the fixed bandwidth votes from cpufreq (CPU nodes) thus achieve high
memory throughput even with lower CPU frequencies.
config QCOM_DEBUG_SYMBOL
tristate "Enable Debug Symbol Support"
help
This enables Debug Symbol Support. This driver is based on
Google Debug Kinfo driver, according to the provided info, this
driver allows other modules to get symbol addresses by traversing
kallsyms table for debug usage.
source "drivers/soc/qcom/mem_buf/Kconfig"
source "drivers/soc/qcom/tmecom/Kconfig"

View File

@ -80,3 +80,4 @@ wcd_usbss_i2c-y += wcd-usbss-tables.o
wcd_usbss_i2c-y += wcd-usbss-utils.o
wcd_usbss_i2c-y += wcd939x-i2c.o
obj-$(CONFIG_QCOM_PANEL_EVENT_NOTIFIER) += panel_event_notifier.o
obj-$(CONFIG_QCOM_DEBUG_SYMBOL) += debug_symbol.o

View File

@ -0,0 +1,227 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* kallsyms.c: in-kernel printing of symbolic oopses and stack traces.
*
* Rewritten and vastly simplified by Rusty Russell for in-kernel
* module loader:
* Copyright 2002 Rusty Russell <rusty@rustcorp.com.au> IBM Corporation
*
* ChangeLog:
*
* (25/Aug/2004) Paulo Marques <pmarques@grupopie.com>
* Changed the compression method from stem compression to "table lookup"
* compression (see scripts/kallsyms.c for a more complete description)
*
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
* This driver is based on Google Debug Kinfo Driver
*/
#define pr_fmt(fmt) "DebugSymbol: " fmt
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/string.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_reserved_mem.h>
#include <linux/kallsyms.h>
#include "debug_symbol.h"
#include "../../android/debug_kinfo.h"
struct debug_symbol_data {
const unsigned long *addresses;
const int *offsets;
const u8 *names;
unsigned int num_syms;
unsigned long relative_base;
const char *token_table;
const u16 *token_index;
const unsigned int *markers;
};
static struct debug_symbol_data debug_symbol;
static void *debug_symbol_vaddr;
int debug_symbol_available(void)
{
struct kernel_all_info *kainfo;
struct kernel_info *kinfo;
if (!debug_symbol_vaddr)
return -EINVAL;
kainfo = (struct kernel_all_info *)debug_symbol_vaddr;
kinfo = &(kainfo->info);
if (kainfo->magic_number != DEBUG_KINFO_MAGIC) {
pr_debug("debug_symbol is not available now\n");
return -EPROBE_DEFER;
}
if (!debug_symbol.addresses) {
debug_symbol.addresses = (unsigned long *)
__phys_to_kimg(kinfo->_addresses_pa);
debug_symbol.offsets = (int *)
__phys_to_kimg(kinfo->_offsets_pa);
debug_symbol.names = (u8 *)
__phys_to_kimg(kinfo->_names_pa);
debug_symbol.num_syms = kinfo->num_syms;
debug_symbol.relative_base =
__phys_to_kimg(kinfo->_relative_pa);
debug_symbol.token_table = (char *)
__phys_to_kimg(kinfo->_token_table_pa);
debug_symbol.token_index = (u16 *)
__phys_to_kimg(kinfo->_token_index_pa);
debug_symbol.markers = (unsigned int *)
__phys_to_kimg(kinfo->_markers_pa);
}
return 0;
}
EXPORT_SYMBOL(debug_symbol_available);
/* In line with kallsyms_expand_symbol from kernel/kallsyms.c */
static unsigned int debug_symbol_expand_symbol(unsigned int off,
char *result, size_t maxlen)
{
int len, skipped_first = 0;
const char *tptr;
const u8 *data;
data = &debug_symbol.names[off];
len = *data;
data++;
off += len + 1;
while (len) {
tptr = &debug_symbol.token_table[debug_symbol.token_index[*data]];
data++;
len--;
while (*tptr) {
if (skipped_first) {
if (maxlen <= 1)
goto tail;
*result = *tptr;
result++;
maxlen--;
} else
skipped_first = 1;
tptr++;
}
}
tail:
if (maxlen)
*result = '\0';
return off;
}
/* In line with kallsyms_sym_address from kernel/kallsyms.c */
static unsigned long debug_symbol_sym_address(int idx)
{
if (!IS_ENABLED(CONFIG_KALLSYMS_BASE_RELATIVE))
return debug_symbol.addresses[idx];
if (!IS_ENABLED(CONFIG_KALLSYMS_ABSOLUTE_PERCPU))
return debug_symbol.relative_base + (u32)debug_symbol.offsets[idx];
if (debug_symbol.offsets[idx] >= 0)
return debug_symbol.offsets[idx];
return debug_symbol.relative_base - 1 - debug_symbol.offsets[idx];
}
/* In line with cleanup_symbol_name from kernel/kallsyms.c */
static bool cleanup_symbol_name(char *s)
{
char *res;
if (!IS_ENABLED(CONFIG_LTO_CLANG))
return false;
res = strnchr(s, KSYM_NAME_LEN, '.');
if (res) {
*res = '\0';
return true;
}
if (!IS_ENABLED(CONFIG_CFI_CLANG) ||
!IS_ENABLED(CONFIG_LTO_CLANG_THIN) ||
CONFIG_CLANG_VERSION >= 130000)
return false;
res = strrchr(s, '$');
if (res) {
*res = '\0';
return true;
}
return false;
}
/* In line with kallsyms_lookup_name from kernel/kallsyms.c */
unsigned long debug_symbol_lookup_name(const char *name)
{
char namebuf[KSYM_NAME_LEN];
unsigned long i;
unsigned int off;
if (!*name)
return 0;
for (i = 0, off = 0; i < debug_symbol.num_syms; i++) {
off = debug_symbol_expand_symbol(off, namebuf, ARRAY_SIZE(namebuf));
if (strcmp(namebuf, name) == 0)
return debug_symbol_sym_address(i);
if (cleanup_symbol_name(namebuf) && strcmp(namebuf, name) == 0)
return debug_symbol_sym_address(i);
}
return 0;
}
EXPORT_SYMBOL(debug_symbol_lookup_name);
static int __init debug_symbol_init(void)
{
struct device_node *rmem_node;
struct reserved_mem *rmem;
rmem_node = of_find_compatible_node(NULL, NULL, "google,debug-kinfo");
if (!rmem_node) {
pr_err("cannot get compatible node\n");
goto out;
}
rmem_node = of_parse_phandle(rmem_node, "memory-region", 0);
if (!rmem_node) {
pr_err("cannot get memory region\n");
goto out;
}
rmem = of_reserved_mem_lookup(rmem_node);
if (!rmem) {
pr_err("cannot get reserved memory\n");
goto out;
}
debug_symbol_vaddr = memremap(rmem->base, rmem->size, MEMREMAP_WB);
if (!debug_symbol_vaddr) {
pr_err("failed to map reserved memory\n");
goto out;
}
memset(debug_symbol_vaddr, 0, sizeof(struct kernel_all_info));
rmem->priv = debug_symbol_vaddr;
out:
return 0;
}
arch_initcall(debug_symbol_init);
MODULE_DESCRIPTION("QCOM Debug Symbol driver");
MODULE_LICENSE("GPL");

View File

@ -0,0 +1,27 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*
*/
#ifndef _DEBUG_SYMBOL_H
#define _DEBUG_SYMBOL_H
#include <linux/types.h>
#if IS_ENABLED(CONFIG_QCOM_DEBUG_SYMBOL)
extern int debug_symbol_available(void);
extern unsigned long debug_symbol_lookup_name(const char *name);
#else
static inline int debug_symbol_available(void)
{
return -EINVAL;
}
static inline unsigned long debug_symbol_lookup_name(const char *name)
{
return 0;
}
#endif /* CONFIG_QCOM_DEBUG_SYMBOL */
#endif

View File

@ -28,7 +28,7 @@
#include <linux/suspend.h>
#include <linux/vmalloc.h>
#include <linux/panic_notifier.h>
#include <linux/android_debug_symbols.h>
#include "debug_symbol.h"
#ifdef CONFIG_QCOM_MINIDUMP_PSTORE
#include <linux/math64.h>
#include <linux/of.h>
@ -195,10 +195,10 @@ static void register_kernel_sections(void)
void *_sdata, *__bss_stop;
void *start_ro, *end_ro;
_sdata = android_debug_symbol(ADS_SDATA);
__bss_stop = android_debug_symbol(ADS_BSS_END);
base = android_debug_symbol(ADS_PER_CPU_START);
static_size = (size_t)(android_debug_symbol(ADS_PER_CPU_END) - base);
_sdata = (void *)debug_symbol_lookup_name("_sdata");
__bss_stop = (void *)debug_symbol_lookup_name("__bss_stop");
base = (void *)debug_symbol_lookup_name("__per_cpu_start");
static_size = (size_t)((void *)debug_symbol_lookup_name("__per_cpu_end") - base);
strscpy(ksec_entry.name, data_name, sizeof(ksec_entry.name));
ksec_entry.virt_addr = (u64)_sdata;
@ -207,8 +207,8 @@ static void register_kernel_sections(void)
if (msm_minidump_add_region(&ksec_entry) < 0)
pr_err("Failed to add data section in Minidump\n");
start_ro = android_debug_symbol(ADS_START_RO_AFTER_INIT);
end_ro = android_debug_symbol(ADS_END_RO_AFTER_INIT);
start_ro = (void *)debug_symbol_lookup_name("__start_ro_after_init");
end_ro = (void *)debug_symbol_lookup_name("__end_ro_after_init");
strscpy(ksec_entry.name, rodata_name, sizeof(ksec_entry.name));
ksec_entry.virt_addr = (uintptr_t)start_ro;
ksec_entry.phys_addr = virt_to_phys(start_ro);
@ -567,7 +567,7 @@ static void register_irq_stack(void)
u64 irq_stack_base;
struct md_region irq_sp_entry;
u64 sp;
u64 *irq_stack_ptr = android_debug_per_cpu_symbol(ADS_IRQ_STACK_PTR);
u64 *irq_stack_ptr = (void *)debug_symbol_lookup_name("irq_stack_ptr");
for_each_possible_cpu(cpu) {
irq_stack_base = *(u64 *)(per_cpu_ptr((void *)irq_stack_ptr, cpu));

View File

@ -17,10 +17,10 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/android_debug_symbols.h>
#include <linux/gunyah/gh_rm_drv.h>
#include <linux/soc/qcom/smem.h>
#include <soc/qcom/minidump.h>
#include "debug_symbol.h"
#include "minidump_private.h"
#include "elf.h"
@ -833,7 +833,7 @@ static int msm_minidump_add_header(void)
char *banner, *linux_banner;
int slot_num;
linux_banner = android_debug_symbol(ADS_LINUX_BANNER);
linux_banner = (void *)debug_symbol_lookup_name("linux_banner");
/* Header buffer contains:
* elf header, MAX_NUM_ENTRIES+4 of section and program elf headers,
* string table section and linux banner.
@ -963,6 +963,9 @@ static int msm_minidump_driver_probe(struct platform_device *pdev)
unsigned long flags;
int ret;
if (debug_symbol_available())
return -EPROBE_DEFER;
is_rm_minidump =
of_device_is_compatible(pdev->dev.of_node, "qcom,minidump-rm");

View File

@ -20,6 +20,8 @@ clk-qcom.ko
clk-dummy.ko
clk-rpmh.ko
dcc_v2.ko
debug_symbol.ko
minidump.ko
memory_dump_v2.ko
dispcc-pineapple.ko
tcsrcc-pineapple.ko