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         pushl blocked(%eax)
 188         call _do_signal
 189         popl %ebx
 190         popl %ebx
 191         RESTORE_ALL
 192 .align 4
 193 v86_signal_return:
 194         call _save_v86_state
 195         movl %eax,%esp
 196         pushl %eax
 197         pushl blocked(%eax)
 198         call _do_signal
 199         popl %ebx
 200         popl %ebx
 201         RESTORE_ALL
 202 
 203 .align 4
 204 _sys_execve:
 205         lea (EIP+4)(%esp),%eax  # don't forget about the return address.
 206         pushl %eax
 207         call _do_execve
 208         addl $4,%esp
 209         ret
 210 
 211 .align 4
 212 _divide_error:
 213         pushl $0                # no error code
 214         pushl $_do_divide_error
 215 .align 4,0x90
 216 error_code:
 217         push %fs
 218         push %es
 219         push %ds
 220         pushl %eax
 221         pushl %ebp
 222         pushl %edi
 223         pushl %esi
 224         pushl %edx
 225         pushl %ecx
 226         pushl %ebx
 227         cld
 228         movl $-1, %eax
 229         xchgl %eax, ORIG_EAX(%esp)      # orig_eax (get the error code. )
 230         xorl %ebx,%ebx                  # zero ebx
 231         mov %gs,%bx                     # get the lower order bits of gs
 232         xchgl %ebx, GS(%esp)            # get the address and save gs.
 233         pushl %eax                      # push the error code
 234         lea 52(%esp),%edx
 235         pushl %edx
 236         movl $0x10,%edx
 237         mov %dx,%ds
 238         mov %dx,%es
 239         movl $0x17,%edx
 240         mov %dx,%fs
 241         call *%ebx
 242         addl $8,%esp
 243         jmp ret_from_sys_call
 244 
 245 .align 4
 246 _coprocessor_error:
 247         pushl $0
 248         pushl $_do_coprocessor_error
 249         jmp error_code
 250 
 251 .align 4
 252 _device_not_available:
 253         pushl $-1               # mark this as an int
 254         SAVE_ALL
 255         pushl $ret_from_sys_call
 256         clts                            # clear TS so that we can use math
 257         movl %cr0,%eax
 258         testl $0x4,%eax                 # EM (math emulation bit)
 259         je _math_state_restore
 260         pushl $0                # temporary storage for ORIG_EIP
 261         call _math_emulate
 262         addl $4,%esp
 263         ret
 264 
 265 .align 4
 266 _debug:
 267         pushl $0
 268         pushl $_do_debug
 269         jmp error_code
 270 
 271 .align 4
 272 _nmi:
 273         pushl $0
 274         pushl $_do_nmi
 275         jmp error_code
 276 
 277 .align 4
 278 _int3:
 279         pushl $0
 280         pushl $_do_int3
 281         jmp error_code
 282 
 283 .align 4
 284 _overflow:
 285         pushl $0
 286         pushl $_do_overflow
 287         jmp error_code
 288 
 289 .align 4
 290 _bounds:
 291         pushl $0
 292         pushl $_do_bounds
 293         jmp error_code
 294 
 295 .align 4
 296 _invalid_op:
 297         pushl $0
 298         pushl $_do_invalid_op
 299         jmp error_code
 300 
 301 .align 4
 302 _coprocessor_segment_overrun:
 303         pushl $0
 304         pushl $_do_coprocessor_segment_overrun
 305         jmp error_code
 306 
 307 .align 4
 308 _reserved:
 309         pushl $0
 310         pushl $_do_reserved
 311         jmp error_code
 312 
 313 .align 4
 314 _double_fault:
 315         pushl $_do_double_fault
 316         jmp error_code
 317 
 318 .align 4
 319 _invalid_TSS:
 320         pushl $_do_invalid_TSS
 321         jmp error_code
 322 
 323 .align 4
 324 _segment_not_present:
 325         pushl $_do_segment_not_present
 326         jmp error_code
 327 
 328 .align 4
 329 _stack_segment:
 330         pushl $_do_stack_segment
 331         jmp error_code
 332 
 333 .align 4
 334 _general_protection:
 335         pushl $_do_general_protection
 336         jmp error_code
 337 
 338 .align 4
 339 _alignment_check:
 340         pushl $_do_alignment_check
 341         jmp error_code
 342 
 343 .align 4
 344 _page_fault:
 345         pushl $_do_page_fault
 346         jmp error_code

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