diff options
author | Robin Getz <rgetz@blackfin.uclinux.org> | 2008-04-25 03:36:31 +0800 |
---|---|---|
committer | Bryan Wu <cooloney@kernel.org> | 2008-04-25 03:36:31 +0800 |
commit | 7f1c906808a36630990d83d872935c079b76595b (patch) | |
tree | 7e29d44cb56fabea3080654480be06c5969b93cc /arch/blackfin/kernel | |
parent | 4d555630704d3f6c0257dde3e622f9295f221c8b (diff) |
[Blackfin] arch: try to remove condition that causes double fault, by checking current before it gets dereferenced
Signed-off-by: Robin Getz <rgetz@blackfin.uclinux.org>
Signed-off-by: Bryan Wu <cooloney@kernel.org>
Diffstat (limited to 'arch/blackfin/kernel')
-rw-r--r-- | arch/blackfin/kernel/traps.c | 34 |
1 files changed, 24 insertions, 10 deletions
diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c index de249d6fdd9..d0f67542207 100644 --- a/arch/blackfin/kernel/traps.c +++ b/arch/blackfin/kernel/traps.c @@ -137,17 +137,30 @@ static void decode_address(char *buf, unsigned long address) /* FLAT does not have its text aligned to the start of * the map while FDPIC ELF does ... */ - if (current->mm && - (address > current->mm->start_code) && - (address < current->mm->end_code)) - offset = address - current->mm->start_code; - else - offset = (address - vma->vm_start) + (vma->vm_pgoff << PAGE_SHIFT); - - sprintf(buf, "<0x%p> [ %s + 0x%lx ]", - (void *)address, name, offset); + + /* before we can check flat/fdpic, we need to + * make sure current is valid + */ + if ((unsigned long)current >= FIXED_CODE_START && + !((unsigned long)current & 0x3)) { + if (current->mm && + (address > current->mm->start_code) && + (address < current->mm->end_code)) + offset = address - current->mm->start_code; + else + offset = (address - vma->vm_start) + + (vma->vm_pgoff << PAGE_SHIFT); + + sprintf(buf, "<0x%p> [ %s + 0x%lx ]", + (void *)address, name, offset); + } else + sprintf(buf, "<0x%p> [ %s vma:0x%lx-0x%lx]", + (void *)address, name, + vma->vm_start, vma->vm_end); + if (!in_atomic) mmput(mm); + goto done; } @@ -658,7 +671,8 @@ void dump_bfin_process(struct pt_regs *fp) /* Because we are crashing, and pointers could be bad, we check things * pretty closely before we use them */ - if (!((unsigned long)current & 0x3) && current->pid) { + if ((unsigned long)current >= FIXED_CODE_START && + !((unsigned long)current & 0x3) && current->pid) { printk(KERN_NOTICE "CURRENT PROCESS:\n"); if (current->comm >= (char *)FIXED_CODE_START) printk(KERN_NOTICE "COMM=%s PID=%d\n", |