diff options
Diffstat (limited to 'arch/tile/kernel/unaligned.c')
-rw-r--r-- | arch/tile/kernel/unaligned.c | 22 |
1 files changed, 13 insertions, 9 deletions
diff --git a/arch/tile/kernel/unaligned.c b/arch/tile/kernel/unaligned.c index 7d9a83be0aca..d075f92ccee0 100644 --- a/arch/tile/kernel/unaligned.c +++ b/arch/tile/kernel/unaligned.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/module.h> | 25 | #include <linux/module.h> |
26 | #include <linux/compat.h> | 26 | #include <linux/compat.h> |
27 | #include <linux/prctl.h> | 27 | #include <linux/prctl.h> |
28 | #include <linux/context_tracking.h> | ||
28 | #include <asm/cacheflush.h> | 29 | #include <asm/cacheflush.h> |
29 | #include <asm/traps.h> | 30 | #include <asm/traps.h> |
30 | #include <asm/uaccess.h> | 31 | #include <asm/uaccess.h> |
@@ -1448,6 +1449,7 @@ void jit_bundle_gen(struct pt_regs *regs, tilegx_bundle_bits bundle, | |||
1448 | 1449 | ||
1449 | void do_unaligned(struct pt_regs *regs, int vecnum) | 1450 | void do_unaligned(struct pt_regs *regs, int vecnum) |
1450 | { | 1451 | { |
1452 | enum ctx_state prev_state = exception_enter(); | ||
1451 | tilegx_bundle_bits __user *pc; | 1453 | tilegx_bundle_bits __user *pc; |
1452 | tilegx_bundle_bits bundle; | 1454 | tilegx_bundle_bits bundle; |
1453 | struct thread_info *info = current_thread_info(); | 1455 | struct thread_info *info = current_thread_info(); |
@@ -1487,12 +1489,11 @@ void do_unaligned(struct pt_regs *regs, int vecnum) | |||
1487 | (int)unaligned_fixup, | 1489 | (int)unaligned_fixup, |
1488 | (unsigned long long)regs->ex1, | 1490 | (unsigned long long)regs->ex1, |
1489 | (unsigned long long)regs->pc); | 1491 | (unsigned long long)regs->pc); |
1490 | return; | 1492 | } else { |
1493 | /* Not fixable. Go panic. */ | ||
1494 | panic("Unalign exception in Kernel. pc=%lx", | ||
1495 | regs->pc); | ||
1491 | } | 1496 | } |
1492 | /* Not fixable. Go panic. */ | ||
1493 | panic("Unalign exception in Kernel. pc=%lx", | ||
1494 | regs->pc); | ||
1495 | return; | ||
1496 | } else { | 1497 | } else { |
1497 | /* | 1498 | /* |
1498 | * Try to fix the exception. If we can't, panic the | 1499 | * Try to fix the exception. If we can't, panic the |
@@ -1501,8 +1502,8 @@ void do_unaligned(struct pt_regs *regs, int vecnum) | |||
1501 | bundle = GX_INSN_BSWAP( | 1502 | bundle = GX_INSN_BSWAP( |
1502 | *((tilegx_bundle_bits *)(regs->pc))); | 1503 | *((tilegx_bundle_bits *)(regs->pc))); |
1503 | jit_bundle_gen(regs, bundle, align_ctl); | 1504 | jit_bundle_gen(regs, bundle, align_ctl); |
1504 | return; | ||
1505 | } | 1505 | } |
1506 | goto done; | ||
1506 | } | 1507 | } |
1507 | 1508 | ||
1508 | /* | 1509 | /* |
@@ -1526,7 +1527,7 @@ void do_unaligned(struct pt_regs *regs, int vecnum) | |||
1526 | 1527 | ||
1527 | trace_unhandled_signal("unaligned fixup trap", regs, 0, SIGBUS); | 1528 | trace_unhandled_signal("unaligned fixup trap", regs, 0, SIGBUS); |
1528 | force_sig_info(info.si_signo, &info, current); | 1529 | force_sig_info(info.si_signo, &info, current); |
1529 | return; | 1530 | goto done; |
1530 | } | 1531 | } |
1531 | 1532 | ||
1532 | 1533 | ||
@@ -1543,7 +1544,7 @@ void do_unaligned(struct pt_regs *regs, int vecnum) | |||
1543 | trace_unhandled_signal("segfault in unalign fixup", regs, | 1544 | trace_unhandled_signal("segfault in unalign fixup", regs, |
1544 | (unsigned long)info.si_addr, SIGSEGV); | 1545 | (unsigned long)info.si_addr, SIGSEGV); |
1545 | force_sig_info(info.si_signo, &info, current); | 1546 | force_sig_info(info.si_signo, &info, current); |
1546 | return; | 1547 | goto done; |
1547 | } | 1548 | } |
1548 | 1549 | ||
1549 | if (!info->unalign_jit_base) { | 1550 | if (!info->unalign_jit_base) { |
@@ -1578,7 +1579,7 @@ void do_unaligned(struct pt_regs *regs, int vecnum) | |||
1578 | 1579 | ||
1579 | if (IS_ERR((void __force *)user_page)) { | 1580 | if (IS_ERR((void __force *)user_page)) { |
1580 | pr_err("Out of kernel pages trying do_mmap\n"); | 1581 | pr_err("Out of kernel pages trying do_mmap\n"); |
1581 | return; | 1582 | goto done; |
1582 | } | 1583 | } |
1583 | 1584 | ||
1584 | /* Save the address in the thread_info struct */ | 1585 | /* Save the address in the thread_info struct */ |
@@ -1591,6 +1592,9 @@ void do_unaligned(struct pt_regs *regs, int vecnum) | |||
1591 | 1592 | ||
1592 | /* Generate unalign JIT */ | 1593 | /* Generate unalign JIT */ |
1593 | jit_bundle_gen(regs, GX_INSN_BSWAP(bundle), align_ctl); | 1594 | jit_bundle_gen(regs, GX_INSN_BSWAP(bundle), align_ctl); |
1595 | |||
1596 | done: | ||
1597 | exception_exit(prev_state); | ||
1594 | } | 1598 | } |
1595 | 1599 | ||
1596 | #endif /* __tilegx__ */ | 1600 | #endif /* __tilegx__ */ |