From b08193bfe3cbd027ceb554e919fcff756ec52103 Mon Sep 17 00:00:00 2001 From: Tao Zeng Date: Thu, 27 Dec 2018 14:31:29 +0800 Subject: [PATCH] dmc: fix panic problem when show memory in highmem [1/1] PD#SWPL-2767 Problem: If DMC violation address is in highmem, then it will panic when show memory using page_address(); Solution: map violation address for highmem Verify: p212 Change-Id: Ib6213eaab42b129c8c0a381511a0b3376b0d3e66 Signed-off-by: Tao Zeng --- drivers/amlogic/ddr_tool/dmc_g12.c | 33 +++++++++++++++++++++--------- drivers/amlogic/ddr_tool/dmc_gx.c | 33 +++++++++++++++++++++--------- 2 files changed, 46 insertions(+), 20 deletions(-) diff --git a/drivers/amlogic/ddr_tool/dmc_g12.c b/drivers/amlogic/ddr_tool/dmc_g12.c index 9afc61e34d52..8e35e212697e 100644 --- a/drivers/amlogic/ddr_tool/dmc_g12.c +++ b/drivers/amlogic/ddr_tool/dmc_g12.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -76,12 +77,31 @@ static size_t g12_dmc_dump_reg(char *buf) return sz; } +static void show_violation_mem(unsigned long addr) +{ + struct page *page; + unsigned long *p, *q; + + if (!pfn_valid(__phys_to_pfn(addr))) + return; + + page = phys_to_page(addr); + p = kmap_atomic(page); + if (!p) + return; + + q = p + ((addr & (PAGE_SIZE - 1)) / sizeof(*p)); + pr_info(DMC_TAG "[%08lx]:%016lx, f:%8lx, m:%p, a:%ps\n", + (unsigned long)q, *q, page->flags & 0xffffffff, + page->mapping, + (void *)get_page_trace(page)); + kunmap_atomic(p); +} + static void check_violation(struct dmc_monitor *mon) { int i, port, subport; unsigned long addr, status; - struct page *page; - unsigned long *p; char id_str[4]; char off1 = 21, off2 = 10; @@ -112,14 +132,7 @@ static void check_violation(struct dmc_monitor *mon) pr_info(DMC_TAG", addr:%08lx, s:%08lx, ID:%s, sub:%s, c:%ld\n", addr, status, to_ports(port), to_sub_ports(port, subport, id_str), mon->same_page); - if (pfn_valid(__phys_to_pfn(addr))) { - page = phys_to_page(addr); - p = (page_address(page) + (addr & (PAGE_SIZE - 1))); - pr_info(DMC_TAG" [%08lx]:%016lx, f:%8lx, m:%p, a:%pf\n", - addr, *p, page->flags & 0xffffffff, - page->mapping, - (void *)get_page_trace(page)); - } + show_violation_mem(addr); if (!port) /* dump stack for CPU write */ dump_stack(); diff --git a/drivers/amlogic/ddr_tool/dmc_gx.c b/drivers/amlogic/ddr_tool/dmc_gx.c index e0b1203974c0..7871970cdd6a 100644 --- a/drivers/amlogic/ddr_tool/dmc_gx.c +++ b/drivers/amlogic/ddr_tool/dmc_gx.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -80,12 +81,31 @@ static size_t gx_dmc_dump_reg(char *buf) return sz; } +static void show_violation_mem(unsigned long addr) +{ + struct page *page; + unsigned long *p, *q; + + if (!pfn_valid(__phys_to_pfn(addr))) + return; + + page = phys_to_page(addr); + p = kmap_atomic(page); + if (!p) + return; + + q = p + ((addr & (PAGE_SIZE - 1)) / sizeof(*p)); + pr_info(DMC_TAG "[%08lx]:%016lx, f:%8lx, m:%p, a:%ps\n", + (unsigned long)q, *q, page->flags & 0xffffffff, + page->mapping, + (void *)get_page_trace(page)); + kunmap_atomic(p); +} + static void check_violation(struct dmc_monitor *mon) { int i, port, subport; unsigned long addr, status; - struct page *page; - unsigned long *p; char id_str[4]; for (i = 1; i < 8; i += 2) { @@ -109,14 +129,7 @@ static void check_violation(struct dmc_monitor *mon) pr_info(DMC_TAG", addr:%08lx, s:%08lx, ID:%s, sub:%s, c:%ld\n", addr, status, to_ports(port), to_sub_ports(port, subport, id_str), mon->same_page); - if (pfn_valid(__phys_to_pfn(addr))) { - page = phys_to_page(addr); - p = (page_address(page) + (addr & (PAGE_SIZE - 1))); - pr_info(DMC_TAG" [%08lx]:%016lx, f:%8lx, m:%p, a:%pf\n", - addr, *p, page->flags & 0xffffffff, - page->mapping, - (void *)get_page_trace(page)); - } + show_violation_mem(addr); if (!port) /* dump stack for CPU write */ dump_stack();