lkml.org 
[lkml]   [2009]   [Sep]   [18]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 1/2] ARM: Pass IFSR register to do_PrefetchAbort()
    Date
    It needed for proper prefetch abort handling on ARMv7.

    Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>
    ---
    arch/arm/include/asm/glue.h | 4 ++--
    arch/arm/kernel/entry-armv.S | 14 ++++----------
    arch/arm/mm/Makefile | 2 ++
    arch/arm/mm/fault.c | 2 +-
    arch/arm/mm/pabort-ifar.S | 18 ++++++++++++++++++
    arch/arm/mm/pabort-noifar.S | 18 ++++++++++++++++++
    6 files changed, 45 insertions(+), 13 deletions(-)
    create mode 100644 arch/arm/mm/pabort-ifar.S
    create mode 100644 arch/arm/mm/pabort-noifar.S

    diff --git a/arch/arm/include/asm/glue.h b/arch/arm/include/asm/glue.h
    index a0e39d5..bc6595c 100644
    --- a/arch/arm/include/asm/glue.h
    +++ b/arch/arm/include/asm/glue.h
    @@ -130,7 +130,7 @@
    # 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 ifar_pabort
    # endif
    #endif

    @@ -138,7 +138,7 @@
    # ifdef CPU_PABORT_HANDLER
    # define MULTI_PABORT 1
    # else
    -# define CPU_PABORT_HANDLER(reg, insn) mov reg, insn
    +# define CPU_PABORT_HANDLER noifar_pabort
    # endif
    #endif

    diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
    index 85040cf..dbb4ce7 100644
    --- a/arch/arm/kernel/entry-armv.S
    +++ b/arch/arm/kernel/entry-armv.S
    @@ -291,22 +291,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)
    + bl CPU_PABORT_HANDLER
    #endif
    msr cpsr_c, r9 @ Maybe enable interrupts
    - mov r1, sp @ regs
    + mov r2, sp @ regs
    bl do_PrefetchAbort @ call abort handler

    @
    @@ -666,10 +660,10 @@ __pabt_usr:
    mov lr, pc
    ldr pc, [r4, #PROCESSOR_PABT_FUNC]
    #else
    - CPU_PABORT_HANDLER(r0, r2)
    + bl CPU_PABORT_HANDLER
    #endif
    enable_irq @ Enable interrupts
    - mov r1, sp @ regs
    + mov r2, sp @ regs
    bl do_PrefetchAbort @ call abort handler
    /* fall through */
    /*
    diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile
    index 480f78a..30f1708 100644
    --- a/arch/arm/mm/Makefile
    +++ b/arch/arm/mm/Makefile
    @@ -78,3 +78,5 @@ obj-$(CONFIG_CACHE_FEROCEON_L2) += cache-feroceon-l2.o
    obj-$(CONFIG_CACHE_L2X0) += cache-l2x0.o
    obj-$(CONFIG_CACHE_XSC3L2) += cache-xsc3l2.o

    +obj-$(CONFIG_CPU_PABRT_NOIFAR) += pabort-noifar.o
    +obj-$(CONFIG_CPU_PABRT_IFAR) += pabort-ifar.o
    diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
    index 22c9530..c7bbb32 100644
    --- a/arch/arm/mm/fault.c
    +++ b/arch/arm/mm/fault.c
    @@ -480,7 +480,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);
    }
    diff --git a/arch/arm/mm/pabort-ifar.S b/arch/arm/mm/pabort-ifar.S
    new file mode 100644
    index 0000000..46838ea
    --- /dev/null
    +++ b/arch/arm/mm/pabort-ifar.S
    @@ -0,0 +1,18 @@
    +#include <linux/linkage.h>
    +#include <asm/assembler.h>
    +
    +/*
    + * Function: ifar_pabort
    + *
    + * Returns : r0 = address of abort
    + * : r1 = IFSR
    + *
    + * Purpose : obtain information about current prefetch abort.
    + */
    + .align 5
    +ENTRY(ifar_pabort)
    + mrc p15, 0, r0, c6, c0, 2 @ get IFAR
    + mrc p15, 0, r1, c5, c0, 1 @ get IFSR
    +
    + mov pc, lr
    +ENDPROC(ifar_pabort)
    diff --git a/arch/arm/mm/pabort-noifar.S b/arch/arm/mm/pabort-noifar.S
    new file mode 100644
    index 0000000..46b0daf
    --- /dev/null
    +++ b/arch/arm/mm/pabort-noifar.S
    @@ -0,0 +1,18 @@
    +#include <linux/linkage.h>
    +#include <asm/assembler.h>
    +
    +/*
    + * Function: noifar_pabort
    +
    + * Returns : r0 = address of abort
    + * : r1 = 5, simulate IFSR with section translation fault status
    + *
    + * Purpose : obtain information about current prefetch abort.
    + */
    + .align 5
    +ENTRY(noifar_pabort)
    + mov r0, insn
    + mov r1, #5 @ translation fault
    +
    + mov pc, lr
    +ENDPROC(noifar_pabort)
    --
    1.6.4.4


    \
     
     \ /
      Last update: 2009-09-18 12:51    [W:0.046 / U:89.632 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site