mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-30 23:54:04 +08:00
ARC: entry: rework (non-functional)
- comments update - rename syscall_trace_entry - use PT_xxx in entry code Signed-off-by: Vineet Gupta <vgupta@kernel.org>
This commit is contained in:
parent
fd476197c6
commit
c505b0da76
@ -48,14 +48,18 @@
|
|||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
.macro INTERRUPT_PROLOGUE
|
.macro INTERRUPT_PROLOGUE
|
||||||
|
|
||||||
; (A) Before jumping to Interrupt Vector, hardware micro-ops did following:
|
; Before jumping to Interrupt Vector, hardware micro-ops did following:
|
||||||
; 1. SP auto-switched to kernel mode stack
|
; 1. SP auto-switched to kernel mode stack
|
||||||
; 2. STATUS32.Z flag set if in U mode at time of interrupt (U:1,K:0)
|
; 2. STATUS32.Z flag set if in U mode at time of interrupt (U:1,K:0)
|
||||||
; 3. Auto save: (mandatory) Push PC and STAT32 on stack
|
; 3. Auto save: (mandatory) Push PC and STAT32 on stack
|
||||||
; hardware does even if CONFIG_ARC_IRQ_NO_AUTOSAVE
|
; hardware does even if CONFIG_ARC_IRQ_NO_AUTOSAVE
|
||||||
; 4. Auto save: (optional) r0-r11, blink, LPE,LPS,LPC, JLI,LDI,EI
|
; 4a. Auto save: (optional) r0-r11, blink, LPE,LPS,LPC, JLI,LDI,EI
|
||||||
;
|
;
|
||||||
; (B) Manually saved some regs: r12,r30, sp,fp,gp, ACCL pair
|
; Now
|
||||||
|
; 4b. If Auto-save (optional) not enabled in hw, manually save them
|
||||||
|
; 5. Manually save: r12,r30, sp,fp,gp, ACCL pair
|
||||||
|
;
|
||||||
|
; At the end, SP points to pt_regs
|
||||||
|
|
||||||
#ifdef CONFIG_ARC_IRQ_NO_AUTOSAVE
|
#ifdef CONFIG_ARC_IRQ_NO_AUTOSAVE
|
||||||
; carve pt_regs on stack (case #3), PC/STAT32 already on stack
|
; carve pt_regs on stack (case #3), PC/STAT32 already on stack
|
||||||
@ -73,13 +77,14 @@
|
|||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
.macro EXCEPTION_PROLOGUE
|
.macro EXCEPTION_PROLOGUE
|
||||||
|
|
||||||
; (A) Before jumping to Exception Vector, hardware micro-ops did following:
|
; Before jumping to Exception Vector, hardware micro-ops did following:
|
||||||
; 1. SP auto-switched to kernel mode stack
|
; 1. SP auto-switched to kernel mode stack
|
||||||
; 2. STATUS32.Z flag set if in U mode at time of exception (U:1,K:0)
|
; 2. STATUS32.Z flag set if in U mode at time of exception (U:1,K:0)
|
||||||
;
|
;
|
||||||
; (B) Manually save the complete reg file below
|
; Now manually save rest of reg file
|
||||||
|
; At the end, SP points to pt_regs
|
||||||
|
|
||||||
sub sp, sp, SZ_PT_REGS ; carve pt_regs
|
sub sp, sp, SZ_PT_REGS ; carve space for pt_regs
|
||||||
|
|
||||||
; _HARD saves r10 clobbered by _SOFT as scratch hence comes first
|
; _HARD saves r10 clobbered by _SOFT as scratch hence comes first
|
||||||
|
|
||||||
@ -136,8 +141,8 @@
|
|||||||
|
|
||||||
ST2 gp, fp, PT_r26 ; gp (r26), fp (r27)
|
ST2 gp, fp, PT_r26 ; gp (r26), fp (r27)
|
||||||
|
|
||||||
st r12, [sp, PT_sp + 4]
|
st r12, [sp, PT_r12]
|
||||||
st r30, [sp, PT_sp + 8]
|
st r30, [sp, PT_r30]
|
||||||
|
|
||||||
; Saving pt_regs->sp correctly requires some extra work due to the way
|
; Saving pt_regs->sp correctly requires some extra work due to the way
|
||||||
; Auto stack switch works
|
; Auto stack switch works
|
||||||
@ -244,7 +249,7 @@
|
|||||||
|
|
||||||
btst r0, STATUS_U_BIT ; Z flag set if K, used in restoring SP
|
btst r0, STATUS_U_BIT ; Z flag set if K, used in restoring SP
|
||||||
|
|
||||||
ld r10, [sp, PT_event + 4]
|
ld r10, [sp, PT_bta]
|
||||||
sr r10, [erbta]
|
sr r10, [erbta]
|
||||||
|
|
||||||
LD2 r10, r11, PT_ret
|
LD2 r10, r11, PT_ret
|
||||||
|
@ -170,12 +170,13 @@
|
|||||||
PUSHAX erbta
|
PUSHAX erbta
|
||||||
|
|
||||||
lr r10, [ecr]
|
lr r10, [ecr]
|
||||||
st r10, [sp, PT_event] /* EV_Trap expects r10 to have ECR */
|
st r10, [sp, PT_event]
|
||||||
|
|
||||||
#ifdef CONFIG_ARC_CURR_IN_REG
|
#ifdef CONFIG_ARC_CURR_IN_REG
|
||||||
/* gp already saved on stack: now load with "current" */
|
/* gp already saved on stack: now load with "current" */
|
||||||
GET_CURR_TASK_ON_CPU gp
|
GET_CURR_TASK_ON_CPU gp
|
||||||
#endif
|
#endif
|
||||||
|
; OUTPUT: r10 has ECR expected by EV_Trap
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
/*--------------------------------------------------------------
|
/*--------------------------------------------------------------
|
||||||
|
@ -75,7 +75,7 @@ struct pt_regs {
|
|||||||
unsigned long event;
|
unsigned long event;
|
||||||
};
|
};
|
||||||
|
|
||||||
unsigned long bta; /* bta_l1, bta_l2, erbta */
|
unsigned long bta; /* erbta */
|
||||||
|
|
||||||
unsigned long r26; /* gp */
|
unsigned long r26; /* gp */
|
||||||
unsigned long fp;
|
unsigned long fp;
|
||||||
|
@ -47,6 +47,7 @@ int main(void)
|
|||||||
|
|
||||||
DEFINE(PT_status32, offsetof(struct pt_regs, status32));
|
DEFINE(PT_status32, offsetof(struct pt_regs, status32));
|
||||||
DEFINE(PT_event, offsetof(struct pt_regs, event));
|
DEFINE(PT_event, offsetof(struct pt_regs, event));
|
||||||
|
DEFINE(PT_bta, offsetof(struct pt_regs, bta));
|
||||||
DEFINE(PT_sp, offsetof(struct pt_regs, sp));
|
DEFINE(PT_sp, offsetof(struct pt_regs, sp));
|
||||||
DEFINE(PT_r0, offsetof(struct pt_regs, r0));
|
DEFINE(PT_r0, offsetof(struct pt_regs, r0));
|
||||||
DEFINE(PT_r1, offsetof(struct pt_regs, r1));
|
DEFINE(PT_r1, offsetof(struct pt_regs, r1));
|
||||||
|
@ -160,20 +160,19 @@ END(EV_Extension)
|
|||||||
; syscall Tracing
|
; syscall Tracing
|
||||||
; ---------------------------------------------
|
; ---------------------------------------------
|
||||||
tracesys:
|
tracesys:
|
||||||
; save EFA in case tracer wants the PC of traced task
|
; safekeep EFA (r12) if syscall tracer wanted PC
|
||||||
; using ERET won't work since next-PC has already committed
|
; for traps, ERET is pre-commit so points to next-PC
|
||||||
GET_CURR_TASK_FIELD_PTR TASK_THREAD, r11
|
GET_CURR_TASK_FIELD_PTR TASK_THREAD, r11
|
||||||
st r12, [r11, THREAD_FAULT_ADDR] ; thread.fault_address
|
st r12, [r11, THREAD_FAULT_ADDR] ; thread.fault_address
|
||||||
|
|
||||||
; PRE Sys Call Ptrace hook
|
; PRE syscall trace hook
|
||||||
mov r0, sp ; pt_regs needed
|
mov r0, sp ; pt_regs
|
||||||
bl @syscall_trace_entry
|
bl @syscall_trace_enter
|
||||||
|
|
||||||
; Tracing code now returns the syscall num (orig or modif)
|
; Tracing code now returns the syscall num (orig or modif)
|
||||||
mov r8, r0
|
mov r8, r0
|
||||||
|
|
||||||
; Do the Sys Call as we normally would.
|
; Do the Sys Call as we normally would.
|
||||||
; Validate the Sys Call number
|
|
||||||
cmp r8, NR_syscalls - 1
|
cmp r8, NR_syscalls - 1
|
||||||
mov.hi r0, -ENOSYS
|
mov.hi r0, -ENOSYS
|
||||||
bhi tracesys_exit
|
bhi tracesys_exit
|
||||||
@ -190,36 +189,36 @@ tracesys:
|
|||||||
ld r6, [sp, PT_r6]
|
ld r6, [sp, PT_r6]
|
||||||
ld r7, [sp, PT_r7]
|
ld r7, [sp, PT_r7]
|
||||||
ld.as r9, [sys_call_table, r8]
|
ld.as r9, [sys_call_table, r8]
|
||||||
jl [r9] ; Entry into Sys Call Handler
|
jl [r9]
|
||||||
|
|
||||||
tracesys_exit:
|
tracesys_exit:
|
||||||
st r0, [sp, PT_r0] ; sys call return value in pt_regs
|
st r0, [sp, PT_r0]
|
||||||
|
|
||||||
;POST Sys Call Ptrace Hook
|
; POST syscall trace hook
|
||||||
mov r0, sp ; pt_regs needed
|
mov r0, sp ; pt_regs needed
|
||||||
bl @syscall_trace_exit
|
bl @syscall_trace_exit
|
||||||
b ret_from_exception ; NOT ret_from_system_call at is saves r0 which
|
|
||||||
; we'd done before calling post hook above
|
; don't call ret_from_system_call as it saves r0, already done above
|
||||||
|
b ret_from_exception
|
||||||
|
|
||||||
; ---------------------------------------------
|
; ---------------------------------------------
|
||||||
; Breakpoint TRAP
|
; Breakpoint TRAP
|
||||||
; ---------------------------------------------
|
; ---------------------------------------------
|
||||||
trap_with_param:
|
trap_with_param:
|
||||||
mov r0, r12 ; EFA in case ptracer/gdb wants stop_pc
|
mov r0, r12 ; EFA in case ptracer/gdb wants stop_pc
|
||||||
mov r1, sp
|
mov r1, sp ; pt_regs
|
||||||
|
|
||||||
; Save callee regs in case gdb wants to have a look
|
; save callee regs in case tracer/gdb wants to peek
|
||||||
; SP will grow up by size of CALLEE Reg-File
|
|
||||||
SAVE_CALLEE_SAVED_USER
|
SAVE_CALLEE_SAVED_USER
|
||||||
|
|
||||||
; save location of saved Callee Regs @ thread_struct->pc
|
; safekeep ref to callee regs
|
||||||
GET_CURR_TASK_FIELD_PTR TASK_THREAD, r10
|
GET_CURR_TASK_FIELD_PTR TASK_THREAD, r10
|
||||||
st sp, [r10, THREAD_CALLEE_REG]
|
st sp, [r10, THREAD_CALLEE_REG]
|
||||||
|
|
||||||
; Call the trap handler
|
; call the non syscall trap handler
|
||||||
bl do_non_swi_trap
|
bl do_non_swi_trap
|
||||||
|
|
||||||
; unwind stack to discard Callee saved Regs
|
; unwind stack to discard callee regs
|
||||||
DISCARD_CALLEE_SAVED_USER
|
DISCARD_CALLEE_SAVED_USER
|
||||||
|
|
||||||
b ret_from_exception
|
b ret_from_exception
|
||||||
@ -237,31 +236,27 @@ ENTRY(EV_Trap)
|
|||||||
|
|
||||||
FAKE_RET_FROM_EXCPN
|
FAKE_RET_FROM_EXCPN
|
||||||
|
|
||||||
;============ TRAP 1 :breakpoints
|
;============ TRAP N : breakpoints, kprobes etc
|
||||||
; Check ECR for trap with arg (PROLOGUE ensures r10 has ECR)
|
|
||||||
bmsk.f 0, r10, 7
|
bmsk.f 0, r10, 7
|
||||||
bnz trap_with_param
|
bnz trap_with_param
|
||||||
|
|
||||||
;============ TRAP (no param): syscall top level
|
;============ TRAP 0 (no param): syscall
|
||||||
|
|
||||||
; If syscall tracing ongoing, invoke pre-post-hooks
|
; syscall tracing ongoing, invoke pre-post-hooks around syscall
|
||||||
GET_CURR_THR_INFO_FLAGS r10
|
GET_CURR_THR_INFO_FLAGS r10
|
||||||
and.f 0, r10, _TIF_SYSCALL_WORK
|
and.f 0, r10, _TIF_SYSCALL_WORK
|
||||||
bnz tracesys ; this never comes back
|
bnz tracesys ; this never comes back
|
||||||
|
|
||||||
;============ Normal syscall case
|
;============ Normal syscall case
|
||||||
|
|
||||||
; syscall num shd not exceed the total system calls avail
|
|
||||||
cmp r8, NR_syscalls - 1
|
cmp r8, NR_syscalls - 1
|
||||||
mov.hi r0, -ENOSYS
|
mov.hi r0, -ENOSYS
|
||||||
bhi .Lret_from_system_call
|
bhi .Lret_from_system_call
|
||||||
|
|
||||||
; Offset into the syscall_table and call handler
|
|
||||||
ld.as r9,[sys_call_table, r8]
|
ld.as r9,[sys_call_table, r8]
|
||||||
jl [r9] ; Entry into Sys Call Handler
|
jl [r9]
|
||||||
|
|
||||||
.Lret_from_system_call:
|
.Lret_from_system_call:
|
||||||
|
|
||||||
st r0, [sp, PT_r0] ; sys call return value in pt_regs
|
st r0, [sp, PT_r0] ; sys call return value in pt_regs
|
||||||
|
|
||||||
; fall through to ret_from_exception
|
; fall through to ret_from_exception
|
||||||
|
@ -339,7 +339,7 @@ long arch_ptrace(struct task_struct *child, long request,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
asmlinkage int syscall_trace_entry(struct pt_regs *regs)
|
asmlinkage int syscall_trace_enter(struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
if (test_thread_flag(TIF_SYSCALL_TRACE))
|
if (test_thread_flag(TIF_SYSCALL_TRACE))
|
||||||
if (ptrace_report_syscall_entry(regs))
|
if (ptrace_report_syscall_entry(regs))
|
||||||
|
Loading…
Reference in New Issue
Block a user