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:
Huibin Hong
2023-11-08 06:25:34 +00:00
parent 15eb463188
commit 0417e5b732
4 changed files with 79 additions and 9 deletions
+56 -8
View File
@@ -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");
+1
View File
@@ -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 */