1
0
Fork 0
alistair23-linux/arch/nds32/kernel/ex-exit.S

194 lines
3.9 KiB
ArmAsm
Raw Normal View History

nds32: Exception handling This patch includes the exception/interrupt entries, pt_reg structure and related accessors. /* Unaligned accessing handling*/ Andes processors cannot load/store information which is not naturally aligned on the bus, i.e., loading a 4 byte data whose start address must be divisible by 4. If unaligned data accessing is happened, data unaligned exception will be triggered and user will get SIGSEGV or kernel oops according to the unaligned address. In order to make user be able to load/store data from an unaligned address, software load/store emulation is implemented in arch/nds32/mm/alignment.c to address data unaligned exception. Unaligned accessing handling is disabled by default because it is not a normal case. User can enable this feature by following steps. A. Compile time: 1. Enable kernel config CONFIG_ALIGNMENT_TRAP B. Run time: 1. Enter /proc/sys/nds32/unaligned_acess folder 2. Write 1 to file enable_mode to enable unaligned accessing handling. User can disable it by writing 0 to this file. 3. Write 1 to file debug to show which unaligned address is under processing. User can disable it by writing 0 to this file. However, unaligned accessing handler cannot work if this unaligned address is not accessible such as protection violation. On this condition, the default behaviors for addressing data unaligned exception still happen Signed-off-by: Vincent Chen <vincentc@andestech.com> Signed-off-by: Greentime Hu <greentime@andestech.com> Acked-by: Arnd Bergmann <arnd@arndb.de>
2017-10-24 00:42:02 -06:00
// SPDX-License-Identifier: GPL-2.0
// Copyright (C) 2005-2017 Andes Technology Corporation
#include <linux/linkage.h>
#include <asm/unistd.h>
#include <asm/assembler.h>
#include <asm/nds32.h>
#include <asm/asm-offsets.h>
#include <asm/thread_info.h>
#include <asm/current.h>
#include <asm/fpu.h>
nds32: Exception handling This patch includes the exception/interrupt entries, pt_reg structure and related accessors. /* Unaligned accessing handling*/ Andes processors cannot load/store information which is not naturally aligned on the bus, i.e., loading a 4 byte data whose start address must be divisible by 4. If unaligned data accessing is happened, data unaligned exception will be triggered and user will get SIGSEGV or kernel oops according to the unaligned address. In order to make user be able to load/store data from an unaligned address, software load/store emulation is implemented in arch/nds32/mm/alignment.c to address data unaligned exception. Unaligned accessing handling is disabled by default because it is not a normal case. User can enable this feature by following steps. A. Compile time: 1. Enable kernel config CONFIG_ALIGNMENT_TRAP B. Run time: 1. Enter /proc/sys/nds32/unaligned_acess folder 2. Write 1 to file enable_mode to enable unaligned accessing handling. User can disable it by writing 0 to this file. 3. Write 1 to file debug to show which unaligned address is under processing. User can disable it by writing 0 to this file. However, unaligned accessing handler cannot work if this unaligned address is not accessible such as protection violation. On this condition, the default behaviors for addressing data unaligned exception still happen Signed-off-by: Vincent Chen <vincentc@andestech.com> Signed-off-by: Greentime Hu <greentime@andestech.com> Acked-by: Arnd Bergmann <arnd@arndb.de>
2017-10-24 00:42:02 -06:00
#ifdef CONFIG_HWZOL
.macro pop_zol
mtusr $r14, $LB
mtusr $r15, $LE
mtusr $r16, $LC
.endm
#endif
.macro restore_user_regs_first
setgie.d
isb
#if defined(CONFIG_FPU)
addi $sp, $sp, OSP_OFFSET
lmw.adm $r12, [$sp], $r25, #0x0
sethi $p0, hi20(has_fpu)
lbsi $p0, [$p0+lo12(has_fpu)]
beqz $p0, 2f
mtsr $r25, $FUCOP_CTL
2:
#else
nds32: Exception handling This patch includes the exception/interrupt entries, pt_reg structure and related accessors. /* Unaligned accessing handling*/ Andes processors cannot load/store information which is not naturally aligned on the bus, i.e., loading a 4 byte data whose start address must be divisible by 4. If unaligned data accessing is happened, data unaligned exception will be triggered and user will get SIGSEGV or kernel oops according to the unaligned address. In order to make user be able to load/store data from an unaligned address, software load/store emulation is implemented in arch/nds32/mm/alignment.c to address data unaligned exception. Unaligned accessing handling is disabled by default because it is not a normal case. User can enable this feature by following steps. A. Compile time: 1. Enable kernel config CONFIG_ALIGNMENT_TRAP B. Run time: 1. Enter /proc/sys/nds32/unaligned_acess folder 2. Write 1 to file enable_mode to enable unaligned accessing handling. User can disable it by writing 0 to this file. 3. Write 1 to file debug to show which unaligned address is under processing. User can disable it by writing 0 to this file. However, unaligned accessing handler cannot work if this unaligned address is not accessible such as protection violation. On this condition, the default behaviors for addressing data unaligned exception still happen Signed-off-by: Vincent Chen <vincentc@andestech.com> Signed-off-by: Greentime Hu <greentime@andestech.com> Acked-by: Arnd Bergmann <arnd@arndb.de>
2017-10-24 00:42:02 -06:00
addi $sp, $sp, FUCOP_CTL_OFFSET
lmw.adm $r12, [$sp], $r24, #0x0
#endif
nds32: Exception handling This patch includes the exception/interrupt entries, pt_reg structure and related accessors. /* Unaligned accessing handling*/ Andes processors cannot load/store information which is not naturally aligned on the bus, i.e., loading a 4 byte data whose start address must be divisible by 4. If unaligned data accessing is happened, data unaligned exception will be triggered and user will get SIGSEGV or kernel oops according to the unaligned address. In order to make user be able to load/store data from an unaligned address, software load/store emulation is implemented in arch/nds32/mm/alignment.c to address data unaligned exception. Unaligned accessing handling is disabled by default because it is not a normal case. User can enable this feature by following steps. A. Compile time: 1. Enable kernel config CONFIG_ALIGNMENT_TRAP B. Run time: 1. Enter /proc/sys/nds32/unaligned_acess folder 2. Write 1 to file enable_mode to enable unaligned accessing handling. User can disable it by writing 0 to this file. 3. Write 1 to file debug to show which unaligned address is under processing. User can disable it by writing 0 to this file. However, unaligned accessing handler cannot work if this unaligned address is not accessible such as protection violation. On this condition, the default behaviors for addressing data unaligned exception still happen Signed-off-by: Vincent Chen <vincentc@andestech.com> Signed-off-by: Greentime Hu <greentime@andestech.com> Acked-by: Arnd Bergmann <arnd@arndb.de>
2017-10-24 00:42:02 -06:00
mtsr $r12, $SP_USR
mtsr $r13, $IPC
#ifdef CONFIG_HWZOL
pop_zol
#endif
mtsr $r19, $PSW
mtsr $r20, $IPSW
mtsr $r21, $P_IPSW
mtsr $r22, $P_IPC
mtsr $r23, $P_P0
mtsr $r24, $P_P1
lmw.adm $sp, [$sp], $sp, #0xe
.endm
.macro restore_user_regs_last
pop $p0
cmovn $sp, $p0, $p0
iret
nop
.endm
.macro restore_user_regs
restore_user_regs_first
lmw.adm $r0, [$sp], $r25, #0x0
addi $sp, $sp, OSP_OFFSET
restore_user_regs_last
.endm
.macro fast_restore_user_regs
restore_user_regs_first
lmw.adm $r1, [$sp], $r25, #0x0
addi $sp, $sp, OSP_OFFSET-4
restore_user_regs_last
.endm
#ifdef CONFIG_PREEMPT
.macro preempt_stop
.endm
#else
.macro preempt_stop
setgie.d
isb
.endm
#define resume_kernel no_work_pending
#endif
ENTRY(ret_from_exception)
preempt_stop
ENTRY(ret_from_intr)
/*
* judge Kernel or user mode
*
*/
lwi $p0, [$sp+(#IPSW_OFFSET)] ! Check if in nested interrupt
andi $p0, $p0, #PSW_mskINTL
bnez $p0, resume_kernel ! done with iret
j resume_userspace
/*
* This is the fast syscall return path. We do as little as
* possible here, and this includes saving $r0 back into the SVC
* stack.
* fixed: tsk - $r25, syscall # - $r7, syscall table pointer - $r8
*/
ENTRY(ret_fast_syscall)
gie_disable
lwi $r1, [tsk+#TSK_TI_FLAGS]
andi $p1, $r1, #_TIF_WORK_MASK
bnez $p1, fast_work_pending
fast_restore_user_regs ! iret
/*
* Ok, we need to do extra processing,
* enter the slow path returning from syscall, while pending work.
*/
fast_work_pending:
swi $r0, [$sp+(#R0_OFFSET)] ! what is different from ret_from_exception
work_pending:
andi $p1, $r1, #_TIF_NEED_RESCHED
bnez $p1, work_resched
andi $p1, $r1, #_TIF_SIGPENDING|#_TIF_NOTIFY_RESUME
beqz $p1, no_work_pending
move $r0, $sp ! 'regs'
gie_enable
bal do_notify_resume
b ret_slow_syscall
work_resched:
bal schedule ! path, return to user mode
/*
* "slow" syscall return path.
*/
ENTRY(resume_userspace)
ENTRY(ret_slow_syscall)
gie_disable
lwi $p0, [$sp+(#IPSW_OFFSET)] ! Check if in nested interrupt
andi $p0, $p0, #PSW_mskINTL
bnez $p0, no_work_pending ! done with iret
lwi $r1, [tsk+#TSK_TI_FLAGS]
andi $p1, $r1, #_TIF_WORK_MASK
bnez $p1, work_pending ! handle work_resched, sig_pend
no_work_pending:
#ifdef CONFIG_TRACE_IRQFLAGS
lwi $p0, [$sp+(#IPSW_OFFSET)]
andi $p0, $p0, #0x1
nds32: Fix a kernel panic issue because of wrong frame pointer access. It can make sure that trace_hardirqs_off/trace_hardirqs_on can get a correct return address by frame pointer through __builtin_return_address() in this fix. Unable to handle kernel paging request at virtual address fffffffc pgd = 3c42e9cf [fffffffc] *pgd=02a9c000 Internal error: Oops: 1 [#1] Modules linked in: CPU: 0 PC is at trace_hardirqs_off+0x78/0xec LP is at common_exception_handler+0xda/0xf4 pc : [<b23ea5a4>] lp : [<b2352eba>] Tainted: G W sp : ada60ab0 fp : efcaff48 gp : 3a020490 r25: efcb0000 r24: 00000000 r23: 00000000 r22: 00000000 r21: 00000000 r20: 000700c1 r19: 000700ca r18: 3a21b018 r17: 00000001 r16: 00000002 r15: 00000001 r14: 0000002a r13: 3a00a804 r12: ada60ab0 r11: 3a113af8 r10: 3a01c530 r9 : 3a124404 r8 : 00120f9c r7 : b2352eba r6 : 00000000 r5 : 3a126b58 r4 : 00000000 r3 : 3a1726a8 r2 : b2921000 r1 : 00000000 r0 : 00000000 IRQs off Segment user Process init (pid: 1, stack limit = 0x069d7f15) Stack: (0xada60ab0 to 0xada61000) Stack: 0aa0: 00000000 00000003 3a110000 0011f000 Stack: 0ac0: 00000005 00000000 00000000 00000000 ada60b10 3a01fe68 ada60b0c ada60b08 Stack: 0ae0: 00000000 ada60ab8 ada60b30 3a020550 00000000 00000001 3a11c2f8 3a01c6e8 Stack: 0b00: 3a01cb80 fffffba8 3a113af8 3a21b018 3a122c28 00003ec4 00000165 00000000 Stack: 0b20: 3a126aec 0000006c 00000000 00000001 3a01fe68 00000000 00000003 00000000 Stack: 0b40: 00000001 000003f8 3a020930 3a01c530 00000008 ada60c18 3a020490 3a003120 Stack: 0b60: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 Stack: 0b80: 00000000 00000000 00000000 00000000 ffff8000 00000000 00000000 00000000 Stack: 0ba0: 00000000 00000001 3a020550 00000000 3a01d020 00000000 fffff000 fffff000 Stack: 0bc0: 00000000 00000000 00000000 00000000 ada60f2c 00000000 00000001 00000000 Stack: 0be0: 00000000 00000000 3a01fe68 fffffab0 00008034 00000008 3a0010cc 3a01fe68 Stack: 0c00: 00000000 00000000 00000001 ada60c88 3a020490 3a0139d4 0009dc6f 00000000 Stack: 0c20: 00000000 00000000 ada60fce fffff000 00000000 0000ebe0 3a020038 3a020550 Stack: 0c40: ada60f20 ada60c90 3a0007f0 3a0002a8 ada60c8c 00000000 00000000 ada60c88 Stack: 0c60: 3a020490 3a004570 00000000 00000000 ada60f20 3a0007f0 3a000000 00000000 Stack: 0c80: 3a020490 3a004850 00000000 3a013f24 3a000000 00000000 3a01ff44 00000000 Stack: 0ca0: 00000000 00000000 00000000 00000000 00000000 00000000 3a01ff84 3a01ff7c Stack: 0cc0: 3a01ff4c 3a01ff5c 3a01ff64 3a01ff9c 3a01ffa4 3a01ffac 3a01ff6c 3a01ff74 Stack: 0ce0: 00000000 00000000 3a01ff44 00000000 00000000 00000000 00000000 00000000 Stack: 0d00: 3a01ff8c 00000000 00000000 3a01ff94 00000000 00000000 00000000 00000000 Stack: 0d20: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 Stack: 0d40: 3a01ffbc 3a01ffb4 00000000 00000000 00000000 00000000 00000000 00000000 Stack: 0d60: 00000000 00000000 00000000 00000000 00000000 3a01ffc4 00000000 00000000 Stack: 0d80: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 Stack: 0da0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 Stack: 0dc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 3a01ff54 Stack: 0de0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 Stack: 0e00: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 Stack: 0e20: 00000000 00000004 00000000 00000000 00000000 00000000 00000000 00000000 Stack: 0e40: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 Stack: 0e60: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 Stack: 0e80: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 Stack: 0ea0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 Stack: 0ec0: 00000000 00000000 00000000 00000000 ffffffff 00000000 00000000 00000000 Stack: 0ee0: 00000000 00000000 00000000 00000000 ada60f20 00000000 00000000 00000000 Stack: 0f00: 00000000 00000000 00000000 00000000 00000000 00000000 3a020490 3a000b24 Stack: 0f20: 00000001 ada60fde 00000000 ada60fe4 ada60feb 00000000 00000021 3a038000 Stack: 0f40: 00000010 0009dc6f 00000006 00001000 00000011 00000064 00000003 00008034 Stack: 0f60: 00000004 00000020 00000005 00000008 00000007 3a000000 00000008 00000000 Stack: 0f80: 00000009 0000ebe0 0000000b 00000000 0000000c 00000000 0000000d 00000000 Stack: 0fa0: 0000000e 00000000 00000017 00000000 00000019 ada60fce 0000001f ada60ff6 Stack: 0fc0: 00000000 00000000 00000000 b5010000 fa839914 23b5dd89 a2aea540 692fc82e Stack: 0fe0: 0074696e 454d4f48 54002f3d 3d4d5245 756e696c 692f0078 0074696e 00000000 CPU: 0 PID: 1 Comm: init Tainted: G W 4.18.0-00015-g1888b64a2558-dirty #112 Hardware name: andestech,ae3xx (DT) Call Trace: [<b27a8e34>] dump_stack+0x2c/0x38 [<b2354874>] die+0x128/0x18c [<b2356f4c>] do_page_fault+0x3b8/0x4e0 [<b2352ed4>] ret_from_exception+0x0/0x10 [<b2352eba>] common_exception_handler+0xda/0xf4 Signed-off-by: Greentime Hu <greentime@andestech.com>
2018-08-23 01:05:46 -06:00
la $r10, __trace_hardirqs_off
la $r9, __trace_hardirqs_on
nds32: Exception handling This patch includes the exception/interrupt entries, pt_reg structure and related accessors. /* Unaligned accessing handling*/ Andes processors cannot load/store information which is not naturally aligned on the bus, i.e., loading a 4 byte data whose start address must be divisible by 4. If unaligned data accessing is happened, data unaligned exception will be triggered and user will get SIGSEGV or kernel oops according to the unaligned address. In order to make user be able to load/store data from an unaligned address, software load/store emulation is implemented in arch/nds32/mm/alignment.c to address data unaligned exception. Unaligned accessing handling is disabled by default because it is not a normal case. User can enable this feature by following steps. A. Compile time: 1. Enable kernel config CONFIG_ALIGNMENT_TRAP B. Run time: 1. Enter /proc/sys/nds32/unaligned_acess folder 2. Write 1 to file enable_mode to enable unaligned accessing handling. User can disable it by writing 0 to this file. 3. Write 1 to file debug to show which unaligned address is under processing. User can disable it by writing 0 to this file. However, unaligned accessing handler cannot work if this unaligned address is not accessible such as protection violation. On this condition, the default behaviors for addressing data unaligned exception still happen Signed-off-by: Vincent Chen <vincentc@andestech.com> Signed-off-by: Greentime Hu <greentime@andestech.com> Acked-by: Arnd Bergmann <arnd@arndb.de>
2017-10-24 00:42:02 -06:00
cmovz $r9, $p0, $r10
jral $r9
#endif
restore_user_regs ! return from iret
/*
* preemptive kernel
*/
#ifdef CONFIG_PREEMPT
resume_kernel:
gie_disable
lwi $t0, [tsk+#TSK_TI_PREEMPT]
bnez $t0, no_work_pending
nds32: Exception handling This patch includes the exception/interrupt entries, pt_reg structure and related accessors. /* Unaligned accessing handling*/ Andes processors cannot load/store information which is not naturally aligned on the bus, i.e., loading a 4 byte data whose start address must be divisible by 4. If unaligned data accessing is happened, data unaligned exception will be triggered and user will get SIGSEGV or kernel oops according to the unaligned address. In order to make user be able to load/store data from an unaligned address, software load/store emulation is implemented in arch/nds32/mm/alignment.c to address data unaligned exception. Unaligned accessing handling is disabled by default because it is not a normal case. User can enable this feature by following steps. A. Compile time: 1. Enable kernel config CONFIG_ALIGNMENT_TRAP B. Run time: 1. Enter /proc/sys/nds32/unaligned_acess folder 2. Write 1 to file enable_mode to enable unaligned accessing handling. User can disable it by writing 0 to this file. 3. Write 1 to file debug to show which unaligned address is under processing. User can disable it by writing 0 to this file. However, unaligned accessing handler cannot work if this unaligned address is not accessible such as protection violation. On this condition, the default behaviors for addressing data unaligned exception still happen Signed-off-by: Vincent Chen <vincentc@andestech.com> Signed-off-by: Greentime Hu <greentime@andestech.com> Acked-by: Arnd Bergmann <arnd@arndb.de>
2017-10-24 00:42:02 -06:00
lwi $t0, [tsk+#TSK_TI_FLAGS]
andi $p1, $t0, #_TIF_NEED_RESCHED
beqz $p1, no_work_pending
lwi $t0, [$sp+(#IPSW_OFFSET)] ! Interrupts off?
andi $t0, $t0, #1
beqz $t0, no_work_pending
jal preempt_schedule_irq
b no_work_pending
nds32: Exception handling This patch includes the exception/interrupt entries, pt_reg structure and related accessors. /* Unaligned accessing handling*/ Andes processors cannot load/store information which is not naturally aligned on the bus, i.e., loading a 4 byte data whose start address must be divisible by 4. If unaligned data accessing is happened, data unaligned exception will be triggered and user will get SIGSEGV or kernel oops according to the unaligned address. In order to make user be able to load/store data from an unaligned address, software load/store emulation is implemented in arch/nds32/mm/alignment.c to address data unaligned exception. Unaligned accessing handling is disabled by default because it is not a normal case. User can enable this feature by following steps. A. Compile time: 1. Enable kernel config CONFIG_ALIGNMENT_TRAP B. Run time: 1. Enter /proc/sys/nds32/unaligned_acess folder 2. Write 1 to file enable_mode to enable unaligned accessing handling. User can disable it by writing 0 to this file. 3. Write 1 to file debug to show which unaligned address is under processing. User can disable it by writing 0 to this file. However, unaligned accessing handler cannot work if this unaligned address is not accessible such as protection violation. On this condition, the default behaviors for addressing data unaligned exception still happen Signed-off-by: Vincent Chen <vincentc@andestech.com> Signed-off-by: Greentime Hu <greentime@andestech.com> Acked-by: Arnd Bergmann <arnd@arndb.de>
2017-10-24 00:42:02 -06:00
#endif
/*
* This is how we return from a fork.
*/
ENTRY(ret_from_fork)
bal schedule_tail
beqz $r6, 1f ! r6 stores fn for kernel thread
move $r0, $r7 ! prepare kernel thread arg
jral $r6
1:
lwi $r1, [tsk+#TSK_TI_FLAGS] ! check for syscall tracing
andi $p1, $r1, #_TIF_WORK_SYSCALL_LEAVE ! are we tracing syscalls?
beqz $p1, ret_slow_syscall
move $r0, $sp
bal syscall_trace_leave
b ret_slow_syscall