root/kernel/sys_call.S

/* [previous][next][first][last][top][bottom][index][help] */
   1 /*
   2  *  linux/kernel/sys_call.S
   3  *
   4  *  Copyright (C) 1991, 1992  Linus Torvalds
   5  */
   6 
   7 /*
   8  * sys_call.S  contains the system-call and fault low-level handling routines.
   9  * This also contains the timer-interrupt handler, as well as all interrupts
  10  * and faults that can result in a task-switch.
  11  *
  12  * NOTE: This code handles signal-recognition, which happens every time
  13  * after a timer-interrupt and after each system call.
  14  *
  15  * I changed all the .align's to 4 (16 byte alignment), as that's faster
  16  * on a 486.
  17  *
  18  * Stack layout in 'ret_from_system_call':
  19  *      ptrace needs to have all regs on the stack.
  20  *      if the order here is changed, it needs to be 
  21  *      updated in fork.c:copy_process, signal.c:do_signal,
  22  *      ptrace.c and ptrace.h
  23  *
  24  *       0(%esp) - %ebx
  25  *       4(%esp) - %ecx
  26  *       8(%esp) - %edx
  27  *       C(%esp) - %esi
  28  *      10(%esp) - %edi
  29  *      14(%esp) - %ebp
  30  *      18(%esp) - %eax
  31  *      1C(%esp) - %ds
  32  *      20(%esp) - %es
  33  *      24(%esp) - %fs
  34  *      28(%esp) - %gs
  35  *      2C(%esp) - orig_eax
  36  *      30(%esp) - %eip
  37  *      34(%esp) - %cs
  38  *      38(%esp) - %eflags
  39  *      3C(%esp) - %oldesp
  40  *      40(%esp) - %oldss
  41  */
  42 
  43 EBX             = 0x00
  44 ECX             = 0x04
  45 EDX             = 0x08
  46 ESI             = 0x0C
  47 EDI             = 0x10
  48 EBP             = 0x14
  49 EAX             = 0x18
  50 DS              = 0x1C
  51 ES              = 0x20
  52 FS              = 0x24
  53 GS              = 0x28
  54 ORIG_EAX        = 0x2C
  55 EIP             = 0x30
  56 CS              = 0x34
  57 EFLAGS          = 0x38
  58 OLDESP          = 0x3C
  59 OLDSS           = 0x40
  60 
  61 IF_MASK         = 0x00000200
  62 NT_MASK         = 0x00004000
  63 VM_MASK         = 0x00020000
  64 
  65 /*
  66  * these are offsets into the task-struct.
  67  */
  68 state           =  0
  69 counter         =  4
  70 priority        =  8
  71 signal          = 12
  72 blocked         = 16
  73 flags           = 20
  74 
  75 ENOSYS = 38
  76 
  77 .globl _system_call,_sys_execve
  78 .globl _device_not_available, _coprocessor_error
  79 .globl _divide_error,_debug,_nmi,_int3,_overflow,_bounds,_invalid_op
  80 .globl _double_fault,_coprocessor_segment_overrun
  81 .globl _invalid_TSS,_segment_not_present,_stack_segment
  82 .globl _general_protection,_reserved
  83 .globl _alignment_check,_page_fault
  84 .globl ret_from_sys_call
  85 
  86 #define SAVE_ALL \
  87         cld; \
  88         push %gs; \
  89         push %fs; \
  90         push %es; \
  91         push %ds; \
  92         pushl %eax; \
  93         pushl %ebp; \
  94         pushl %edi; \
  95         pushl %esi; \
  96         pushl %edx; \
  97         pushl %ecx; \
  98         pushl %ebx; \
  99         movl $0x10,%edx; \
 100         mov %dx,%ds; \
 101         mov %dx,%es; \
 102         movl $0x17,%edx; \
 103         mov %dx,%fs
 104 
 105 #define RESTORE_ALL \
 106         popl %ebx; \
 107         popl %ecx; \
 108         popl %edx; \
 109         popl %esi; \
 110         popl %edi; \
 111         popl %ebp; \
 112         popl %eax; \
 113         pop %ds; \
 114         pop %es; \
 115         pop %fs; \
 116         pop %gs; \
 117         addl $4,%esp; \
 118         iret
 119 
 120 .align 4
 121 reschedule:
 122         pushl $ret_from_sys_call
 123         jmp _schedule
 124 .align 4
 125 _system_call:
 126         pushl %eax                      # save orig_eax
 127         SAVE_ALL
 128         movl $-ENOSYS,EAX(%esp)
 129         cmpl _NR_syscalls,%eax
 130         jae ret_from_sys_call
 131         movl _current,%ebx
 132         testl $0x20,flags(%ebx)         # PF_TRACESYS
 133         je 1f
 134         pushl $0
 135         pushl %ebx
 136         pushl $5                        # SIGTRAP
 137         call _send_sig
 138         addl $12,%esp
 139         call _schedule
 140         movl ORIG_EAX(%esp),%eax
 141 1:      call _sys_call_table(,%eax,4)
 142         movl %eax,EAX(%esp)             # save the return value
 143         movl _current,%eax
 144         testl $0x20,flags(%eax)         # PF_TRACESYS
 145         je ret_from_sys_call
 146         cmpl $0,signal(%eax)
 147         jne ret_from_sys_call           # ptrace would clear signal
 148         pushl $0
 149         pushl %eax
 150         pushl $5                        # SIGTRAP
 151         call _send_sig
 152         addl $12,%esp
 153         call _schedule
 154         .align 4,0x90
 155 ret_from_sys_call:
 156         movl EFLAGS(%esp),%eax          # check VM86 flag: CS/SS are
 157         testl $VM_MASK,%eax             # different then
 158         jne 1f
 159         cmpw $0x0f,CS(%esp)             # was old code segment supervisor ?
 160         jne 2f
 161         cmpw $0x17,OLDSS(%esp)          # was stack segment = 0x17 ?
 162         jne 2f
 163 1:      sti                             # slow interrupts get here with interrupts disabled
 164         orl $IF_MASK,%eax               # these just try to make sure
 165         andl $~NT_MASK,%eax             # the program doesn't do anything
 166         movl %eax,EFLAGS(%esp)          # stupid
 167         cmpl $0,_need_resched
 168         jne reschedule
 169         movl _current,%eax
 170         cmpl _task,%eax                 # task[0] cannot have signals
 171         je 2f
 172         cmpl $0,state(%eax)             # state
 173         jne reschedule
 174         cmpl $0,counter(%eax)           # counter
 175         je reschedule
 176         movl blocked(%eax),%ecx
 177         notl %ecx
 178         andl signal(%eax),%ecx
 179         jne signal_return
 180 2:      RESTORE_ALL
 181 .align 4
 182 signal_return:
 183         movl %esp,%ebx
 184         pushl %ebx
 185         testl $VM_MASK,EFLAGS(%ebx)
 186         jne v86_signal_return
 187         call _do_signal
 188         popl %ebx
 189         RESTORE_ALL
 190 .align 4
 191 v86_signal_return:
 192         call _save_v86_state
 193         movl %eax,%esp
 194         pushl %eax
 195         call _do_signal
 196         popl %ebx
 197         RESTORE_ALL
 198 
 199 .align 4
 200 _sys_execve:
 201         lea (EIP+4)(%esp),%eax  # don't forget about the return address.
 202         pushl %eax
 203         call _do_execve
 204         addl $4,%esp
 205         ret
 206 
 207 .align 4
 208 _divide_error:
 209         pushl $0                # no error code
 210         pushl $_do_divide_error
 211 .align 4,0x90
 212 error_code:
 213         push %fs
 214         push %es
 215         push %ds
 216         pushl %eax
 217         pushl %ebp
 218         pushl %edi
 219         pushl %esi
 220         pushl %edx
 221         pushl %ecx
 222         pushl %ebx
 223         cld
 224         movl $-1, %eax
 225         xchgl %eax, ORIG_EAX(%esp)      # orig_eax (get the error code. )
 226         xorl %ebx,%ebx                  # zero ebx
 227         mov %gs,%bx                     # get the lower order bits of gs
 228         xchgl %ebx, GS(%esp)            # get the address and save gs.
 229         pushl %eax                      # push the error code
 230         lea 52(%esp),%edx
 231         pushl %edx
 232         movl $0x10,%edx
 233         mov %dx,%ds
 234         mov %dx,%es
 235         movl $0x17,%edx
 236         mov %dx,%fs
 237         call *%ebx
 238         addl $8,%esp
 239         jmp ret_from_sys_call
 240 
 241 .align 4
 242 _coprocessor_error:
 243         pushl $0
 244         pushl $_do_coprocessor_error
 245         jmp error_code
 246 
 247 .align 4
 248 _device_not_available:
 249         pushl $-1               # mark this as an int
 250         SAVE_ALL
 251         pushl $ret_from_sys_call
 252         clts                            # clear TS so that we can use math
 253         movl %cr0,%eax
 254         testl $0x4,%eax                 # EM (math emulation bit)
 255         je _math_state_restore
 256         pushl $0                # temporary storage for ORIG_EIP
 257         call _math_emulate
 258         addl $4,%esp
 259         ret
 260 
 261 .align 4
 262 _debug:
 263         pushl $0
 264         pushl $_do_debug
 265         jmp error_code
 266 
 267 .align 4
 268 _nmi:
 269         pushl $0
 270         pushl $_do_nmi
 271         jmp error_code
 272 
 273 .align 4
 274 _int3:
 275         pushl $0
 276         pushl $_do_int3
 277         jmp error_code
 278 
 279 .align 4
 280 _overflow:
 281         pushl $0
 282         pushl $_do_overflow
 283         jmp error_code
 284 
 285 .align 4
 286 _bounds:
 287         pushl $0
 288         pushl $_do_bounds
 289         jmp error_code
 290 
 291 .align 4
 292 _invalid_op:
 293         pushl $0
 294         pushl $_do_invalid_op
 295         jmp error_code
 296 
 297 .align 4
 298 _coprocessor_segment_overrun:
 299         pushl $0
 300         pushl $_do_coprocessor_segment_overrun
 301         jmp error_code
 302 
 303 .align 4
 304 _reserved:
 305         pushl $0
 306         pushl $_do_reserved
 307         jmp error_code
 308 
 309 .align 4
 310 _double_fault:
 311         pushl $_do_double_fault
 312         jmp error_code
 313 
 314 .align 4
 315 _invalid_TSS:
 316         pushl $_do_invalid_TSS
 317         jmp error_code
 318 
 319 .align 4
 320 _segment_not_present:
 321         pushl $_do_segment_not_present
 322         jmp error_code
 323 
 324 .align 4
 325 _stack_segment:
 326         pushl $_do_stack_segment
 327         jmp error_code
 328 
 329 .align 4
 330 _general_protection:
 331         pushl $_do_general_protection
 332         jmp error_code
 333 
 334 .align 4
 335 _alignment_check:
 336         pushl $_do_alignment_check
 337         jmp error_code
 338 
 339 .align 4
 340 _page_fault:
 341         pushl $_do_page_fault
 342         jmp error_code

/* [previous][next][first][last][top][bottom][index][help] */