mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-28 11:18:45 +07:00
0cde56e028
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>
185 lines
3.7 KiB
ArmAsm
185 lines
3.7 KiB
ArmAsm
// 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>
|
|
|
|
|
|
|
|
#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
|
|
|
|
addi $sp, $sp, FUCOP_CTL_OFFSET
|
|
|
|
lmw.adm $r12, [$sp], $r24, #0x0
|
|
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
|
|
la $r10, __trace_hardirqs_off
|
|
la $r9, __trace_hardirqs_on
|
|
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
|
|
need_resched:
|
|
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 need_resched
|
|
#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
|