summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/tile/kernel/single_step.c31
1 files changed, 19 insertions, 12 deletions
diff --git a/arch/tile/kernel/single_step.c b/arch/tile/kernel/single_step.c
index bc1eb586e24d..9efbc1391b3c 100644
--- a/arch/tile/kernel/single_step.c
+++ b/arch/tile/kernel/single_step.c
@@ -153,6 +153,25 @@ static tile_bundle_bits rewrite_load_store_unaligned(
if (((unsigned long)addr % size) == 0)
return bundle;
+ /*
+ * Return SIGBUS with the unaligned address, if requested.
+ * Note that we return SIGBUS even for completely invalid addresses
+ * as long as they are in fact unaligned; this matches what the
+ * tilepro hardware would be doing, if it could provide us with the
+ * actual bad address in an SPR, which it doesn't.
+ */
+ if (unaligned_fixup == 0) {
+ siginfo_t info = {
+ .si_signo = SIGBUS,
+ .si_code = BUS_ADRALN,
+ .si_addr = addr
+ };
+ trace_unhandled_signal("unaligned trap", regs,
+ (unsigned long)addr, SIGBUS);
+ force_sig_info(info.si_signo, &info, current);
+ return (tilepro_bundle_bits) 0;
+ }
+
#ifndef __LITTLE_ENDIAN
# error We assume little-endian representation with copy_xx_user size 2 here
#endif
@@ -192,18 +211,6 @@ static tile_bundle_bits rewrite_load_store_unaligned(
return (tile_bundle_bits) 0;
}
- if (unaligned_fixup == 0) {
- siginfo_t info = {
- .si_signo = SIGBUS,
- .si_code = BUS_ADRALN,
- .si_addr = addr
- };
- trace_unhandled_signal("unaligned trap", regs,
- (unsigned long)addr, SIGBUS);
- force_sig_info(info.si_signo, &info, current);
- return (tile_bundle_bits) 0;
- }
-
if (unaligned_printk || unaligned_fixup_count == 0) {
pr_info("Process %d/%s: PC %#lx: Fixup of"
" unaligned %s at %#lx.\n",