summaryrefslogtreecommitdiff
path: root/arch/tile
diff options
context:
space:
mode:
authorChris Metcalf <cmetcalf@tilera.com>2012-03-30 20:24:41 (GMT)
committerChris Metcalf <cmetcalf@tilera.com>2012-04-02 16:13:56 (GMT)
commitcdd8e16feba87a3fc2bb1885d36f895a2a3288bf (patch)
tree26569389231172fbf0baf00f71e06dae7bab2583 /arch/tile
parent54229ff359250ce7292dbeb59f157a2d3b67e30c (diff)
downloadlinux-cdd8e16feba87a3fc2bb1885d36f895a2a3288bf.tar.xz
arch/tile: return SIGBUS for addresses that are unaligned AND invalid
Previously we were returning SIGSEGV in this case. It seems cleaner to return SIGBUS since the hardware figures out alignment traps before TLB violations, so SIGBUS is the "more correct" signal. Signed-off-by: Chris Metcalf <cmetcalf@tilera.com>
Diffstat (limited to 'arch/tile')
-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 bc1eb58..9efbc13 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",