mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 20:07:46 +09:00
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 <tao.zeng@amlogic.com>
This commit is contained in:
@@ -29,6 +29,7 @@
|
||||
#include <linux/irqreturn.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/highmem.h>
|
||||
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/smp.h>
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <linux/irqreturn.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/highmem.h>
|
||||
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/smp.h>
|
||||
@@ -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();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user