Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e4c33baa authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "Minidump: Add update region support for minidump regions"

parents 7a6e9213 1e461678
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1776,7 +1776,7 @@ static int lpm_probe(struct platform_device *pdev)
	md_entry.virt_addr = (uintptr_t)lpm_debug;
	md_entry.phys_addr = lpm_debug_phys;
	md_entry.size = size;
	if (msm_minidump_add_region(&md_entry))
	if (msm_minidump_add_region(&md_entry) < 0)
		pr_info("Failed to add lpm_debug in Minidump\n");

	return 0;
+1 −1
Original line number Diff line number Diff line
@@ -140,7 +140,7 @@ int msm_dump_data_register(enum msm_dump_table_ids id,

	dmac_flush_range(table, (void *)table + sizeof(struct msm_dump_table));

	if (msm_dump_data_add_minidump(entry))
	if (msm_dump_data_add_minidump(entry) < 0)
		pr_err("Failed to add entry in Minidump table\n");

	return 0;
+6 −6
Original line number Diff line number Diff line
/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -37,7 +37,7 @@ static void __init register_log_buf(void)
	md_entry.virt_addr = (uintptr_t) (*log_bufp);
	md_entry.phys_addr = virt_to_phys(*log_bufp);
	md_entry.size = *log_buf_lenp;
	if (msm_minidump_add_region(&md_entry))
	if (msm_minidump_add_region(&md_entry) < 0)
		pr_err("Failed to add logbuf in Minidump\n");
}

@@ -53,7 +53,7 @@ static void __init register_kernel_sections(void)
	ksec_entry.virt_addr = (uintptr_t)_sdata;
	ksec_entry.phys_addr = virt_to_phys(_sdata);
	ksec_entry.size = roundup((__bss_stop - _sdata), 4);
	if (msm_minidump_add_region(&ksec_entry))
	if (msm_minidump_add_region(&ksec_entry) < 0)
		pr_err("Failed to add data section in Minidump\n");

	/* Add percpu static sections */
@@ -66,7 +66,7 @@ static void __init register_kernel_sections(void)
		ksec_entry.virt_addr = (uintptr_t)start;
		ksec_entry.phys_addr = per_cpu_ptr_to_phys(start);
		ksec_entry.size = static_size;
		if (msm_minidump_add_region(&ksec_entry))
		if (msm_minidump_add_region(&ksec_entry) < 0)
			pr_err("Failed to add percpu sections in Minidump\n");
	}
}
@@ -87,14 +87,14 @@ void dump_stack_minidump(u64 sp)
	ksp_entry.virt_addr = sp;
	ksp_entry.phys_addr = virt_to_phys((uintptr_t *)sp);
	ksp_entry.size = THREAD_SIZE;
	if (msm_minidump_add_region(&ksp_entry))
	if (msm_minidump_add_region(&ksp_entry) < 0)
		pr_err("Failed to add stack of cpu %d in Minidump\n", cpu);

	scnprintf(ktsk_entry.name, sizeof(ktsk_entry.name), "KTASK%d", cpu);
	ktsk_entry.virt_addr = (u64)current;
	ktsk_entry.phys_addr = virt_to_phys((uintptr_t *)current);
	ktsk_entry.size = sizeof(struct task_struct);
	if (msm_minidump_add_region(&ktsk_entry))
	if (msm_minidump_add_region(&ktsk_entry) < 0)
		pr_err("Failed to add current task %d in Minidump\n", cpu);
}

+55 −13
Original line number Diff line number Diff line
/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -169,17 +169,10 @@ bool msm_minidump_enabled(void)
}
EXPORT_SYMBOL(msm_minidump_enabled);

int msm_minidump_add_region(const struct md_region *entry)
static inline int validate_region(const struct md_region *entry)
{
	u32 entries;
	struct md_region *mdr;
	int ret = 0;

	if (!entry)
		return -EINVAL;

	if ((strlen(entry->name) > MAX_NAME_LENGTH) ||
		md_check_name(entry->name) || !entry->virt_addr) {
	if (!entry || (strlen(entry->name) > MAX_NAME_LENGTH) ||
		!entry->virt_addr) {
		pr_err("Invalid entry details\n");
		return -EINVAL;
	}
@@ -188,6 +181,55 @@ int msm_minidump_add_region(const struct md_region *entry)
		pr_err("size should be 4 byte aligned\n");
		return -EINVAL;
	}
	return 0;
}

int msm_minidump_update_region(int regno, const struct md_region *entry)
{
	struct md_region *mdr;
	struct md_ss_region *mdssr;
	struct elfhdr *hdr = minidump_elfheader.ehdr;
	struct elf_shdr *shdr;
	struct elf_phdr *phdr;

	if (validate_region(entry) || (regno >= MAX_NUM_ENTRIES))
		return -EINVAL;

	if (!md_check_name(entry->name)) {
		pr_err("Region:[%s] does not exist to update.\n", entry->name);
		return -ENOMEM;
	}

	mdr = &minidump_table.entry[regno];
	mdr->virt_addr = entry->virt_addr;
	mdr->phys_addr = entry->phys_addr;

	mdssr = &minidump_table.md_regions[regno + 1];
	mdssr->region_base_address = entry->phys_addr;

	shdr = elf_section(hdr, regno + 4);
	phdr = elf_program(hdr, regno + 1);

	shdr->sh_addr = (elf_addr_t)entry->virt_addr;
	phdr->p_vaddr = entry->virt_addr;
	phdr->p_paddr = entry->phys_addr;

	return 0;
}
EXPORT_SYMBOL(msm_minidump_update_region);

int msm_minidump_add_region(const struct md_region *entry)
{
	u32 entries;
	struct md_region *mdr;

	if (validate_region(entry))
		return -EINVAL;

	if (md_check_name(entry->name)) {
		pr_err("Region name [%s] already registered\n", entry->name);
		return -EEXIST;
	}

	spin_lock(&mdt_lock);
	entries = minidump_table.num_regions;
@@ -215,7 +257,7 @@ int msm_minidump_add_region(const struct md_region *entry)

	spin_unlock(&mdt_lock);

	return ret;
	return entries;
}
EXPORT_SYMBOL(msm_minidump_add_region);

+1 −1
Original line number Diff line number Diff line
@@ -885,7 +885,7 @@ static int msm_watchdog_probe(struct platform_device *pdev)
	md_entry.virt_addr = (uintptr_t)wdog_dd;
	md_entry.phys_addr = virt_to_phys(wdog_dd);
	md_entry.size = sizeof(*wdog_dd);
	if (msm_minidump_add_region(&md_entry))
	if (msm_minidump_add_region(&md_entry) < 0)
		pr_info("Failed to add Watchdog data in Minidump\n");

	return 0;
Loading