/[lkdp]/lkdp/pm/signal.tex
ViewVC logotype

Diff of /lkdp/pm/signal.tex

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.1 by nayaniabhishek, Tue Nov 5 19:35:42 2002 UTC revision 1.2 by kdlinux2001, Thu Nov 21 13:08:15 2002 UTC
# Line 1  Line 1 
1  \chapter{System calls \& Signals}  \chapter{System calls \& Signals}
2    
3          \section{User to Kernel space using system\_call()}          \section{User to Kernel space}
4    
5          System calls are used to perform "low-level" operations on the system. System calls are the bridges between user space and kernel space. So it is the bridge between a user application and the system hardware.               System calls are used to perform "low-level" operations on the system. System calls are the bridges between user space and kernel space. So it is the bridge between a user application and the system hardware.
6          \par Each system call has its own unique identifying number. The kernel uses this number as an index into a table of system call entry points, which point to where the system calls reside in memory along with the number of arguments that should be passed to them. The system calls are defined in the file \url{include/asm-i386/unistd.h}          \par Each system call \footnote{System calls are defined in \url{include/asm-i386/unistd.h}} has its own unique identifying number. The kernel uses this number as an index into a table of system call entry points, which point to where the system calls reside in memory along with the number of arguments that should be passed to them.
7          When a process makes a system call, the behavior is similar to that with interrupts and exceptions. Like exception handling, the general purpose registers and the number of the system call are pushed onto the stack. And, the system call handler is invoked, which calls the routine within the kernel that will do the actual work.          \par When a process makes a system call, the behavior is similar to that with interrupts and exceptions. Like exception handling, the general purpose registers and the number of the system call are pushed onto the stack. And, the system call handler is invoked, which calls the routine within the kernel that will do the actual work.
8          When a user mode program invokes a system call, the libc library transfers control to kernel mode using software interrupt 0x80 registered during IRQ initialization \footnote{set\_system\_gate(SYSCALL\_VECTOR,\&system\_call); in trap\_init() in \url{arch/i386/kernel/traps.c}} and the kernel executes the system call related function. The system call within the kernel is its counterpart in user space prefixed by sys. So, when user calls fork/clone/vfork, kernel executes sys\_fork/sys\_clone/sys\_vfork function. Since, the system call is invoked from user space in order to enter kernel space,it has to pass through the call gate \footnote{Call gates are used to change priviledge level to perform priviledged operatios. Refer ~\ref{Appendix 2}.} to ensure that user code moves up to the higher privilege level at a specific location within the kernel.          \par When a user mode program invokes a system call, the libc library transfers control to kernel mode using software interrupt 0x80 registered during IRQ initialization \footnote{set\_system\_gate(SYSCALL\_VECTOR,\&system\_call); in trap\_init() in \url{arch/i386/kernel/traps.c}} and the kernel executes the system call related function. The system call within the kernel is its counterpart in user space prefixed by sys. So, when user calls fork/clone/vfork, kernel executes sys\_fork/sys\_clone/sys\_vfork function. Since, the system call is invoked from user space in order to enter kernel space,it has to pass through the call gate \footnote{Call gates are used to change priviledge level to perform priviledged operatios. Refer appendix ~\ref{appendix B}.} to ensure that user code moves up to the higher privilege level at a specific location within the kernel.
9          The system\_call code and the sys\_call\_table is defined in the asm code \url{arch/i386/kernel/entry.S}          \subsection{sys\_call\_table} \index{sys\_call\_table}
10            The \textit{system\_call} code and the \textit{sys\_call\_table} is defined in the asm code \url{arch/i386/kernel/entry.S}
11          % TODO explain code          % TODO explain code
12          \begin{verbatim}          \begin{verbatim}
13    
14          ENTRY(system_call)      # LINE : 230          ENTRY(system_call)      # LINE : 230
15              pushl %eax          # save orig_eax              pushl %eax          # save orig_eax
16              SAVE_ALL              SAVE_ALL
# Line 30  Line 32 
32              jne syscall_exit_work              jne syscall_exit_work
33          restore_all:          restore_all:
34                  RESTORE_ALL                  RESTORE_ALL
35    
36          \end{verbatim}          \end{verbatim}
37          % TODO examples , fork -> sys_fork          % TODO examples , fork -> sys_fork
38    
39          \par Scheduling is performed during a system call, to check if any interrupts, signals are missed.          \par Scheduling is performed during a system call, to check if any interrupts, signals are missed.
40    
41            % TODO explain
42    
43          \begin{verbatim}          \begin{verbatim}
44    
45              ALIGN              ALIGN
46          work_pending:          work_pending:
47              testb $_TIF_NEED_RESCHED, %cl              testb $_TIF_NEED_RESCHED, %cl
# Line 50  Line 57 
57              jz restore_all              jz restore_all
58              testb $_TIF_NEED_RESCHED, %cl              testb $_TIF_NEED_RESCHED, %cl
59              jnz work_resched              jnz work_resched
60    
61          \end{verbatim}          \end{verbatim}
62    
63          \par When the system call is invoked , the call number is stored in \textit{\%eax register} and the system call handler is picked from the system\_call\_table as defined below.          \par When the system call is invoked , the call number is stored in \textit{\%eax register} and the system call handler is picked from the system\_call\_table as defined below.
64          \begin{verbatim}          \begin{verbatim}
65    
66          .data          .data
67          ENTRY(sys_call_table)          ENTRY(sys_call_table)
68              .long sys_ni_syscall    /* 0 - old "setup()" system call*/              .long sys_ni_syscall    /* 0 - old "setup()" system call*/
# Line 69  Line 78 
78              .rept NR_syscalls-(.-sys_call_table)/4              .rept NR_syscalls-(.-sys_call_table)/4
79                   .long sys_ni_syscall                   .long sys_ni_syscall
80              .endr              .endr
81    
82          \end{verbatim}          \end{verbatim}
83    
84          \section{Signal data structure in a process}          \section{Signal data structure in a process} \label{sig:structs}
85          A  Signal is an asynchronous notification to an application, by the kernel.The application can override default actions for signals, by specifying handlers to be invoked on signal occurences. But, only certain signals can be overridden.          A  Signal is an asynchronous notification to an application, by the kernel.The application can override default actions for signals, by specifying handlers to be invoked on signal occurences. But, only certain signals can be overridden.
86          Signals can only be processed when the process is in user mode. If a signal has been sent to a process that is in kernel mode, it is dealt with immediately on returning to user mode.Since, signals are received by user processes and the signal handlers also represents a thread of execution in user space, they can do anything bounded by user privileges. e.g. open/close files, invoke sytstem calls etc.          \par Signals can only be processed when the process is in user mode. If a signal has been sent to a process that is in kernel mode, it is dealt with immediately on returning to user mode.Since, signals are received by user processes and the signal handlers also represents a thread of execution in user space, they can do anything bounded by user privileges. e.g. open/close files, invoke sytstem calls etc.
87          The process structure [task\_struct] contains following structures related to signals. These are described below, in details.          \subsection{signals in task\_struct}
88            \par The process structure \textit{[task\_struct]} contains following structures related to signals. These are described below, in details.
89    
90          \begin{verbatim}          \begin{verbatim}
91          /* signal handlers */  
92                 /* signal handlers */
93              spinlock_t sigmask_lock;        /* Protects signal and blocked */              spinlock_t sigmask_lock;        /* Protects signal and blocked */
94              struct signal_struct *sig;      /* signal structure */              struct signal_struct *sig;      /* signal structure */
95    
# Line 89  Line 101 
101              int (*notifier)(void *priv);              int (*notifier)(void *priv);
102              void *notifier_data;              void *notifier_data;
103              sigset_t *notifier_mask;        /* new signal notification bit mask */              sigset_t *notifier_mask;        /* new signal notification bit mask */
104    
105          \end{verbatim}          \end{verbatim}
106    
107          The signal\_struct is a generic signal structure defined in \url{include/linux/sched.h}. This contains the singal count per process and the spin-lock to protect the signals over multiple CPUs. It also contains an array of size \_NSIG \footnote{NSIG is the maximum number of singals supported.} and of type k\_sigaction defined below.          \subsection{signal\_struct} \index{signal\_struct}
108            The \textit{signal\_struct} is a generic signal structure defined in \url{include/linux/sched.h}. This contains the signal count per process and the spin-lock to protect the signals over multiple CPUs. It also contains an array of size \textit{\_NSIG} \footnote{NSIG is the maximum number of signals supported.} and of type \textit{k\_sigaction} defined below. This array defines the actions to be taken upon receiving any of the \_NSIG [NSIG = 64] signals.
109          \begin{verbatim}          \begin{verbatim}
110    
111          struct signal_struct {          struct signal_struct {
112              atomic_t                count;              atomic_t                count;
113              struct k_sigaction      action[_NSIG];              struct k_sigaction      action[_NSIG];
114              spinlock_t              siglock;              spinlock_t              siglock;
115          };          };
116    
117            struct k_sigaction {
118                struct sigaction sa;
119            };
120    
121          \end{verbatim}          \end{verbatim}
122    
123          The sigset\_t contains a bitmask of 2 words (64 bits), with each bit per signal. This bitmask can be used to check whether any signals are pending for a process or any new signals have arrived. Bit0 corresponds to signal0 and running upwards. An important thing to note here, is that all 64 signals are only available in kernel mode signal handling. At user level, only 32 signals can be handled.          \subsection{sigset\_t and struct sigaction}
124            The \textit{sigset\_t} contains a bitmask of 2 words (64 bits), with each bit per signal. This bitmask can be used to check whether any signals are pending for a process or any new signals have arrived. Bit0 corresponds to signal0 and running upwards. An important thing to note here, is that all 64 signals are only available in kernel mode signal handling. At user level, only 32 signals can be handled. Earlier versions of linux used to support only 32 signals in kernel space also. As as result of this, we have oldsigset\_t structure defined in kernel. As a result of this, we also have struct sigaction and struct old\_sigaction defined in \url{include/asm-i386/signal.h}, which differ only in the sigset\_t field. These sigaction structures are used by signal and sigaction system calls explained in section ~\ref{sig:regi}.
125    
126          \begin{verbatim}          \begin{verbatim}
127    
# Line 111  Line 132 
132              #define _NSIG           64              #define _NSIG           64
133              #define _NSIG_BPW       32              #define _NSIG_BPW       32
134              #define _NSIG_WORDS     (_NSIG / _NSIG_BPW)              #define _NSIG_WORDS     (_NSIG / _NSIG_BPW)
135    
136            typedef unsigned long old_sigset_t;
137    
138          #else          #else
139    
140              #define NSIG            32              #define NSIG            32
# Line 118  Line 142 
142    
143          #endif          #endif
144    
145            struct sigaction {
146                __sighandler_t sa_handler;
147                unsigned long sa_flags;
148                void (*sa_restorer)(void);
149                sigset_t sa_mask;       /* mask last for extensibility */
150            };
151    
152          \end{verbatim}          \end{verbatim}
153    
154            \subsection{struct sigpending}
155          The list of pending signals is maintained as circular linked list with header node and reference to tail node. The sigqueue structure contains the \textit{siginfo\_t} structure along with a bitmask.          The list of pending signals is maintained as circular linked list with header node and reference to tail node. The sigqueue structure contains the \textit{siginfo\_t} structure along with a bitmask.
156          \begin{verbatim}          \begin{verbatim}
157    
158          struct sigpending {          struct sigpending {
159              struct sigqueue *head, **tail;              struct sigqueue *head, **tail;
160              sigset_t signal;              sigset_t signal;
161          };          };
162    
163          \end{verbatim}          \end{verbatim}
164    
165          \section{Sending Signal to process}          \section{Registering Signals} \label{sig:regi}
166           When sending a signal to a process, kernel saves the context of the current thread of execution in user-space itself and overwrites the process's thread context with the signal handlers context. While delivering a signal, kernel stores the thread state of the previous thread of execution in the user-stack.           When sending a signal to a process, kernel saves the context of the current thread of execution in user-space itself and overwrites the process's thread context with the signal handlers context. While delivering a signal, kernel stores the thread state of the previous thread of execution in the user-stack.
167           The kernel keeps track of pending signals in each process's process structure. This is a 32-bit value, in user space \footnote{Refer to sigset\_t struct above.} in which each bit represents a single signal. Because it is only one bit per signal, there can only be one signal pending of each type.           \par The kernel keeps track of pending signals in each process's process structure. This is a 32-bit value, in user space \footnote{Refer to sigset\_t struct above.} in which each bit represents a single signal. Because it is only one bit per signal, there can only be one signal pending of each type. Its possible that the process to which you want to send the signal is sleeping. If that process is sleeping at an interruptible priority, then the process will be awaken to handle the signal.
168          Its possible that the process to which you want to send the signal is sleeping. If that process is sleeping at an interruptible priority, then the process will be awaken to handle the signal.          \par Whenever a new signal handler is registered by a process using the \textit{signal or sigaction} system call, the kernel updates invokes the sys\_signal function from \url{kernel/signal.c}, or the sys\_sigaction function from \url{acrh/i386/kernel/signal.c}. These functions update the various signal parameters within kernel signal information. Both of these functions call \textit{do\_sigaction} to update signal statisticks.
         Whenever a new signal handler is registered by a process using the signal system call, the kernel updates invokes the sys\_signal function from \url{kernel/signal.c}. This function updates the various signal parameters within kernel signal information.  
