Commit ec146bb1 authored by Richard Henderson's avatar Richard Henderson

[ALPHA] Update for generic exception table cleanup.

parent 487cffcd
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include <linux/tty.h> #include <linux/tty.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include <linux/module.h>
#include <asm/gentrap.h> #include <asm/gentrap.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
...@@ -465,7 +466,7 @@ do_entUna(void * va, unsigned long opcode, unsigned long reg, ...@@ -465,7 +466,7 @@ do_entUna(void * va, unsigned long opcode, unsigned long reg,
{ {
long error, tmp1, tmp2, tmp3, tmp4; long error, tmp1, tmp2, tmp3, tmp4;
unsigned long pc = regs.pc - 4; unsigned long pc = regs.pc - 4;
unsigned fixup; const struct exception_table_entry *fixup;
unaligned[0].count++; unaligned[0].count++;
unaligned[0].va = (unsigned long) va; unaligned[0].va = (unsigned long) va;
...@@ -638,7 +639,7 @@ do_entUna(void * va, unsigned long opcode, unsigned long reg, ...@@ -638,7 +639,7 @@ do_entUna(void * va, unsigned long opcode, unsigned long reg,
got_exception: got_exception:
/* Ok, we caught the exception, but we don't want it. Is there /* Ok, we caught the exception, but we don't want it. Is there
someone to pass it along to? */ someone to pass it along to? */
if ((fixup = search_exception_table(pc)) != 0) { if ((fixup = search_exception_tables(pc)) != 0) {
unsigned long newpc; unsigned long newpc;
newpc = fixup_exception(una_reg, fixup, pc); newpc = fixup_exception(una_reg, fixup, pc);
......
...@@ -6,13 +6,10 @@ ...@@ -6,13 +6,10 @@
#include <linux/module.h> #include <linux/module.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
extern const struct exception_table_entry __start___ex_table[]; const struct exception_table_entry *
extern const struct exception_table_entry __stop___ex_table[]; search_extable(const struct exception_table_entry *first,
const struct exception_table_entry *last,
static inline unsigned unsigned long value)
search_one_table(const struct exception_table_entry *first,
const struct exception_table_entry *last,
unsigned long value)
{ {
while (first <= last) { while (first <= last) {
const struct exception_table_entry *mid; const struct exception_table_entry *mid;
...@@ -21,40 +18,12 @@ search_one_table(const struct exception_table_entry *first, ...@@ -21,40 +18,12 @@ search_one_table(const struct exception_table_entry *first,
mid = (last - first) / 2 + first; mid = (last - first) / 2 + first;
mid_value = (unsigned long)&mid->insn + mid->insn; mid_value = (unsigned long)&mid->insn + mid->insn;
if (mid_value == value) if (mid_value == value)
return mid->fixup.unit; return mid;
else if (mid_value < value) else if (mid_value < value)
first = mid+1; first = mid+1;
else else
last = mid-1; last = mid-1;
} }
return 0;
}
unsigned
search_exception_table(unsigned long addr)
{
unsigned ret;
#ifndef CONFIG_MODULES
ret = search_one_table(__start___ex_table, __stop___ex_table-1, addr);
#else
unsigned long flags;
struct list_head *i;
ret = 0;
spin_lock_irqsave(&modlist_lock, flags);
list_for_each(i, &extables) {
struct exception_table *ex
= list_entry(i, struct exception_table, list);
if (ex->num_entries == 0)
continue;
ret = search_one_table(ex->entry,
ex->entry + ex->num_entries - 1, addr);
if (ret)
break;
}
spin_unlock_irqrestore(&modlist_lock, flags);
#endif
return ret; return NULL;
} }
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <linux/smp.h> #include <linux/smp.h>
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/module.h>
#include <asm/system.h> #include <asm/system.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
...@@ -88,7 +89,7 @@ do_page_fault(unsigned long address, unsigned long mmcsr, ...@@ -88,7 +89,7 @@ do_page_fault(unsigned long address, unsigned long mmcsr,
{ {
struct vm_area_struct * vma; struct vm_area_struct * vma;
struct mm_struct *mm = current->mm; struct mm_struct *mm = current->mm;
unsigned int fixup; const struct exception_table_entry *fixup;
int fault, si_code = SEGV_MAPERR; int fault, si_code = SEGV_MAPERR;
siginfo_t info; siginfo_t info;
...@@ -176,7 +177,7 @@ do_page_fault(unsigned long address, unsigned long mmcsr, ...@@ -176,7 +177,7 @@ do_page_fault(unsigned long address, unsigned long mmcsr,
no_context: no_context:
/* Are we prepared to handle this fault as an exception? */ /* Are we prepared to handle this fault as an exception? */
if ((fixup = search_exception_table(regs->pc)) != 0) { if ((fixup = search_exception_tables(regs->pc)) != 0) {
unsigned long newpc; unsigned long newpc;
newpc = fixup_exception(dpf_reg, fixup, regs->pc); newpc = fixup_exception(dpf_reg, fixup, regs->pc);
regs->pc = newpc; regs->pc = newpc;
......
...@@ -501,19 +501,14 @@ struct exception_table_entry ...@@ -501,19 +501,14 @@ struct exception_table_entry
} fixup; } fixup;
}; };
/* Returns 0 if exception not found and fixup.unit otherwise. */
extern unsigned search_exception_table(unsigned long);
/* Returns the new pc */ /* Returns the new pc */
#define fixup_exception(map_reg, fixup_unit, pc) \ #define fixup_exception(map_reg, fixup, pc) \
({ \ ({ \
union exception_fixup __fie_fixup; \ if ((fixup)->fixup.bits.valreg != 31) \
__fie_fixup.unit = fixup_unit; \ map_reg((fixup)->fixup.bits.valreg) = 0; \
if (__fie_fixup.bits.valreg != 31) \ if ((fixup)->fixup.bits.errreg != 31) \
map_reg(__fie_fixup.bits.valreg) = 0; \ map_reg((fixup)->fixup.bits.errreg) = -EFAULT; \
if (__fie_fixup.bits.errreg != 31) \ (pc) + (fixup)->fixup.bits.nextinsn; \
map_reg(__fie_fixup.bits.errreg) = -EFAULT; \
(pc) + __fie_fixup.bits.nextinsn; \
}) })
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment