Commit ec146bb1 authored by Richard Henderson's avatar Richard Henderson

[ALPHA] Update for generic exception table cleanup.

parent 487cffcd
......@@ -14,6 +14,7 @@
#include <linux/tty.h>
#include <linux/delay.h>
#include <linux/smp_lock.h>
#include <linux/module.h>
#include <asm/gentrap.h>
#include <asm/uaccess.h>
......@@ -465,7 +466,7 @@ do_entUna(void * va, unsigned long opcode, unsigned long reg,
{
long error, tmp1, tmp2, tmp3, tmp4;
unsigned long pc = regs.pc - 4;
unsigned fixup;
const struct exception_table_entry *fixup;
unaligned[0].count++;
unaligned[0].va = (unsigned long) va;
......@@ -638,7 +639,7 @@ do_entUna(void * va, unsigned long opcode, unsigned long reg,
got_exception:
/* Ok, we caught the exception, but we don't want it. Is there
someone to pass it along to? */
if ((fixup = search_exception_table(pc)) != 0) {
if ((fixup = search_exception_tables(pc)) != 0) {
unsigned long newpc;
newpc = fixup_exception(una_reg, fixup, pc);
......
......@@ -6,11 +6,8 @@
#include <linux/module.h>
#include <asm/uaccess.h>
extern const struct exception_table_entry __start___ex_table[];
extern const struct exception_table_entry __stop___ex_table[];
static inline unsigned
search_one_table(const struct exception_table_entry *first,
const struct exception_table_entry *
search_extable(const struct exception_table_entry *first,
const struct exception_table_entry *last,
unsigned long value)
{
......@@ -21,40 +18,12 @@ search_one_table(const struct exception_table_entry *first,
mid = (last - first) / 2 + first;
mid_value = (unsigned long)&mid->insn + mid->insn;
if (mid_value == value)
return mid->fixup.unit;
return mid;
else if (mid_value < value)
first = mid+1;
else
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 @@
#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <asm/system.h>
#include <asm/uaccess.h>
......@@ -88,7 +89,7 @@ do_page_fault(unsigned long address, unsigned long mmcsr,
{
struct vm_area_struct * vma;
struct mm_struct *mm = current->mm;
unsigned int fixup;
const struct exception_table_entry *fixup;
int fault, si_code = SEGV_MAPERR;
siginfo_t info;
......@@ -176,7 +177,7 @@ do_page_fault(unsigned long address, unsigned long mmcsr,
no_context:
/* 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;
newpc = fixup_exception(dpf_reg, fixup, regs->pc);
regs->pc = newpc;
......
......@@ -501,19 +501,14 @@ struct exception_table_entry
} fixup;
};
/* Returns 0 if exception not found and fixup.unit otherwise. */
extern unsigned search_exception_table(unsigned long);
/* Returns the new pc */
#define fixup_exception(map_reg, fixup_unit, pc) \
#define fixup_exception(map_reg, fixup, pc) \
({ \
union exception_fixup __fie_fixup; \
__fie_fixup.unit = fixup_unit; \
if (__fie_fixup.bits.valreg != 31) \
map_reg(__fie_fixup.bits.valreg) = 0; \
if (__fie_fixup.bits.errreg != 31) \
map_reg(__fie_fixup.bits.errreg) = -EFAULT; \
(pc) + __fie_fixup.bits.nextinsn; \
if ((fixup)->fixup.bits.valreg != 31) \
map_reg((fixup)->fixup.bits.valreg) = 0; \
if ((fixup)->fixup.bits.errreg != 31) \
map_reg((fixup)->fixup.bits.errreg) = -EFAULT; \
(pc) + (fixup)->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