All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] arm64: Provide ESR_EL1 information to user signal handlers
@ 2014-04-06 22:19 Catalin Marinas
  2014-04-06 22:19 ` [PATCH 1/3] arm64: Provide read/write fault information in compat " Catalin Marinas
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Catalin Marinas @ 2014-04-06 22:19 UTC (permalink / raw)
  To: linux-arm-kernel

The arm64 port omitted the fault status information in sigcontext.
However, there are emulators like Qemu that rely on such information to
distinguish between a read or a write fault without decoding the
faulting instruction.

The first patch fixes the compat case. The second patch is a clean-up
and the third introduces the esr_context structure with its own magic to
be stored on the signal handler stack when applicable (SIGSEGV and
SIGBUS). Given that this hardware register is meant for EL1 consumption,
if significant changes are made in future architecture versions a new
magic number will be introduced.

Catalin Marinas (3):
  arm64: Provide read/write fault information in compat signal handlers
  arm64: Remove the aux_context structure
  arm64: Expose ESR_EL1 information to user when SIGSEGV/SIGBUS

 arch/arm64/include/asm/processor.h       |  1 +
 arch/arm64/include/asm/sigcontext.h      | 31 --------------------------
 arch/arm64/include/uapi/asm/sigcontext.h |  7 ++++++
 arch/arm64/kernel/signal.c               | 37 +++++++++++++++++++++++---------
 arch/arm64/kernel/signal32.c             |  4 +++-
 arch/arm64/kernel/traps.c                |  7 ++++--
 arch/arm64/mm/fault.c                    |  3 ++-
 7 files changed, 45 insertions(+), 45 deletions(-)
 delete mode 100644 arch/arm64/include/asm/sigcontext.h

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/3] arm64: Provide read/write fault information in compat signal handlers
  2014-04-06 22:19 [PATCH 0/3] arm64: Provide ESR_EL1 information to user signal handlers Catalin Marinas
@ 2014-04-06 22:19 ` Catalin Marinas
  2014-04-07  9:39   ` Michal Simek
  2014-04-06 22:19 ` [PATCH 2/3] arm64: Remove the aux_context structure Catalin Marinas
  2014-04-06 22:19 ` [PATCH 3/3] arm64: Expose ESR_EL1 information to user when SIGSEGV/SIGBUS Catalin Marinas
  2 siblings, 1 reply; 6+ messages in thread
From: Catalin Marinas @ 2014-04-06 22:19 UTC (permalink / raw)
  To: linux-arm-kernel

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>
---
 arch/arm64/include/asm/processor.h | 1 +
 arch/arm64/kernel/signal32.c       | 4 +++-
 arch/arm64/kernel/traps.c          | 7 +++++--
 arch/arm64/mm/fault.c              | 3 ++-
 4 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index 45b20cd6cbca..34de2a8f7d93 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -79,6 +79,7 @@ struct thread_struct {
 	unsigned long		tp_value;
 	struct fpsimd_state	fpsimd_state;
 	unsigned long		fault_address;	/* fault info */
+	unsigned long		fault_code;	/* ESR_EL1 value */
 	struct debug_info	debug;		/* debugging */
 };
 
diff --git a/arch/arm64/kernel/signal32.c b/arch/arm64/kernel/signal32.c
index b3fc9f5ec6d3..e4f0c0b0ca3a 100644
--- a/arch/arm64/kernel/signal32.c
+++ b/arch/arm64/kernel/signal32.c
@@ -500,7 +500,9 @@ static int compat_setup_sigframe(struct compat_sigframe __user *sf,
 	__put_user_error(regs->pstate, &sf->uc.uc_mcontext.arm_cpsr, err);
 
 	__put_user_error((compat_ulong_t)0, &sf->uc.uc_mcontext.trap_no, err);
-	__put_user_error((compat_ulong_t)0, &sf->uc.uc_mcontext.error_code, err);
+	/* compat tasks expect bit 11 as WnR status bit */
+	__put_user_error((current->thread.fault_code & (1 << 6)) << 5,
+			 &sf->uc.uc_mcontext.error_code, err);
 	__put_user_error(current->thread.fault_address, &sf->uc.uc_mcontext.fault_address, err);
 	__put_user_error(set->sig[0], &sf->uc.uc_mcontext.oldmask, err);
 
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index 7ffadddb645d..c43cfa9b8304 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -251,10 +251,13 @@ void die(const char *str, struct pt_regs *regs, int err)
 void arm64_notify_die(const char *str, struct pt_regs *regs,
 		      struct siginfo *info, int err)
 {
-	if (user_mode(regs))
+	if (user_mode(regs)) {
+		current->thread.fault_address = 0;
+		current->thread.fault_code = err;
 		force_sig_info(info->si_signo, info, current);
-	else
+	} else {
 		die(str, regs, err);
+	}
 }
 
 asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index c23751b06120..625985f6531b 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -123,6 +123,7 @@ static void __do_user_fault(struct task_struct *tsk, unsigned long addr,
 	}
 
 	tsk->thread.fault_address = addr;
+	tsk->thread.fault_code = esr;
 	si.si_signo = sig;
 	si.si_errno = 0;
 	si.si_code = code;
@@ -525,7 +526,7 @@ asmlinkage int __exception do_debug_exception(unsigned long addr,
 	info.si_errno = 0;
 	info.si_code  = inf->code;
 	info.si_addr  = (void __user *)addr;
-	arm64_notify_die("", regs, &info, esr);
+	arm64_notify_die("", regs, &info, 0);
 
 	return 0;
 }

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/3] arm64: Remove the aux_context structure
  2014-04-06 22:19 [PATCH 0/3] arm64: Provide ESR_EL1 information to user signal handlers Catalin Marinas
  2014-04-06 22:19 ` [PATCH 1/3] arm64: Provide read/write fault information in compat " Catalin Marinas
