soc: rockchip: minidump: don't save peripheral space
Signed-off-by: Huibin Hong <huibin.hong@rock-chips.com> Change-Id: I9da05cd44d85866dccd0bbd61962c2ac4534dcfd
This commit is contained in:
@@ -659,20 +659,68 @@ static int md_register_minidump_entry(char *name, u64 virt_addr,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int md_is_kernel_address(u64 addr)
|
||||
struct page *md_vmalloc_to_page(const void *vmalloc_addr)
|
||||
{
|
||||
unsigned long addr = (unsigned long) vmalloc_addr;
|
||||
struct page *page = NULL;
|
||||
pgd_t *pgd = pgd_offset_k(addr);
|
||||
p4d_t *p4d;
|
||||
pud_t *pud;
|
||||
pmd_t *pmd;
|
||||
pte_t *ptep, pte;
|
||||
|
||||
if (pgd_none(*pgd))
|
||||
return NULL;
|
||||
p4d = p4d_offset(pgd, addr);
|
||||
if (p4d_none(*p4d))
|
||||
return NULL;
|
||||
pud = pud_offset(p4d, addr);
|
||||
|
||||
if (pud_none(*pud) || pud_bad(*pud))
|
||||
return NULL;
|
||||
pmd = pmd_offset(pud, addr);
|
||||
if (pmd_none(*pmd) || pmd_bad(*pmd))
|
||||
return NULL;
|
||||
|
||||
ptep = pte_offset_map(pmd, addr);
|
||||
pte = *ptep;
|
||||
if (pte_present(pte))
|
||||
page = pte_page(pte);
|
||||
pte_unmap(ptep);
|
||||
return page;
|
||||
}
|
||||
|
||||
static bool md_is_kernel_address(u64 addr)
|
||||
{
|
||||
u32 data;
|
||||
u64 phys_addr = 0;
|
||||
struct page *page;
|
||||
|
||||
if (addr < PAGE_OFFSET || addr > -4096UL)
|
||||
return 0;
|
||||
if (!is_ttbr1_addr(addr))
|
||||
return false;
|
||||
|
||||
if (addr >= (u64)_text && addr < (u64)_end)
|
||||
return 0;
|
||||
return false;
|
||||
|
||||
if (__is_lm_address(addr)) {
|
||||
phys_addr = virt_to_phys((void *)addr);
|
||||
} else if (is_vmalloc_or_module_addr((const void *)addr)) {
|
||||
page = md_vmalloc_to_page((const void *) addr);
|
||||
if (page)
|
||||
phys_addr = page_to_phys(page);
|
||||
else
|
||||
return false;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!md_is_ddr_address(phys_addr))
|
||||
return false;
|
||||
|
||||
if (aarch64_insn_read((void *)addr, &data))
|
||||
return 0;
|
||||
return false;
|
||||
else
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
static int md_save_page(u64 addr, bool flush)
|
||||
@@ -689,8 +737,8 @@ static int md_save_page(u64 addr, bool flush)
|
||||
|
||||
if (__is_lm_address(virt_addr)) {
|
||||
phys_addr = virt_to_phys((void *)virt_addr);
|
||||
} else if (virt_addr >= VMALLOC_START && virt_addr < VMALLOC_END) {
|
||||
page = vmalloc_to_page((const void *) virt_addr);
|
||||
} else if (is_vmalloc_or_module_addr((const void *)virt_addr)) {
|
||||
page = md_vmalloc_to_page((const void *) virt_addr);
|
||||
phys_addr = page_to_phys(page);
|
||||
} else {
|
||||
return -1;
|
||||
|
||||
@@ -933,7 +933,7 @@ static ssize_t slab_owner_dump_size_read(struct file *file, char __user *ubuf,
|
||||
{
|
||||
char buf[100];
|
||||
|
||||
snprintf(buf, sizeof(buf), "%llu MB\n", md_slabowner_dump_size/SZ_1M);
|
||||
snprintf(buf, sizeof(buf), "%lu MB\n", md_slabowner_dump_size/SZ_1M);
|
||||
return simple_read_from_buffer(ubuf, count, offset, buf, strlen(buf));
|
||||
}
|
||||
|
||||
|
||||
@@ -72,6 +72,8 @@ static bool md_init_done;
|
||||
static void __iomem *md_elf_mem;
|
||||
static resource_size_t md_elf_size;
|
||||
static struct proc_dir_entry *proc_rk_minidump;
|
||||
static bool md_is_ddr_address_default(u64 phys_addr);
|
||||
bool (*md_is_ddr_address)(u64 virt_addr) = md_is_ddr_address_default;
|
||||
|
||||
/* Number of pending entries to be added in ToC regions */
|
||||
static unsigned int pendings;
|
||||
@@ -621,6 +623,22 @@ static const struct proc_ops rk_minidump_proc_ops = {
|
||||
.proc_read = rk_minidump_read_elf,
|
||||
};
|
||||
|
||||
static bool md_is_ddr_address_rk3588(u64 phys_addr)
|
||||
{
|
||||
/* peripheral address space */
|
||||
if (phys_addr >= 0xf0000000 && phys_addr < 0x100000000)
|
||||
return false;
|
||||
/* DDR is up to 32GB */
|
||||
if (phys_addr > 0x800000000)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool md_is_ddr_address_default(u64 phys_addr)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static int rk_minidump_driver_probe(struct platform_device *pdev)
|
||||
{
|
||||
unsigned int i;
|
||||
@@ -689,6 +707,9 @@ static int rk_minidump_driver_probe(struct platform_device *pdev)
|
||||
pr_info("Create /proc/rk_md/minidump fail...\n");
|
||||
}
|
||||
|
||||
if (of_machine_is_compatible("rockchip,rk3588"))
|
||||
md_is_ddr_address = md_is_ddr_address_rk3588;
|
||||
|
||||
/* Check global minidump support initialization */
|
||||
if (!md_global_toc->md_toc_init) {
|
||||
pr_err("System Minidump TOC not initialized\n");
|
||||
|
||||
@@ -71,4 +71,5 @@ static inline int rk_minidump_hardlock_notify(struct notifier_block *nb,
|
||||
#endif
|
||||
|
||||
void rk_md_flush_dcache_area(void *addr, size_t len);
|
||||
extern bool (*md_is_ddr_address)(u64 virt_addr);
|
||||
#endif /* __RK_MINIDUMP_H */
|
||||
|
||||
Reference in New Issue
Block a user