diff options
Diffstat (limited to 'arch/sparc64/kernel/traps.c')
-rw-r--r-- | arch/sparc64/kernel/traps.c | 60 |
1 files changed, 20 insertions, 40 deletions
diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c index f8e7005fede9..5570e7bb22bb 100644 --- a/arch/sparc64/kernel/traps.c +++ b/arch/sparc64/kernel/traps.c | |||
@@ -189,19 +189,18 @@ void spitfire_data_access_exception(struct pt_regs *regs, unsigned long sfsr, un | |||
189 | 189 | ||
190 | if (regs->tstate & TSTATE_PRIV) { | 190 | if (regs->tstate & TSTATE_PRIV) { |
191 | /* Test if this comes from uaccess places. */ | 191 | /* Test if this comes from uaccess places. */ |
192 | unsigned long fixup; | 192 | const struct exception_table_entry *entry; |
193 | unsigned long g2 = regs->u_regs[UREG_G2]; | ||
194 | 193 | ||
195 | if ((fixup = search_extables_range(regs->tpc, &g2))) { | 194 | entry = search_exception_tables(regs->tpc); |
196 | /* Ouch, somebody is trying ugly VM hole tricks on us... */ | 195 | if (entry) { |
196 | /* Ouch, somebody is trying VM hole tricks on us... */ | ||
197 | #ifdef DEBUG_EXCEPTIONS | 197 | #ifdef DEBUG_EXCEPTIONS |
198 | printk("Exception: PC<%016lx> faddr<UNKNOWN>\n", regs->tpc); | 198 | printk("Exception: PC<%016lx> faddr<UNKNOWN>\n", regs->tpc); |
199 | printk("EX_TABLE: insn<%016lx> fixup<%016lx> " | 199 | printk("EX_TABLE: insn<%016lx> fixup<%016lx>\n", |
200 | "g2<%016lx>\n", regs->tpc, fixup, g2); | 200 | regs->tpc, entry->fixup); |
201 | #endif | 201 | #endif |
202 | regs->tpc = fixup; | 202 | regs->tpc = entry->fixup; |
203 | regs->tnpc = regs->tpc + 4; | 203 | regs->tnpc = regs->tpc + 4; |
204 | regs->u_regs[UREG_G2] = g2; | ||
205 | return; | 204 | return; |
206 | } | 205 | } |
207 | /* Shit... */ | 206 | /* Shit... */ |
@@ -758,26 +757,12 @@ void __init cheetah_ecache_flush_init(void) | |||
758 | ecache_flush_size = (2 * largest_size); | 757 | ecache_flush_size = (2 * largest_size); |
759 | ecache_flush_linesize = smallest_linesize; | 758 | ecache_flush_linesize = smallest_linesize; |
760 | 759 | ||
761 | /* Discover a physically contiguous chunk of physical | 760 | ecache_flush_physbase = find_ecache_flush_span(ecache_flush_size); |
762 | * memory in 'sp_banks' of size ecache_flush_size calculated | ||
763 | * above. Store the physical base of this area at | ||
764 | * ecache_flush_physbase. | ||
765 | */ | ||
766 | for (node = 0; ; node++) { | ||
767 | if (sp_banks[node].num_bytes == 0) | ||
768 | break; | ||
769 | if (sp_banks[node].num_bytes >= ecache_flush_size) { | ||
770 | ecache_flush_physbase = sp_banks[node].base_addr; | ||
771 | break; | ||
772 | } | ||
773 | } | ||
774 | 761 | ||
775 | /* Note: Zero would be a valid value of ecache_flush_physbase so | 762 | if (ecache_flush_physbase == ~0UL) { |
776 | * don't use that as the success test. :-) | ||
777 | */ | ||
778 | if (sp_banks[node].num_bytes == 0) { | ||
779 | prom_printf("cheetah_ecache_flush_init: Cannot find %d byte " | 763 | prom_printf("cheetah_ecache_flush_init: Cannot find %d byte " |
780 | "contiguous physical memory.\n", ecache_flush_size); | 764 | "contiguous physical memory.\n", |
765 | ecache_flush_size); | ||
781 | prom_halt(); | 766 | prom_halt(); |
782 | } | 767 | } |
783 | 768 | ||
@@ -1346,16 +1331,12 @@ static int cheetah_fix_ce(unsigned long physaddr) | |||
1346 | /* Return non-zero if PADDR is a valid physical memory address. */ | 1331 | /* Return non-zero if PADDR is a valid physical memory address. */ |
1347 | static int cheetah_check_main_memory(unsigned long paddr) | 1332 | static int cheetah_check_main_memory(unsigned long paddr) |
1348 | { | 1333 | { |
1349 | int i; | 1334 | unsigned long vaddr = PAGE_OFFSET + paddr; |
1350 | 1335 | ||
1351 | for (i = 0; ; i++) { | 1336 | if (vaddr > (unsigned long) high_memory) |
1352 | if (sp_banks[i].num_bytes == 0) | 1337 | return 0; |
1353 | break; | 1338 | |
1354 | if (paddr >= sp_banks[i].base_addr && | 1339 | return kern_addr_valid(vaddr); |
1355 | paddr < (sp_banks[i].base_addr + sp_banks[i].num_bytes)) | ||
1356 | return 1; | ||
1357 | } | ||
1358 | return 0; | ||
1359 | } | 1340 | } |
1360 | 1341 | ||
1361 | void cheetah_cee_handler(struct pt_regs *regs, unsigned long afsr, unsigned long afar) | 1342 | void cheetah_cee_handler(struct pt_regs *regs, unsigned long afsr, unsigned long afar) |
@@ -1610,10 +1591,10 @@ void cheetah_deferred_handler(struct pt_regs *regs, unsigned long afsr, unsigned | |||
1610 | /* OK, usermode access. */ | 1591 | /* OK, usermode access. */ |
1611 | recoverable = 1; | 1592 | recoverable = 1; |
1612 | } else { | 1593 | } else { |
1613 | unsigned long g2 = regs->u_regs[UREG_G2]; | 1594 | const struct exception_table_entry *entry; |
1614 | unsigned long fixup = search_extables_range(regs->tpc, &g2); | ||
1615 | 1595 | ||
1616 | if (fixup != 0UL) { | 1596 | entry = search_exception_tables(regs->tpc); |
1597 | if (entry) { | ||
1617 | /* OK, kernel access to userspace. */ | 1598 | /* OK, kernel access to userspace. */ |
1618 | recoverable = 1; | 1599 | recoverable = 1; |
1619 | 1600 | ||
@@ -1632,9 +1613,8 @@ void cheetah_deferred_handler(struct pt_regs *regs, unsigned long afsr, unsigned | |||
1632 | * recoverable condition. | 1613 | * recoverable condition. |
1633 | */ | 1614 | */ |
1634 | if (recoverable) { | 1615 | if (recoverable) { |
1635 | regs->tpc = fixup; | 1616 | regs->tpc = entry->fixup; |
1636 | regs->tnpc = regs->tpc + 4; | 1617 | regs->tnpc = regs->tpc + 4; |
1637 | regs->u_regs[UREG_G2] = g2; | ||
1638 | } | 1618 | } |
1639 | } | 1619 | } |
1640 | } | 1620 | } |