Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 128013
b: refs/heads/master
c: c61c25e
h: refs/heads/master
i:
  128011: b029d3c
v: v3
  • Loading branch information
Kyle McMartin committed Jan 5, 2009
1 parent 9bccf8c commit 0f27911
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 28 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: aefa8b6bf48fdcc904de4f166e59ab37fb750dec
refs/heads/master: c61c25eb02757ecf697015ef4ae3675c5e114e2e
2 changes: 2 additions & 0 deletions trunk/arch/parisc/include/asm/uaccess.h
Original file line number Diff line number Diff line change
Expand Up @@ -241,4 +241,6 @@ unsigned long copy_in_user(void __user *dst, const void __user *src, unsigned lo
#define __copy_to_user_inatomic __copy_to_user
#define __copy_from_user_inatomic __copy_from_user

int fixup_exception(struct pt_regs *regs);

#endif /* __PARISC_UACCESS_H */
4 changes: 4 additions & 0 deletions trunk/arch/parisc/kernel/traps.c
Original file line number Diff line number Diff line change
Expand Up @@ -745,6 +745,10 @@ void handle_interruption(int code, struct pt_regs *regs)
/* Fall Through */
case 27:
/* Data memory protection ID trap */
if (code == 27 && !user_mode(regs) &&
fixup_exception(regs))
return;

die_if_kernel("Protection id trap", regs, code);
si.si_code = SEGV_MAPERR;
si.si_signo = SIGSEGV;
Expand Down
58 changes: 31 additions & 27 deletions trunk/arch/parisc/mm/fault.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,13 +139,41 @@ parisc_acctyp(unsigned long code, unsigned int inst)
}
#endif

int fixup_exception(struct pt_regs *regs)
{
const struct exception_table_entry *fix;

fix = search_exception_tables(regs->iaoq[0]);
if (fix) {
struct exception_data *d;
d = &__get_cpu_var(exception_data);
d->fault_ip = regs->iaoq[0];
d->fault_space = regs->isr;
d->fault_addr = regs->ior;

regs->iaoq[0] = ((fix->fixup) & ~3);
/*
* NOTE: In some cases the faulting instruction
* may be in the delay slot of a branch. We
* don't want to take the branch, so we don't
* increment iaoq[1], instead we set it to be
* iaoq[0]+4, and clear the B bit in the PSW
*/
regs->iaoq[1] = regs->iaoq[0] + 4;
regs->gr[0] &= ~PSW_B; /* IPSW in gr[0] */

return 1;
}

return 0;
}

void do_page_fault(struct pt_regs *regs, unsigned long code,
unsigned long address)
{
struct vm_area_struct *vma, *prev_vma;
struct task_struct *tsk = current;
struct mm_struct *mm = tsk->mm;
const struct exception_table_entry *fix;
unsigned long acc_type;
int fault;

Expand Down Expand Up @@ -229,32 +257,8 @@ void do_page_fault(struct pt_regs *regs, unsigned long code,

no_context:

if (!user_mode(regs)) {
fix = search_exception_tables(regs->iaoq[0]);

if (fix) {
struct exception_data *d;

d = &__get_cpu_var(exception_data);
d->fault_ip = regs->iaoq[0];
d->fault_space = regs->isr;
d->fault_addr = regs->ior;

regs->iaoq[0] = ((fix->fixup) & ~3);

/*
* NOTE: In some cases the faulting instruction
* may be in the delay slot of a branch. We
* don't want to take the branch, so we don't
* increment iaoq[1], instead we set it to be
* iaoq[0]+4, and clear the B bit in the PSW
*/

regs->iaoq[1] = regs->iaoq[0] + 4;
regs->gr[0] &= ~PSW_B; /* IPSW in gr[0] */

return;
}
if (!user_mode(regs) && fixup_exception(regs)) {
return;
}

parisc_terminate("Bad Address (null pointer deref?)", regs, code, address);
Expand Down

0 comments on commit 0f27911

Please sign in to comment.