diff options
author | Catalin Marinas <catalin.marinas@arm.com> | 2014-04-06 18:04:12 -0400 |
---|---|---|
committer | Catalin Marinas <catalin.marinas@arm.com> | 2014-05-09 10:47:47 -0400 |
commit | 9141300a5884b57cea6d32c4e3fd16a337cfc99a (patch) | |
tree | d717d0ae66c7458c922b885c689b9c192b0f4083 /arch/arm64/kernel/signal32.c | |
parent | 6400111399e16a535231ebd76389c894ea1837ff (diff) |
arm64: Provide read/write fault information in compat signal handlers
For AArch32, bit 11 (WnR) of the FSR/ESR register is set when the fault
was caused by a write access and applications like Qemu rely on such
information being provided in sigcontext. This patch introduces the
ESR_EL1 tracking for the arm64 kernel faults and sets bit 11 accordingly
in compat sigcontext.
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Diffstat (limited to 'arch/arm64/kernel/signal32.c')
-rw-r--r-- | arch/arm64/kernel/signal32.c | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/arch/arm64/kernel/signal32.c b/arch/arm64/kernel/signal32.c index b3fc9f5ec6d3..050c1c2af777 100644 --- a/arch/arm64/kernel/signal32.c +++ b/arch/arm64/kernel/signal32.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/syscalls.h> | 23 | #include <linux/syscalls.h> |
24 | #include <linux/ratelimit.h> | 24 | #include <linux/ratelimit.h> |
25 | 25 | ||
26 | #include <asm/esr.h> | ||
26 | #include <asm/fpsimd.h> | 27 | #include <asm/fpsimd.h> |
27 | #include <asm/signal32.h> | 28 | #include <asm/signal32.h> |
28 | #include <asm/uaccess.h> | 29 | #include <asm/uaccess.h> |
@@ -81,6 +82,8 @@ struct compat_vfp_sigframe { | |||
81 | #define VFP_MAGIC 0x56465001 | 82 | #define VFP_MAGIC 0x56465001 |
82 | #define VFP_STORAGE_SIZE sizeof(struct compat_vfp_sigframe) | 83 | #define VFP_STORAGE_SIZE sizeof(struct compat_vfp_sigframe) |
83 | 84 | ||
85 | #define FSR_WRITE_SHIFT (11) | ||
86 | |||
84 | struct compat_aux_sigframe { | 87 | struct compat_aux_sigframe { |
85 | struct compat_vfp_sigframe vfp; | 88 | struct compat_vfp_sigframe vfp; |
86 | 89 | ||
@@ -500,7 +503,9 @@ static int compat_setup_sigframe(struct compat_sigframe __user *sf, | |||
500 | __put_user_error(regs->pstate, &sf->uc.uc_mcontext.arm_cpsr, err); | 503 | __put_user_error(regs->pstate, &sf->uc.uc_mcontext.arm_cpsr, err); |
501 | 504 | ||
502 | __put_user_error((compat_ulong_t)0, &sf->uc.uc_mcontext.trap_no, err); | 505 | __put_user_error((compat_ulong_t)0, &sf->uc.uc_mcontext.trap_no, err); |
503 | __put_user_error((compat_ulong_t)0, &sf->uc.uc_mcontext.error_code, err); | 506 | /* set the compat FSR WnR */ |
507 | __put_user_error(!!(current->thread.fault_code & ESR_EL1_WRITE) << | ||
508 | FSR_WRITE_SHIFT, &sf->uc.uc_mcontext.error_code, err); | ||
504 | __put_user_error(current->thread.fault_address, &sf->uc.uc_mcontext.fault_address, err); | 509 | __put_user_error(current->thread.fault_address, &sf->uc.uc_mcontext.fault_address, err); |
505 | __put_user_error(set->sig[0], &sf->uc.uc_mcontext.oldmask, err); | 510 | __put_user_error(set->sig[0], &sf->uc.uc_mcontext.oldmask, err); |
506 | 511 | ||