diff options
author | Dave Martin <dave.martin@linaro.org> | 2011-07-28 09:29:40 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2011-08-09 03:42:39 -0400 |
commit | 2102a65e69eac8d77dd71b4991b395e825087ba8 (patch) | |
tree | 4e13dd2abc790283b6a987bdbf8e9c37a339edc7 /arch/arm/mm | |
parent | 088c01f1e39dbe93a13e0b00f4532ed8b79d35f4 (diff) |
ARM: 7008/1: alignment: Make SIGBUS sent to userspace POSIXly correct
With the UM_SIGNAL alignment fault mode, no siginfo structure is
passed to userspace.
POSIX specifies how siginfo_t should be populated for alignment
faults, so this patch does just that:
* si_signo = SIGBUS
* si_code = BUS_ADRALN
* si_addr = misaligned data address at which access was attempted
Signed-off-by: Dave Martin <dave.martin@linaro.org>
Acked-by: Nicolas Pitre <nicolas.pitre@linaro.org>
Acked-by: Kirill A. Shutemov <kirill@shutemov.name>
Reviewed-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/mm')
-rw-r--r-- | arch/arm/mm/alignment.c | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c index 1df38e833570..cfbcf8b95599 100644 --- a/arch/arm/mm/alignment.c +++ b/arch/arm/mm/alignment.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/sched.h> | 22 | #include <linux/sched.h> |
23 | #include <linux/uaccess.h> | 23 | #include <linux/uaccess.h> |
24 | 24 | ||
25 | #include <asm/system.h> | ||
25 | #include <asm/unaligned.h> | 26 | #include <asm/unaligned.h> |
26 | 27 | ||
27 | #include "fault.h" | 28 | #include "fault.h" |
@@ -913,9 +914,16 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs) | |||
913 | if (ai_usermode & UM_FIXUP) | 914 | if (ai_usermode & UM_FIXUP) |
914 | goto fixup; | 915 | goto fixup; |
915 | 916 | ||
916 | if (ai_usermode & UM_SIGNAL) | 917 | if (ai_usermode & UM_SIGNAL) { |
917 | force_sig(SIGBUS, current); | 918 | siginfo_t si; |
918 | else { | 919 | |
920 | si.si_signo = SIGBUS; | ||
921 | si.si_errno = 0; | ||
922 | si.si_code = BUS_ADRALN; | ||
923 | si.si_addr = (void __user *)addr; | ||
924 | |||
925 | force_sig_info(si.si_signo, &si, current); | ||
926 | } else { | ||
919 | /* | 927 | /* |
920 | * We're about to disable the alignment trap and return to | 928 | * We're about to disable the alignment trap and return to |
921 | * user space. But if an interrupt occurs before actually | 929 | * user space. But if an interrupt occurs before actually |