aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm64/kernel/signal32.c
diff options
context:
space:
mode:
authorCatalin Marinas <catalin.marinas@arm.com>2014-04-06 18:04:12 -0400
committerCatalin Marinas <catalin.marinas@arm.com>2014-05-09 10:47:47 -0400
commit9141300a5884b57cea6d32c4e3fd16a337cfc99a (patch)
treed717d0ae66c7458c922b885c689b9c192b0f4083 /arch/arm64/kernel/signal32.c
parent6400111399e16a535231ebd76389c894ea1837ff (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.c7
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
84struct compat_aux_sigframe { 87struct 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