summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCatalin Marinas <catalin.marinas@arm.com>2013-09-16 15:19:27 +0100
committerChanho Park <chanho61.park@samsung.com>2014-04-16 21:36:53 +0900
commit9fc47e5328125a6b00aa998cb65ae205c9f62649 (patch)
treec3e835212afe469f0e424a2b8485be6be59350c5
parent5b7f4f430c6a897da5491ebc2fed0c95c9f1e700 (diff)
downloadlinux-3.10-9fc47e5328125a6b00aa998cb65ae205c9f62649.tar.gz
linux-3.10-9fc47e5328125a6b00aa998cb65ae205c9f62649.tar.bz2
linux-3.10-9fc47e5328125a6b00aa998cb65ae205c9f62649.zip
arm64: Expose ESR_EL1 information to user when SIGSEGV/SIGBUS
This information is useful for instruction emulators to detect read/write and access size without having to decode the faulting instruction. The current patch exports it via sigcontext (struct esr_context) and is only valid for SIGSEGV and SIGBUS. Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
-rw-r--r--arch/arm64/include/uapi/asm/sigcontext.h7
-rw-r--r--arch/arm64/kernel/signal.c10
2 files changed, 17 insertions, 0 deletions
diff --git a/arch/arm64/include/uapi/asm/sigcontext.h b/arch/arm64/include/uapi/asm/sigcontext.h
index 690ad51cc90..b72cf405b3f 100644
--- a/arch/arm64/include/uapi/asm/sigcontext.h
+++ b/arch/arm64/include/uapi/asm/sigcontext.h
@@ -53,5 +53,12 @@ struct fpsimd_context {
__uint128_t vregs[32];
};
+/* ESR_EL1 context */
+#define ESR_MAGIC 0x45535201
+
+struct esr_context {
+ struct _aarch64_ctx head;
+ u64 esr;
+};
#endif /* _UAPI__ASM_SIGCONTEXT_H */
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 7ff2eee96c6..dc2ab1b0ac0 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -194,6 +194,16 @@ static int setup_sigframe(struct rt_sigframe __user *sf,
aux += sizeof(*fpsimd_ctx);
}
+ /* fault information, if valid */
+ if (current->thread.fault_code) {
+ struct esr_context *esr_ctx =
+ container_of(aux, struct esr_context, head);
+ __put_user_error(ESR_MAGIC, &esr_ctx->head.magic, err);
+ __put_user_error(sizeof(*esr_ctx), &esr_ctx->head.size, err);
+ __put_user_error(current->thread.fault_code, &esr_ctx->esr, err);
+ aux += sizeof(*esr_ctx);
+ }
+
/* set the "end" magic */
end = aux;
__put_user_error(0, &end->magic, err);