All of lore.kernel.org
 help / color / mirror / Atom feed
From: aaro.koskinen@nokia.com (Aaro Koskinen)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v3 1/2] ARM: Pass IFSR register to do_PrefetchAbort()
Date: Mon, 21 Sep 2009 12:37:26 +0300	[thread overview]
Message-ID: <4AB74956.8070708@nokia.com> (raw)
In-Reply-To: <2f6c0105e623b9134adbb2e849e8074722903fb9.1253530731.git.kirill@shutemov.name>

Hi,

Kirill A. Shutemov wrote:
> It needed for proper prefetch abort handling on ARMv7.
> 
> Instruction fault status register (IFSR) was introduced on ARMv7.

According to the ARMv7-AR reference manual it's available in ARMv6
(see chapter G.7).

> For older CPU we simulate IFSR with translation fault status. It
> allows to generalize code.
> 
> Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>
> ---
>  arch/arm/include/asm/glue.h    |   10 ++++++++--
>  arch/arm/kernel/entry-armv.S   |   14 ++++----------
>  arch/arm/kernel/entry-common.S |    8 ++++++--
>  arch/arm/mm/fault.c            |    2 +-
>  4 files changed, 19 insertions(+), 15 deletions(-)
> 
> diff --git a/arch/arm/include/asm/glue.h b/arch/arm/include/asm/glue.h
> index a0e39d5..5bfaf6f 100644
> --- a/arch/arm/include/asm/glue.h
> +++ b/arch/arm/include/asm/glue.h
> @@ -130,7 +130,10 @@
>  # ifdef CPU_PABORT_HANDLER
>  #  define MULTI_PABORT 1
>  # else
> -#  define CPU_PABORT_HANDLER(reg, insn)	mrc p15, 0, reg, cr6, cr0, 2
> +#  define CPU_PABORT_HANDLER(addr, ifsr, insn) \
> +	mrc	p15, 0, addr, c6, c0, 2 ; \
> +	mrc	p15, 0, ifsr, c5, c0, 1
> +
>  # endif
>  #endif
>  
> @@ -138,7 +141,10 @@
>  # ifdef CPU_PABORT_HANDLER
>  #  define MULTI_PABORT 1
>  # else
> -#  define CPU_PABORT_HANDLER(reg, insn)	mov reg, insn
> +#define __hash_5 #5
> +#  define CPU_PABORT_HANDLER(addr, ifsr, insn) \
> +	mov	addr, insn ; \
> +	mov	ifsr, __hash_5
>  # endif
>  #endif
>  
> diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
> index 3d727a8..335ae58 100644
> --- a/arch/arm/kernel/entry-armv.S
> +++ b/arch/arm/kernel/entry-armv.S
> @@ -303,22 +303,16 @@ __pabt_svc:
>  	tst	r3, #PSR_I_BIT
>  	biceq	r9, r9, #PSR_I_BIT
>  
> -	@
> -	@ set args, then call main handler
> -	@
> -	@  r0 - address of faulting instruction
> -	@  r1 - pointer to registers on stack
> -	@
>  #ifdef MULTI_PABORT
>  	mov	r0, r2			@ pass address of aborted instruction.
>  	ldr	r4, .LCprocfns
>  	mov	lr, pc
>  	ldr	pc, [r4, #PROCESSOR_PABT_FUNC]
>  #else
> -	CPU_PABORT_HANDLER(r0, r2)
> +	CPU_PABORT_HANDLER(r0, r1, r2)
>  #endif
>  	msr	cpsr_c, r9			@ Maybe enable interrupts
> -	mov	r1, sp				@ regs
> +	mov	r2, sp				@ regs
>  	bl	do_PrefetchAbort		@ call abort handler
>  
>  	@
> @@ -697,10 +691,10 @@ __pabt_usr:
>  	mov	lr, pc
>  	ldr	pc, [r4, #PROCESSOR_PABT_FUNC]
>  #else
> -	CPU_PABORT_HANDLER(r0, r2)
> +	CPU_PABORT_HANDLER(r0, r1, r2)
>  #endif
>  	enable_irq				@ Enable interrupts
> -	mov	r1, sp				@ regs
> +	mov	r2, sp				@ regs
>  	bl	do_PrefetchAbort		@ call abort handler
>   UNWIND(.fnend		)
>  	/* fall through */
> diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
> index 807cfeb..931ab9a 100644
> --- a/arch/arm/kernel/entry-common.S
> +++ b/arch/arm/kernel/entry-common.S
> @@ -426,10 +426,14 @@ sys_mmap2:
>  ENDPROC(sys_mmap2)
>  
>  ENTRY(pabort_ifar)
> -		mrc	p15, 0, r0, cr6, cr0, 2
> -ENTRY(pabort_noifar)
> +		mrc	p15, 0, r0, c6, c0, 2		@ get IFAR
> +		mrc	p15, 0, r1, c5, c0, 1		@ get IFSR
>  		mov	pc, lr
>  ENDPROC(pabort_ifar)
> +ENTRY(pabort_noifar)
> +		/* simulate IFSR with section translation fault status */
> +		mov	r1, #5
> +		mov	pc, lr
>  ENDPROC(pabort_noifar)
>  
>  #ifdef CONFIG_OABI_COMPAT
> diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
> index cc8829d..5e27462 100644
> --- a/arch/arm/mm/fault.c
> +++ b/arch/arm/mm/fault.c
> @@ -506,7 +506,7 @@ do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
>  }
>  
>  asmlinkage void __exception
> -do_PrefetchAbort(unsigned long addr, struct pt_regs *regs)
> +do_PrefetchAbort(unsigned long addr, int ifsr, struct pt_regs *regs)
>  {
>  	do_translation_fault(addr, 0, regs);
>  }

WARNING: multiple messages have this Message-ID (diff)
From: Aaro Koskinen <aaro.koskinen@nokia.com>
To: "ext Kirill A. Shutemov" <kirill@shutemov.name>
Cc: "linux-arm-kernel@lists.infradead.org" 
	<linux-arm-kernel@lists.infradead.org>,
	Russell King <linux@arm.linux.org.uk>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	"Bityutskiy Artem (Nokia-D/Helsinki)"
	<Artem.Bityutskiy@nokia.com>
Subject: Re: [PATCH v3 1/2] ARM: Pass IFSR register to do_PrefetchAbort()
Date: Mon, 21 Sep 2009 12:37:26 +0300	[thread overview]
Message-ID: <4AB74956.8070708@nokia.com> (raw)
In-Reply-To: <2f6c0105e623b9134adbb2e849e8074722903fb9.1253530731.git.kirill@shutemov.name>

Hi,

Kirill A. Shutemov wrote:
> It needed for proper prefetch abort handling on ARMv7.
> 
> Instruction fault status register (IFSR) was introduced on ARMv7.

According to the ARMv7-AR reference manual it's available in ARMv6
(see chapter G.7).

> For older CPU we simulate IFSR with translation fault status. It
> allows to generalize code.
> 
> Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>
> ---
>  arch/arm/include/asm/glue.h    |   10 ++++++++--
>  arch/arm/kernel/entry-armv.S   |   14 ++++----------
>  arch/arm/kernel/entry-common.S |    8 ++++++--
>  arch/arm/mm/fault.c            |    2 +-
>  4 files changed, 19 insertions(+), 15 deletions(-)
> 
> diff --git a/arch/arm/include/asm/glue.h b/arch/arm/include/asm/glue.h
> index a0e39d5..5bfaf6f 100644
> --- a/arch/arm/include/asm/glue.h
> +++ b/arch/arm/include/asm/glue.h
> @@ -130,7 +130,10 @@
>  # ifdef CPU_PABORT_HANDLER
>  #  define MULTI_PABORT 1
>  # else
> -#  define CPU_PABORT_HANDLER(reg, insn)	mrc p15, 0, reg, cr6, cr0, 2
> +#  define CPU_PABORT_HANDLER(addr, ifsr, insn) \
> +	mrc	p15, 0, addr, c6, c0, 2 ; \
> +	mrc	p15, 0, ifsr, c5, c0, 1
> +
>  # endif
>  #endif
>  
> @@ -138,7 +141,10 @@
>  # ifdef CPU_PABORT_HANDLER
>  #  define MULTI_PABORT 1
>  # else
> -#  define CPU_PABORT_HANDLER(reg, insn)	mov reg, insn
> +#define __hash_5 #5
> +#  define CPU_PABORT_HANDLER(addr, ifsr, insn) \
> +	mov	addr, insn ; \
> +	mov	ifsr, __hash_5
>  # endif
>  #endif
>  
> diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
> index 3d727a8..335ae58 100644
> --- a/arch/arm/kernel/entry-armv.S
> +++ b/arch/arm/kernel/entry-armv.S
> @@ -303,22 +303,16 @@ __pabt_svc:
>  	tst	r3, #PSR_I_BIT
>  	biceq	r9, r9, #PSR_I_BIT
>  
> -	@
> -	@ set args, then call main handler
> -	@
> -	@  r0 - address of faulting instruction
> -	@  r1 - pointer to registers on stack
> -	@
>  #ifdef MULTI_PABORT
>  	mov	r0, r2			@ pass address of aborted instruction.
>  	ldr	r4, .LCprocfns
>  	mov	lr, pc
>  	ldr	pc, [r4, #PROCESSOR_PABT_FUNC]
>  #else
> -	CPU_PABORT_HANDLER(r0, r2)
> +	CPU_PABORT_HANDLER(r0, r1, r2)
>  #endif
>  	msr	cpsr_c, r9			@ Maybe enable interrupts
> -	mov	r1, sp				@ regs
> +	mov	r2, sp				@ regs
>  	bl	do_PrefetchAbort		@ call abort handler
>  
>  	@
> @@ -697,10 +691,10 @@ __pabt_usr:
>  	mov	lr, pc
>  	ldr	pc, [r4, #PROCESSOR_PABT_FUNC]
>  #else
> -	CPU_PABORT_HANDLER(r0, r2)
> +	CPU_PABORT_HANDLER(r0, r1, r2)
>  #endif
>  	enable_irq				@ Enable interrupts
> -	mov	r1, sp				@ regs
> +	mov	r2, sp				@ regs
>  	bl	do_PrefetchAbort		@ call abort handler
>   UNWIND(.fnend		)
>  	/* fall through */
> diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
> index 807cfeb..931ab9a 100644
> --- a/arch/arm/kernel/entry-common.S
> +++ b/arch/arm/kernel/entry-common.S
> @@ -426,10 +426,14 @@ sys_mmap2:
>  ENDPROC(sys_mmap2)
>  
>  ENTRY(pabort_ifar)
> -		mrc	p15, 0, r0, cr6, cr0, 2
> -ENTRY(pabort_noifar)
> +		mrc	p15, 0, r0, c6, c0, 2		@ get IFAR
> +		mrc	p15, 0, r1, c5, c0, 1		@ get IFSR
>  		mov	pc, lr
>  ENDPROC(pabort_ifar)
> +ENTRY(pabort_noifar)
> +		/* simulate IFSR with section translation fault status */
> +		mov	r1, #5
> +		mov	pc, lr
>  ENDPROC(pabort_noifar)
>  
>  #ifdef CONFIG_OABI_COMPAT
> diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
> index cc8829d..5e27462 100644
> --- a/arch/arm/mm/fault.c
> +++ b/arch/arm/mm/fault.c
> @@ -506,7 +506,7 @@ do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
>  }
>  
>  asmlinkage void __exception
> -do_PrefetchAbort(unsigned long addr, struct pt_regs *regs)
> +do_PrefetchAbort(unsigned long addr, int ifsr, struct pt_regs *regs)
>  {
>  	do_translation_fault(addr, 0, regs);
>  }


  reply	other threads:[~2009-09-21  9:37 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-09-21 11:05 [PATCH v3 1/2] ARM: Pass IFSR register to do_PrefetchAbort() Kirill A. Shutemov
2009-09-21 11:05 ` Kirill A. Shutemov
2009-09-21  9:37 ` Aaro Koskinen [this message]
2009-09-21  9:37   ` Aaro Koskinen
2009-09-21 11:30   ` Kirill A. Shutemov
2009-09-21 11:30     ` Kirill A. Shutemov
2009-09-21 11:05 ` [PATCH v3 2/2] ARM: Proper prefetch abort handling on ARMv7 Kirill A. Shutemov
2009-09-21 11:05   ` Kirill A. Shutemov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4AB74956.8070708@nokia.com \
    --to=aaro.koskinen@nokia.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.