Merge "debug: add more strict checking for show_regs [2/2]" into amlogic-4.9-dev

This commit is contained in:
Jianxin Pan
2019-06-17 23:14:04 -07:00
committed by Gerrit Code Review
7 changed files with 89 additions and 7 deletions

View File

@@ -47,6 +47,10 @@ unsigned long __stack_chk_guard __read_mostly;
EXPORT_SYMBOL(__stack_chk_guard);
#endif
#ifdef CONFIG_AMLOGIC_MODIFY
#include <linux/amlogic/secmon.h>
#endif
static const char *processor_modes[] __maybe_unused = {
"USER_26", "FIQ_26" , "IRQ_26" , "SVC_26" , "UK4_26" , "UK5_26" , "UK6_26" , "UK7_26" ,
"UK8_26" , "UK9_26" , "UK10_26", "UK11_26", "UK12_26", "UK13_26", "UK14_26", "UK15_26",
@@ -119,6 +123,34 @@ static void show_data(unsigned long addr, int nbytes, const char *name)
if (addr < PAGE_OFFSET || addr > -256UL)
return;
#ifdef CONFIG_AMLOGIC_MODIFY
/*
* Treating data in general purpose register as an address
* and dereferencing it is quite a dangerous behaviour,
* especially when it is an address belonging to secure
* region or ioremap region, which can lead to external
* abort on non-linefetch and can not be protected by
* probe_kernel_address.
* We need more strict filtering rules
*/
#ifdef CONFIG_AMLOGIC_SEC
/*
* filter out secure monitor region
*/
if (addr <= (unsigned long)high_memory)
if (within_secmon_region(addr))
return;
#endif
/*
* filter out ioremap region
*/
if ((addr >= VMALLOC_START) && (addr <= VMALLOC_END))
if (!pfn_valid(vmalloc_to_pfn((void *)addr)))
return;
#endif
printk("\n%s: %#lx:\n", name, addr);
/*

View File

@@ -62,6 +62,10 @@ unsigned long __stack_chk_guard __read_mostly;
EXPORT_SYMBOL(__stack_chk_guard);
#endif
#ifdef CONFIG_AMLOGIC_MODIFY
#include <linux/amlogic/secmon.h>
#endif
/*
* Function pointers to optional machine specific functions
*/
@@ -195,6 +199,27 @@ static void show_data(unsigned long addr, int nbytes, const char *name)
if (addr < PAGE_OFFSET || addr > -256UL)
return;
#ifdef CONFIG_AMLOGIC_MODIFY
/*
* Treating data in general purpose register as an address
* and dereferencing it is quite a dangerous behaviour,
* especially when it belongs to secure monotor region or
* ioremap region(for arm64 vmalloc region is already filtered
* out), which can lead to external abort on non-linefetch and
* can not be protected by probe_kernel_address.
* We need more strict filtering rules
*/
#ifdef CONFIG_AMLOGIC_SEC
/*
* filter out secure monitor region
*/
if (addr <= (unsigned long)high_memory)
if (within_secmon_region(addr))
return;
#endif
#endif
printk("\n%s: %#lx:\n", name, addr);
/*

View File

@@ -35,6 +35,8 @@ static void __iomem *sharemem_in_base;
static void __iomem *sharemem_out_base;
static long phy_in_base;
static long phy_out_base;
static unsigned long secmon_start_virt;
#ifdef CONFIG_ARM64
#define IN_SIZE 0x1000
#else
@@ -55,6 +57,19 @@ static long get_sharemem_info(unsigned int function_id)
}
#define RESERVE_MEM_SIZE 0x300000
int within_secmon_region(unsigned long addr)
{
if (!secmon_start_virt)
return 0;
if ((addr >= secmon_start_virt) &&
(addr <= (secmon_start_virt + RESERVE_MEM_SIZE)))
return 1;
return 0;
}
static int secmon_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
@@ -87,6 +102,7 @@ static int secmon_probe(struct platform_device *pdev)
return -ENOMEM;
}
pr_info("get page:%p, %lx\n", page, page_to_pfn(page));
secmon_start_virt = (unsigned long)page_to_virt(page);
if (pfn_valid(__phys_to_pfn(phy_in_base)))
sharemem_in_base = (void __iomem *)__phys_to_virt(phy_in_base);

View File

@@ -257,13 +257,6 @@ static DECLARE_WORK(sysrq_showallcpus, sysrq_showregs_othercpus);
static void sysrq_handle_showallcpus(int key)
{
/*
* Temporarily disable this function
* Remove it later
*/
#ifdef CONFIG_AMLOGIC_MODIFY
return;
#endif
/*
* Fall back to the workqueue based printing if the
* backtrace printing did not succeed or the

View File

@@ -27,4 +27,6 @@ void sharemem_mutex_lock(void);
void sharemem_mutex_unlock(void);
void secmon_clear_cma_mmu(void);
int within_secmon_region(unsigned long addr);
#endif

View File

@@ -93,9 +93,19 @@ bool nmi_cpu_backtrace(struct pt_regs *regs)
cpu, instruction_pointer(regs));
} else {
pr_warn("NMI backtrace for cpu %d\n", cpu);
/*
* two reasons for not calling show_regs here
* 1. two many logs(100 lines per second) are
* introduced, which makes the wanted stack
* infos missed
* 2. leads to potential external abort on
* non-linefetch issue
*/
#ifndef CONFIG_AMLOGIC_MODIFY
if (regs)
show_regs(regs);
else
#endif
dump_stack();
}
cpumask_clear_cpu(cpu, to_cpumask(backtrace_mask));

View File

@@ -254,10 +254,14 @@ struct page *vmalloc_to_page(const void *vmalloc_addr)
*/
if (!pgd_none(*pgd)) {
pud_t *pud = pud_offset(pgd, addr);
#ifndef CONFIG_AMLOGIC_MODIFY
WARN_ON_ONCE(pud_bad(*pud));
#endif
if (!pud_none(*pud) && !pud_bad(*pud)) {
pmd_t *pmd = pmd_offset(pud, addr);
#ifndef CONFIG_AMLOGIC_MODIFY
WARN_ON_ONCE(pmd_bad(*pmd));
#endif
if (!pmd_none(*pmd) && !pmd_bad(*pmd)) {
pte_t *ptep, pte;