保护linux系统调用,Linux软中断与系统调用

1. SWI软中断

以ARMV7 A/R架构为例, SWI软中断和中断一样,内核空间处理始于异常向量表。Linux向量表默认地址0XFFFF0000,SWI向量偏移8字节为0xFFFF0008:

d6d18f73d6d8a19e66e88b2d5254cc9b.png

具体代码,位于 \linux-3.4.x\arch\arm\kernel\entry-armv.S:

__vectors_start:

ARM( swi SYS_ERROR0 )

THUMB( svc #0)

THUMB( nop )

W(b) vector_und+stubs_offset

W(ldr) pc, .LCvswi+stubs_offset

W(b) vector_pabt+stubs_offset

W(b) vector_dabt+stubs_offset

W(b) vector_addrexcptn+stubs_offset

W(b) vector_irq+stubs_offset

W(b) vector_fiq+stubs_offset

.globl __vectors_end

__vectors_end:

.LCvswi:

.word vector_swi

vector_swi的具体实现,位于 linux_plat\base\linux\linux-3.4.x\arch\arm\kernel\entry-common.S:

1 ENTRY(vector_swi)2 sub sp, sp, #S_FRAME_SIZE3 stmia sp, {r0 - r12} @ Calling r0 -r124 ARM( add r8, sp, #S_PC )5 ARM( stmdb r8, {sp, lr}^) @ Calling sp, lr6 THUMB( mov r8, sp )7 THUMB( store_user_sp_lr r8, r10, S_SP ) @ calling sp, lr8 mrs r8, spsr @ called from non-FIQ mode, so ok.9 str lr, [sp, #S_PC] @ Save calling PC10 str r8, [sp, #S_PSR] @ Save CPSR11 str r0, [sp, #S_OLD_R0] @ Save OLD_R012 zero_fp13

14 /*

15 * Get the system call number.16 */

17

18 #if defined(CONFIG_OABI_COMPAT)

19

20 /*

21 * If we have CONFIG_OABI_COMPAT then we need to look at the swi22 * value to determine if it is an EABI or an old ABI call.23 */

24 #ifdef CONFIG_ARM_THUMB25 tst r8, #PSR_T_BIT26 movne r10, #0@ no thumb OABI emulation27 ldreq r10, [lr, #-4] @ getSWI instruction28 #else

29 ldr r10, [lr, #-4] @ getSWI instruction30 A710( and ip, r10, #0x0f000000 @ check forSWI )31 A710( teq ip, #0x0f000000)32 A710( bne .Larm710bug )33 #endif

34 #ifdef CONFIG_CPU_ENDIAN_BE835 rev r10, r10 @ little endian instruction36 #endif

37

38 #elif defined(CONFIG_AEABI)

39

40 /*

41 * Pure EABI user space always put syscall number into scno (r7).42 */

43 A710( ldr ip, [lr, #-4] @ getSWI instruction )44 A710( and ip, ip, #0x0f000000 @ check forSWI )45 A710( teq ip, #0x0f000000)46 A710( bne .Larm710bug )47

48 #elif defined(CONFIG_ARM_THUMB)

49

50 /*Legacy ABI only, possibly thumb mode.*/

51 tst r8, #PSR_T_BIT @ this is SPSR fromsave_user_regs52 addne scno, r7, #__NR_SYSCALL_BASE @ put OS number in

53 ldreq scno, [lr, #-4]54

55 #else

56

57 /*Legacy ABI only.*/

58 ldr scno, [lr, #-4] @ getSWI instruction59 A710( and ip, scno, #0x0f000000 @ check forSWI )60 A710( teq ip, #0x0f000000)61 A710( bne .Larm710bug )62

63 #endif

64

65 #ifdef CONFIG_ALIGNMENT_TRAP66 ldr ip, __cr_alignment67 ldr ip, [ip]68 mcr p15, 0, ip, c1, c0 @ update control register69 #endif

70 enable_irq71

72 get_thread_info tsk73 adr tbl, sys_call_table @ load syscall table pointer74

75 #if defined(CONFIG_OABI_COMPAT)

76 /*

77 * If the swi argument is zero, this is an EABI call and we do nothing.78 *79 * If this is an old ABI call, get the syscall number into scno and80 * get the old ABI syscall table address.81 */

82 bics r10, r10, #0xff000000

83 eorne scno, r10, #__NR_OABI_SYSCALL_BASE84 ldrne tbl, =sys_oabi_call_table85 #elif !defined(CONFIG_AEABI)

86 bic scno, scno, #0xff000000 @ mask off SWI op-code87 eor scno, scno, #__NR_SYSCALL_BASE @ check OS number88 #endif

89

90 ldr r10, [tsk, #TI_FLAGS] @ check forsyscall tracing91 stmdb sp!, {r4, r5} @ push fifth and sixth args92

93 #ifdef CONFIG_SECCOMP94 tst r10, #_TIF_SECCOMP95 beq 1f96 mov r0, scno97 bl __secure_computing98 add r0, sp, #S_R0 +S_OFF @ pointer to regs99 ldmia r0, {r0 - r3} @ have to reload r0 -r3100 1:101 #endif

102

103 tst r10, #_TIF_SYSCALL_WORK @ are we tracing syscalls?

104 bne __sys_trace105

106 cmp scno, #NR_syscalls @ check upper syscall limit107 adr lr, BSYM(ret_fast_syscall) @ returnaddress108 ldrcc pc, [tbl, scno, lsl #2] @ call sys_*routine109

110 add r1, sp, #S_OFF111 2: mov why, #0@ no longer a real syscall112 cmp scno, #(__ARM_NR_BASE -__NR_SYSCALL_BASE)113 eor r0, scno, #__NR_SYSCALL_BASE @ put OS number back114 bcs arm_syscall115 b sys_ni_syscall @ not privatefunc116 ENDPROC(vector_swi)

这个vector_swi函数完成的工作:

1. 保护异常前的现场

保存现场大小为S_FRAME_SIZE,大小是一个完整的寄存器栈帧:

DEFINE(S_FRAME_SIZE, sizeof(structpt_regs));structpt_regs {long uregs[18];

};

#define ARM_cpsr uregs[16]

#define ARM_pc  uregs[15]

#define ARM_lr  uregs[14]

#define ARM_sp  uregs[13]

#define ARM_ip  uregs[12]

#define ARM_fp  uregs[11]

#define ARM_r10  uregs[10]

#define ARM_r9  uregs[9]

#define ARM_r8  uregs[8]

#define ARM_r7  uregs[7]

#define ARM_r6  uregs[6]

#define ARM_r5  uregs[5]

#define ARM_r4  uregs[4]

#define ARM_r3  uregs[3]

#define ARM_r2  uregs[2]

#define ARM_r1  uregs[1]

#define ARM_r0  uregs[0]

#define ARM_ORIG_r0 uregs[17]

从现场可以看出,每次用户空间向内核空间切换时,线程内核栈会保留一份完整的寄存器现场,保存地址在内核栈的(最高地址-8):

线程内核栈基地址:0xc288a000

线程内核栈最高地址:0xc288a000+8k = 0xc288c000

保存形式:

=============================低地址

R0        R1           R2          R3

R4        R5           R6          R7

R8        R9           R10        R11

R12       SP           LR         PC

CPSR   R0_OLD    X          X

========================== kernel stack start(最高地址)

3fbb058d6976f534d934106a1f1770f4.png

#define THREAD_SIZE 8192

#define THREAD_START_SP (THREAD_SIZE - 8)

原文:https://www.cnblogs.com/DF11G/p/10172520.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值