@ 2014-04-06 22:19 ` Catalin Marinas
  2014-04-06 22:19 ` [PATCH 3/3] arm64: Expose ESR_EL1 information to user when SIGSEGV/SIGBUS Catalin Marinas
  2 siblings, 0 replies; 6+ messages in thread
From: Catalin Marinas @ 2014-04-06 22:19 UTC (permalink / raw)
  To: linux-arm-kernel

This patch removes the aux_context structure (and the containing file)
to allow the placement of the _aarch64_ctx end magic based on the
context stored on the signal stack.

Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
---
 arch/arm64/include/asm/sigcontext.h | 31 -------------------------------
 arch/arm64/kernel/signal.c          | 27 +++++++++++++++++----------
 2 files changed, 17 insertions(+), 41 deletions(-)
 delete mode 100644 arch/arm64/include/asm/sigcontext.h

diff --git a/arch/arm64/include/asm/sigcontext.h b/arch/arm64/include/asm/sigcontext.h
deleted file mode 100644
index dca1094acc74..000000000000
--- a/arch/arm64/include/asm/sigcontext.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2012 ARM Ltd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-#ifndef __ASM_SIGCONTEXT_H
-#define __ASM_SIGCONTEXT_H
-
-#include <uapi/asm/sigcontext.h>
-
-/*
- * Auxiliary context saved in the sigcontext.__reserved array. Not exported to
- * user space as it will change with the addition of new context. User space
- * should check the magic/size information.
- */
-struct aux_context {
-	struct fpsimd_context fpsimd;
-	/* additional context to be added before "end" */
-	struct _aarch64_ctx end;
-};
-#endif
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 890a591f75dd..7ff2eee96c6b 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -100,8 +100,7 @@ static int restore_sigframe(struct pt_regs *regs,
 {
 	sigset_t set;
 	int i, err;
-	struct aux_context __user *aux =
-		(struct aux_context __user *)sf->uc.uc_mcontext.__reserved;
+	void *aux = sf->uc.uc_mcontext.__reserved;
 
 	err = __copy_from_user(&set, &sf->uc.uc_sigmask, sizeof(set));
 	if (err == 0)
@@ -121,8 +120,11 @@ static int restore_sigframe(struct pt_regs *regs,
 
 	err |= !valid_user_regs(&regs->user_regs);
 
-	if (err == 0)
-		err |= restore_fpsimd_context(&aux->fpsimd);
+	if (err == 0) {
+		struct fpsimd_context *fpsimd_ctx =
+			container_of(aux, struct fpsimd_context, head);
+		err |= restore_fpsimd_context(fpsimd_ctx);
+	}
 
 	return err;
 }
@@ -167,8 +169,8 @@ static int setup_sigframe(struct rt_sigframe __user *sf,
 			  struct pt_regs *regs, sigset_t *set)
 {
 	int i, err = 0;
-	struct aux_context __user *aux =
-		(struct aux_context __user *)sf->uc.uc_mcontext.__reserved;
+	void *aux = sf->uc.uc_mcontext.__reserved;
+	struct _aarch64_ctx *end;
 
 	/* set up the stack frame for unwinding */
 	__put_user_error(regs->regs[29], &sf->fp, err);
@@ -185,12 +187,17 @@ static int setup_sigframe(struct rt_sigframe __user *sf,
 
 	err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(*set));
 
-	if (err == 0)
-		err |= preserve_fpsimd_context(&aux->fpsimd);
+	if (err == 0) {
+		struct fpsimd_context *fpsimd_ctx =
+			container_of(aux, struct fpsimd_context, head);
+		err |= preserve_fpsimd_context(fpsimd_ctx);
+		aux += sizeof(*fpsimd_ctx);
+	}
 
 	/* set the "end" magic */
-	__put_user_error(0, &aux->end.magic, err);
-	__put_user_error(0, &aux->end.size, err);
+	end = aux;
+	__put_user_error(0, &end->magic, err);
+	__put_user_error(0, &end->size, err);
 
 	return err;
 }

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 3/3] arm64: Expose ESR_EL1 information to user when SIGSEGV/SIGBUS
  2014-04-06 22:19 [PATCH 0/3] arm64: Provide ESR_EL1 information to user signal handlers Catalin Marinas
  2014-04-06 22:19 ` [PATCH 1/3] arm64: Provide read/write fault information in compat " Catalin Marinas
  2014-04-06 22:19 ` [PATCH 2/3] arm64: Remove the aux_context structure Catalin Marinas
@ 2014-04-06 22:19 ` Catalin Marinas
  2 siblings, 0 replies; 6+ messages in thread
From: Catalin Marinas @ 2014-04-06 22:19 UTC (permalink / raw)
  To: linux-arm-kernel

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>
---
 arch/arm64/include/uapi/asm/sigcontext.h |  7 +++++++
 arch/arm64/kernel/signal.c               | 10 ++++++++++
 2 files changed, 17 insertions(+)

diff --git a/arch/arm64/include/uapi/asm/sigcontext.h b/arch/arm64/include/uapi/asm/sigcontext.h
index 690ad51cc901..b72cf405b3fe 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 7ff2eee96c6b..dc2ab1b0ac0d 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);

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 1/3] arm64: Provide read/write fault information in compat signal handlers
  2014-04-06 22:19 ` [PATCH 1/3] arm64: Provide read/write fault information in compat " Catalin Marinas
@ 2014-04-07  9:39   ` Michal Simek
  2014-04-07 11:41     ` Catalin Marinas
  0 siblings, 1 reply; 6+ messages in thread
From: Michal Simek @ 2014-04-07  9:39 UTC (permalink / raw)
  To: linux-arm-kernel

On 04/07/2014 12:19 AM, Catalin Marinas wrote:
> 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>
> ---
>  arch/arm64/include/asm/processor.h | 1 +
>  arch/arm64/kernel/signal32.c       | 4 +++-
>  arch/arm64/kernel/traps.c          | 7 +++++--
>  arch/arm64/mm/fault.c              | 3 ++-
>  4 files changed, 11 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
> index 45b20cd6cbca..34de2a8f7d93 100644
> --- a/arch/arm64/include/asm/processor.h
> +++ b/arch/arm64/include/asm/processor.h
> @@ -79,6 +79,7 @@ struct thread_struct {
>  	unsigned long		tp_value;
>  	struct fpsimd_state	fpsimd_state;
>  	unsigned long		fault_address;	/* fault info */
> +	unsigned long		fault_code;	/* ESR_EL1 value */
>  	struct debug_info	debug;		/* debugging */
>  };
>  
> diff --git a/arch/arm64/kernel/signal32.c b/arch/arm64/kernel/signal32.c
> index b3fc9f5ec6d3..e4f0c0b0ca3a 100644
> --- a/arch/arm64/kernel/signal32.c
> +++ b/arch/arm64/kernel/signal32.c
> @@ -500,7 +500,9 @@ static int compat_setup_sigframe(struct compat_sigframe __user *sf,
>  	__put_user_error(regs->pstate, &sf->uc.uc_mcontext.arm_cpsr, err);
>  
>  	__put_user_error((compat_ulong_t)0, &sf->uc.uc_mcontext.trap_no, err);
> -	__put_user_error((compat_ulong_t)0, &sf->uc.uc_mcontext.error_code, err);
> +	/* compat tasks expect bit 11 as WnR status bit */
> +	__put_user_error((current->thread.fault_code & (1 << 6)) << 5,


Isn't it better to use macros for these magic values?

Thanks,
Michal


-- 
Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel - Microblaze cpu - http://www.monstr.eu/fdt/
Maintainer of Linux kernel - Xilinx Zynq ARM architecture
Microblaze U-BOOT custodian and responsible for u-boot arm zynq platform


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 263 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140407/7499cd9b/attachment.sig>

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/3] arm64: Provide read/write fault information in compat signal handlers
  2014-04-07  9:39   ` Michal Simek
@ 2014-04-07 11:41     ` Catalin Marinas
  0 siblings, 0 replies; 6+ messages in thread
From: Catalin Marinas @ 2014-04-07 11:41 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Apr 07, 2014 at 10:39:20AM +0100, Michal Simek wrote:
> On 04/07/2014 12:19 AM, Catalin Marinas wrote:
> > --- a/arch/arm64/kernel/signal32.c
> > +++ b/arch/arm64/kernel/signal32.c
> > @@ -500,7 +500,9 @@ static int compat_setup_sigframe(struct compat_sigframe __user *sf,
> >  	__put_user_error(regs->pstate, &sf->uc.uc_mcontext.arm_cpsr, err);
> >  
> >  	__put_user_error((compat_ulong_t)0, &sf->uc.uc_mcontext.trap_no, err);
> > -	__put_user_error((compat_ulong_t)0, &sf->uc.uc_mcontext.error_code, err);
> > +	/* compat tasks expect bit 11 as WnR status bit */
> > +	__put_user_error((current->thread.fault_code & (1 << 6)) << 5,
> 
> Isn't it better to use macros for these magic values?

I was too lazy ;). I'll add some macros.

-- 
Catalin

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2014-04-07 11:41 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-04-06 22:19 [PATCH 0/3] arm64: Provide ESR_EL1 information to user signal handlers Catalin Marinas
2014-04-06 22:19 ` [PATCH 1/3] arm64: Provide read/write fault information in compat " Catalin Marinas
2014-04-07  9:39   ` Michal Simek
2014-04-07 11:41     ` Catalin Marinas
2014-04-06 22:19 ` [PATCH 2/3] arm64: Remove the aux_context structure Catalin Marinas
2014-04-06 22:19 ` [PATCH 3/3] arm64: Expose ESR_EL1 information to user when SIGSEGV/SIGBUS Catalin Marinas

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.