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 CF_MASK         = 0x00000001
  62 IF_MASK         = 0x00000200
  63 NT_MASK         = 0x00004000
  64 VM_MASK         = 0x00020000
  65 
  66 /*
  67  * these are offsets into the task-struct.
  68  */
  69 state           =  0
  70 counter         =  4
  71 priority        =  8
  72 signal          = 12
  73 blocked         = 16
  74 flags           = 20
  75 errno           = 24
  76 
  77 ENOSYS = 38
  78 
  79 .globl _system_call,_sys_execve
  80 .globl _device_not_available, _coprocessor_error
  81 .globl _divide_error,_debug,_nmi,_int3,_overflow,_bounds,_invalid_op
  82 .globl _double_fault,_coprocessor_segment_overrun
  83 .globl _invalid_TSS,_segment_not_present,_stack_segment
  84 .globl _general_protection,_reserved
  85 .globl _alignment_check,_page_fault
  86 .globl ret_from_sys_call
  87 
  88 #define SAVE_ALL \
  89         cld; \
  90         push %gs; \
  91         push %fs; \
  92         push %es; \
  93         push %ds; \
  94         pushl %eax; \
  95         pushl %ebp; \
  96         pushl %edi; \
  97         pushl %esi; \
  98         pushl %edx; \
  99         pushl %ecx; \
 100         pushl %ebx; \
 101         movl $0x10,%edx; \
 102         mov %dx,%ds; \
 103         mov %dx,%es; \
 104         movl $0x17,%edx; \
 105         mov %dx,%fs
 106 
 107 #define RESTORE_ALL \
 108         popl %ebx; \
 109         popl %ecx; \
 110         popl %edx; \
 111         popl %esi; \
 112         popl %edi; \
 113         popl %ebp; \
 114         popl %eax; \
 115         pop %ds; \
 116         pop %es; \
 117         pop %fs; \
 118         pop %gs; \
 119         addl $4,%esp; \
 120         iret
 121 
 122 .align 4
 123 reschedule:
 124         pushl $ret_from_sys_call
 125         jmp _schedule
 126 .align 4
 127 _system_call:
 128         pushl %eax                      # save orig_eax
 129         SAVE_ALL
 130         movl $-ENOSYS,EAX(%esp)
 131         cmpl _NR_syscalls,%eax
 132         jae ret_from_sys_call
 133         movl _current,%ebx
 134         movl $0,errno(%ebx)
 135         andl $~CF_MASK,EFLAGS(%esp)     # clear carry - assume no errors
 136         testl $0x20,flags(%ebx)         # PF_TRACESYS
 137         je 1f
 138         pushl $0
 139         pushl %ebx
 140         pushl $5                        # SIGTRAP
 141         call _send_sig
 142         addl $12,%esp
 143         call _schedule
 144         movl ORIG_EAX(%esp),%eax
 145 1:      call _sys_call_table(,%eax,4)
 146         movl %eax,EAX(%esp)             # save the return value
 147         movl _current,%eax
 148         movl errno(%eax),%edx
 149         negl %edx
 150         je 2f
 151         movl %edx,EAX(%esp)
 152         orl $CF_MASK,EFLAGS(%esp)       # set carry to indicate error
 153 2:      testl $0x20,flags(%eax)         # PF_TRACESYS
 154         je ret_from_sys_call
 155         cmpl $0,signal(%eax)
 156         jne ret_from_sys_call           # ptrace would clear signal
 157         pushl $0
 158         pushl %eax
 159         pushl $5                        # SIGTRAP
 160         call _send_sig
 161         addl $12,%esp
 162         call _schedule
 163         .align 4,0x90
 164 ret_from_sys_call:
 165         movl EFLAGS(%esp),%eax          # check VM86 flag: CS/SS are
 166         testl $VM_MASK,%eax             # different then
 167         jne 1f
 168         cmpw $0x0f,CS(%esp)             # was old code segment supervisor ?
 169         jne 2f
 170         cmpw $0x17,OLDSS(%esp)          # was stack segment = 0x17 ?
 171         jne 2f
 172 1:      sti                             # slow interrupts get here with interrupts disabled
 173         orl $IF_MASK,%eax               # these just try to make sure
 174         andl $~NT_MASK,%eax             # the program doesn't do anything
 175         movl %eax,EFLAGS(%esp)          # stupid
 176         cmpl $0,_need_resched
 177         jne reschedule
 178         movl _current,%eax
 179         cmpl _task,%eax                 # task[0] cannot have signals
 180         je 2f
 181         cmpl $0,state(%eax)             # state
 182         jne reschedule
 183         cmpl $0,counter(%eax)           # counter
 184         je reschedule
 185         movl blocked(%eax),%ecx
 186         movl %ecx,%ebx                  # save blocked in %ebx for signal handling
 187         notl %ecx
 188         andl signal(%eax),%ecx
 189         jne signal_return
 190 2:      RESTORE_ALL
 191 .align 4
 192 signal_return:
 193         movl %esp,%ecx
 194         pushl %ecx
 195         testl $VM_MASK,EFLAGS(%ecx)
 196         jne v86_signal_return
 197         pushl %ebx
 198         call _do_signal
 199         popl %ebx
 200         popl %ebx
 201         RESTORE_ALL
 202 .align 4
 203 v86_signal_return:
 204         call _save_v86_state
 205         movl %eax,%esp
 206         pushl %eax
 207         pushl %ebx
 208         call _do_signal
 209         popl %ebx
 210         popl %ebx
 211         RESTORE_ALL
 212 
 213 .align 4
 214 _sys_execve:
 215         lea (EIP+4)(%esp),%eax  # don't forget about the return address.
 216         pushl %eax
 217         call _do_execve
 218         addl $4,%esp
 219         ret
 220 
 221 .align 4
 222 _divide_error:
 223         pushl $0                # no error code
 224         pushl $_do_divide_error
 225 .align 4,0x90
 226 error_code:
 227         push %fs
 228         push %es
 229         push %ds
 230         pushl %eax
 231         pushl %ebp
 232         pushl %edi
 233         pushl %esi
 234         pushl %edx
 235         pushl %ecx
 236         pushl %ebx
 237         cld
 238         movl $-1, %eax
 239         xchgl %eax, ORIG_EAX(%esp)      # orig_eax (get the error code. )
 240         xorl %ebx,%ebx                  # zero ebx
 241         mov %gs,%bx                     # get the lower order bits of gs
 242         xchgl %ebx, GS(%esp)            # get the address and save gs.
 243         pushl %eax                      # push the error code
 244         lea 52(%esp),%edx
 245         pushl %edx
 246         movl $0x10,%edx
 247         mov %dx,%ds
 248         mov %dx,%es
 249         movl $0x17,%edx
 250         mov %dx,%fs
 251         call *%ebx
 252         addl $8,%esp
 253         jmp ret_from_sys_call
 254 
 255 .align 4
 256 _coprocessor_error:
 257         pushl $0
 258         pushl $_do_coprocessor_error
 259         jmp error_code
 260 
 261 .align 4
 262 _device_not_available:
 263         pushl $-1               # mark this as an int
 264         SAVE_ALL
 265         pushl $ret_from_sys_call
 266         clts                            # clear TS so that we can use math
 267         movl %cr0,%eax
 268         testl $0x4,%eax                 # EM (math emulation bit)
 269         je _math_state_restore
 270         pushl $0                # temporary storage for ORIG_EIP
 271         call _math_emulate
 272         addl $4,%esp
 273         ret
 274 
 275 .align 4
 276 _debug:
 277         pushl $0
 278         pushl $_do_debug
 279         jmp error_code
 280 
 281 .align 4
 282 _nmi:
 283         pushl $0
 284         pushl $_do_nmi
 285         jmp error_code
 286 
 287 .align 4
 288 _int3:
 289         pushl $0
 290         pushl $_do_int3
 291         jmp error_code
 292 
 293 .align 4
 294 _overflow:
 295         pushl $0
 296         pushl $_do_overflow
 297         jmp error_code
 298 
 299 .align 4
 300 _bounds:
 301         pushl $0
 302         pushl $_do_bounds
 303         jmp error_code
 304 
 305 .align 4
 306 _invalid_op:
 307         pushl $0
 308         pushl $_do_invalid_op
 309         jmp error_code
 310 
 311 .align 4
 312 _coprocessor_segment_overrun:
 313         pushl $0
 314         pushl $_do_coprocessor_segment_overrun
 315         jmp error_code
 316 
 317 .align 4
 318 _reserved:
 319         pushl $0
 320         pushl $_do_reserved
 321         jmp error_code
 322 
 323 .align 4
 324 _double_fault:
 325         pushl $_do_double_fault
 326         jmp error_code
 327 
 328 .align 4
 329 _invalid_TSS:
 330         pushl $_do_invalid_TSS
 331         jmp error_code
 332 
 333 .align 4
 334 _segment_not_present:
 335         pushl $_do_segment_not_present
 336         jmp error_code
 337 
 338 .align 4
 339 _stack_segment:
 340         pushl $_do_stack_segment
 341         jmp error_code
 342 
 343 .align 4
 344 _general_protection:
 345         pushl $_do_general_protection
 346         jmp error_code
 347 
 348 .align 4
 349 _alignment_check:
 350         pushl $_do_alignment_check
 351         jmp error_code
 352 
 353 .align 4
 354 _page_fault:
 355         pushl $_do_page_fault
 356         jmp error_code

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