169          \begin{verbatim}          \begin{verbatim}
170    
171           /* User space system call */           /* User space system call */
172          sighandler_t signal(int signum, sighandler_t handler);          sighandler_t signal(int signum, sighandler_t handler);
173    
# Line 155  Line 189 
189          \end{verbatim}          \end{verbatim}
190    
191          The function stores the passed handler into new signal handler and calls the do\_sigaction function. If the do\_sigaction function returns success, the old signal handler is returned to the calling process, which can be restored using another signal() system call.          The function stores the passed handler into new signal handler and calls the do\_sigaction function. If the do\_sigaction function returns success, the old signal handler is returned to the calling process, which can be restored using another signal() system call.
         % TODO do_sigaction  
192    
193          \begin{verbatim}          \begin{verbatim}
194    
195             /* User space system call */
196            int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
197    
198             /* sys_sigaction function */
199            asmlinkage int
200            sys_sigaction(int sig, const struct old_sigaction *act,
201                 struct old_sigaction *oact)
202    
203             /* INCOMOPLETE CODE */
204    
205            if (act) {
206                old_sigset_t mask;
207                __get_user(new_ka.sa.sa_flags, &act->sa_flags);
208                _get_user(mask, &act->sa_mask);
209                siginitset(&new_ka.sa.sa_mask, mask);
210            }
211    
212            ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
213    
214                __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
215                __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
216    
217            \end{verbatim}
218    
219            \newline \par The system call sigaction is used to modify the complete signal action associated with a signal rather than merely changing the handler. Hence, it takes the \textit{struct sigation} as function arguments. The kernel function sys\_sigaction uses \textit{\_\_get\_user}\footnote{\_\_get\_user is a privileged operation which works across system memory spaces, user and kernel. See also, copy\_from\_user.} to copy the new sigaction structure from user space to kernel space. And calls the do\_sigaction function. When the function returns, it calls \textit{\_\_put\_user} to copy the old sigaction structure from kernel space to user space.
220    
221            \subsection{Function do\_sigaction}
222            The function do\_sigaction is described below:
223            \begin{verbatim}
224    
225            int
226            do_sigaction(int sig, const struct k_sigaction *act, struct k_sigaction *oact)
227            {
228                struct k_sigaction *k;
229    
230                if (sig < 1 || sig > _NSIG ||
231                    (act && (sig == SIGKILL || sig == SIGSTOP)))
232                        return -EINVAL;  /*  1. */
233    
234                k = &current->sig->action[sig-1];  /*  2. */
235    
236                spin_lock(&current->sig->siglock);
237    
238                if (oact)
239                    *oact = *k;   /*  3. */
240    
241                if (act) {
242                    *k = *act;    /*  4. */
243                    sigdelsetmask(&k->sa.sa_mask, sigmask(SIGKILL) | sigmask(SIGSTOP));
244    
245                    if (k->sa.sa_handler == SIG_IGN
246                        || (k->sa.sa_handler == SIG_DFL
247                            && (sig == SIGCONT ||
248                                sig == SIGCHLD ||
249                                sig == SIGWINCH ||
250                                sig == SIGURG))) {
251                            spin_lock_irq(&current->sigmask_lock);
252                            if (rm_sig_from_queue(sig, current))
253                                recalc_sigpending();    /*  5. */
254                            spin_unlock_irq(&current->sigmask_lock);
255                    }
256                }
257    
258                spin_unlock(&current->sig->siglock);
259                return 0;
260            }
261    
262            \end{verbatim}
263    
264            \begin{enumerate}
265            \item The function checks the validity of signal. And compares gig with SIGKILL, SIGSTOP because, Changing the signal handlers of SIGKILL or SIGSTOP is not allowed.
266            \item The signal lock used for sigsignal handler for the signal is accessed from the sig field of the current process. Signals start with SIGHUP as number 1, and arrays start with number 0, hence [sig-1] is used.
267            \item  This signal handler is stored as old signal handler. The signal lock in the signal\_struct for the process is grabbed, here and released after pending signals are recalculated.
268            \item The new signal handler passed, is stored as signal handler in the current process sig field.
269            \item For the valid signals, the function removes the signal from the sigqueue and updates the sigqueue structure. For the valid signals, the function removes the signal from the sigqueue and updates the sigqueue structure. The inline function \textit{recalc\_sigpending} defined in \url{include/linux/sched.h} re-calculates signal pending state from the set of locally pending signals, globally pending signals, and blocked signals for the \textbf{current} process.
270            \begin{verbatim}
271            static inline void recalc_sigpending(void)
272            {
273                if (has_pending_signals(&current->pending.signal, &current->blocked))
274                    set_thread_flag(TIF_SIGPENDING);
275                else
276                    clear_thread_flag(TIF_SIGPENDING);
277            }
278            \end{verbatim}
279            \end{enumerate}
280    
281            \section{Sending Signals to process} \label{sig:send}
282            % TODO
283            \subsection{Function send\_sig()}
284            % TODO from entry.S
285            % send_sig; send_sig_info; deliver_signal; send_signal, signal_wake_up
286            % force_sig; force_sig_info;send_sig_info; deliver_signal; send_signal
287            \section{Response of processes to signals}
288            \subsection{Function do\_signal()}
289            % TODO
290            % do_signal, handle_signal, setup_frame
291            \begin{verbatim}
292           movl $__NR_sigreturn           movl $__NR_sigreturn
293           int $0x80           int $0x80
294          \end{verbatim}          \end{verbatim}
295    
296           The "\_\_NR\_sigreturn" system call helps the kernel to restore the previous thread's context. When the signal handler exits, it returns to an area in stack where the kernel had already set the trap to make the signal handler execute the system call transparently.           The "\_\_NR\_sigreturn" system call helps the kernel to restore the previous thread's context. When the signal handler exits, it returns to an area in stack where the kernel had already set the trap to make the signal handler execute the system call transparently.
297    
         \section{Responce of processes to signals}  

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.2

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26