aboutsummaryrefslogtreecommitdiffstats
path: root/arch/m32r/kernel
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
commit8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch)
treea8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /arch/m32r/kernel
parent406089d01562f1e2bf9f089fd7637009ebaad589 (diff)
Patched in Tegra support.
Diffstat (limited to 'arch/m32r/kernel')
-rw-r--r--arch/m32r/kernel/Makefile2
-rw-r--r--arch/m32r/kernel/entry.S9
-rw-r--r--arch/m32r/kernel/m32r_ksyms.c1
-rw-r--r--arch/m32r/kernel/module.c15
-rw-r--r--arch/m32r/kernel/process.c133
-rw-r--r--arch/m32r/kernel/ptrace.c8
-rw-r--r--arch/m32r/kernel/signal.c49
-rw-r--r--arch/m32r/kernel/smpboot.c8
-rw-r--r--arch/m32r/kernel/sys_m32r.c21
-rw-r--r--arch/m32r/kernel/traps.c1
10 files changed, 202 insertions, 45 deletions
diff --git a/arch/m32r/kernel/Makefile b/arch/m32r/kernel/Makefile
index 0c09dad8b1f..b1a4b603659 100644
--- a/arch/m32r/kernel/Makefile
+++ b/arch/m32r/kernel/Makefile
@@ -2,7 +2,7 @@
2# Makefile for the Linux/M32R kernel. 2# Makefile for the Linux/M32R kernel.
3# 3#
4 4
5extra-y := head.o vmlinux.lds 5extra-y := head.o init_task.o vmlinux.lds
6 6
7obj-y := process.o entry.o traps.o align.o irq.o setup.o time.o \ 7obj-y := process.o entry.o traps.o align.o irq.o setup.o time.o \
8 m32r_ksyms.o sys_m32r.o signal.o ptrace.o 8 m32r_ksyms.o sys_m32r.o signal.o ptrace.o
diff --git a/arch/m32r/kernel/entry.S b/arch/m32r/kernel/entry.S
index 0c01543f10c..225412bc227 100644
--- a/arch/m32r/kernel/entry.S
+++ b/arch/m32r/kernel/entry.S
@@ -125,15 +125,6 @@
125 and \reg, sp 125 and \reg, sp
126 .endm 126 .endm
127 127
128ENTRY(ret_from_kernel_thread)
129 pop r0
130 bl schedule_tail
131 GET_THREAD_INFO(r8)
132 ld r0, R0(r8)
133 ld r1, R1(r8)
134 jl r1
135 bra syscall_exit
136
137ENTRY(ret_from_fork) 128ENTRY(ret_from_fork)
138 pop r0 129 pop r0
139 bl schedule_tail 130 bl schedule_tail
diff --git a/arch/m32r/kernel/m32r_ksyms.c b/arch/m32r/kernel/m32r_ksyms.c
index b727e693c80..700570747a9 100644
--- a/arch/m32r/kernel/m32r_ksyms.c
+++ b/arch/m32r/kernel/m32r_ksyms.c
@@ -21,6 +21,7 @@ EXPORT_SYMBOL(boot_cpu_data);
21EXPORT_SYMBOL(dump_fpu); 21EXPORT_SYMBOL(dump_fpu);
22EXPORT_SYMBOL(__ioremap); 22EXPORT_SYMBOL(__ioremap);
23EXPORT_SYMBOL(iounmap); 23EXPORT_SYMBOL(iounmap);
24EXPORT_SYMBOL(kernel_thread);
24 25
25EXPORT_SYMBOL(strncpy_from_user); 26EXPORT_SYMBOL(strncpy_from_user);
26EXPORT_SYMBOL(__strncpy_from_user); 27EXPORT_SYMBOL(__strncpy_from_user);
diff --git a/arch/m32r/kernel/module.c b/arch/m32r/kernel/module.c
index 38233b6596b..3071fe83ffc 100644
--- a/arch/m32r/kernel/module.c
+++ b/arch/m32r/kernel/module.c
@@ -201,3 +201,18 @@ int apply_relocate_add(Elf32_Shdr *sechdrs,
201 } 201 }
202 return 0; 202 return 0;
203} 203}
204
205int apply_relocate(Elf32_Shdr *sechdrs,
206 const char *strtab,
207 unsigned int symindex,
208 unsigned int relsec,
209 struct module *me)
210{
211#if 0
212 printk(KERN_ERR "module %s: REL RELOCATION unsupported\n",
213 me->name);
214 return -ENOEXEC;
215#endif
216 return 0;
217
218}
diff --git a/arch/m32r/kernel/process.c b/arch/m32r/kernel/process.c
index 765d0f57c78..422bea9f1db 100644
--- a/arch/m32r/kernel/process.c
+++ b/arch/m32r/kernel/process.c
@@ -26,7 +26,6 @@
26#include <linux/ptrace.h> 26#include <linux/ptrace.h>
27#include <linux/unistd.h> 27#include <linux/unistd.h>
28#include <linux/hardirq.h> 28#include <linux/hardirq.h>
29#include <linux/rcupdate.h>
30 29
31#include <asm/io.h> 30#include <asm/io.h>
32#include <asm/uaccess.h> 31#include <asm/uaccess.h>
@@ -83,7 +82,6 @@ void cpu_idle (void)
83{ 82{
84 /* endless idle loop with no priority at all */ 83 /* endless idle loop with no priority at all */
85 while (1) { 84 while (1) {
86 rcu_idle_enter();
87 while (!need_resched()) { 85 while (!need_resched()) {
88 void (*idle)(void) = pm_idle; 86 void (*idle)(void) = pm_idle;
89 87
@@ -92,8 +90,9 @@ void cpu_idle (void)
92 90
93 idle(); 91 idle();
94 } 92 }
95 rcu_idle_exit(); 93 preempt_enable_no_resched();
96 schedule_preempt_disabled(); 94 schedule();
95 preempt_disable();
97 } 96 }
98} 97}
99 98
@@ -165,6 +164,41 @@ void show_regs(struct pt_regs * regs)
165} 164}
166 165
167/* 166/*
167 * Create a kernel thread
168 */
169
170/*
171 * This is the mechanism for creating a new kernel thread.
172 *
173 * NOTE! Only a kernel-only process(ie the swapper or direct descendants
174 * who haven't done an "execve()") should use this: it will work within
175 * a system call from a "real" process, but the process memory space will
176 * not be free'd until both the parent and the child have exited.
177 */
178static void kernel_thread_helper(void *nouse, int (*fn)(void *), void *arg)
179{
180 fn(arg);
181 do_exit(-1);
182}
183
184int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
185{
186 struct pt_regs regs;
187
188 memset(&regs, 0, sizeof (regs));
189 regs.r1 = (unsigned long)fn;
190 regs.r2 = (unsigned long)arg;
191
192 regs.bpc = (unsigned long)kernel_thread_helper;
193
194 regs.psw = M32R_PSW_BIE;
195
196 /* Ok, create the new process. */
197 return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL,
198 NULL);
199}
200
201/*
168 * Free current thread data structures etc.. 202 * Free current thread data structures etc..
169 */ 203 */
170void exit_thread(void) 204void exit_thread(void)
@@ -192,31 +226,88 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu)
192} 226}
193 227
194int copy_thread(unsigned long clone_flags, unsigned long spu, 228int copy_thread(unsigned long clone_flags, unsigned long spu,
195 unsigned long arg, struct task_struct *tsk) 229 unsigned long unused, struct task_struct *tsk, struct pt_regs *regs)
196{ 230{
197 struct pt_regs *childregs = task_pt_regs(tsk); 231 struct pt_regs *childregs = task_pt_regs(tsk);
198 extern void ret_from_fork(void); 232 extern void ret_from_fork(void);
199 extern void ret_from_kernel_thread(void); 233
200 234 /* Copy registers */
201 if (unlikely(tsk->flags & PF_KTHREAD)) { 235 *childregs = *regs;
202 memset(childregs, 0, sizeof(struct pt_regs)); 236
203 childregs->psw = M32R_PSW_BIE; 237 childregs->spu = spu;
204 childregs->r1 = spu; /* fn */ 238 childregs->r0 = 0; /* Child gets zero as return value */
205 childregs->r0 = arg; 239 regs->r0 = tsk->pid;
206 tsk->thread.lr = (unsigned long)ret_from_kernel_thread;
207 } else {
208 /* Copy registers */
209 *childregs = *current_pt_regs();
210 if (spu)
211 childregs->spu = spu;
212 childregs->r0 = 0; /* Child gets zero as return value */
213 tsk->thread.lr = (unsigned long)ret_from_fork;
214 }
215 tsk->thread.sp = (unsigned long)childregs; 240 tsk->thread.sp = (unsigned long)childregs;
241 tsk->thread.lr = (unsigned long)ret_from_fork;
216 242
217 return 0; 243 return 0;
218} 244}
219 245
246asmlinkage int sys_fork(unsigned long r0, unsigned long r1, unsigned long r2,
247 unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6,
248 struct pt_regs regs)
249{
250#ifdef CONFIG_MMU
251 return do_fork(SIGCHLD, regs.spu, &regs, 0, NULL, NULL);
252#else
253 return -EINVAL;
254#endif /* CONFIG_MMU */
255}
256
257asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
258 unsigned long parent_tidptr,
259 unsigned long child_tidptr,
260 unsigned long r4, unsigned long r5, unsigned long r6,
261 struct pt_regs regs)
262{
263 if (!newsp)
264 newsp = regs.spu;
265
266 return do_fork(clone_flags, newsp, &regs, 0,
267 (int __user *)parent_tidptr, (int __user *)child_tidptr);
268}
269
270/*
271 * This is trivial, and on the face of it looks like it
272 * could equally well be done in user mode.
273 *
274 * Not so, for quite unobvious reasons - register pressure.
275 * In user mode vfork() cannot have a stack frame, and if
276 * done by calling the "clone()" system call directly, you
277 * do not have enough call-clobbered registers to hold all
278 * the information you need.
279 */
280asmlinkage int sys_vfork(unsigned long r0, unsigned long r1, unsigned long r2,
281 unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6,
282 struct pt_regs regs)
283{
284 return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.spu, &regs, 0,
285 NULL, NULL);
286}
287
288/*
289 * sys_execve() executes a new program.
290 */
291asmlinkage int sys_execve(const char __user *ufilename,
292 const char __user *const __user *uargv,
293 const char __user *const __user *uenvp,
294 unsigned long r3, unsigned long r4, unsigned long r5,
295 unsigned long r6, struct pt_regs regs)
296{
297 int error;
298 char *filename;
299
300 filename = getname(ufilename);
301 error = PTR_ERR(filename);
302 if (IS_ERR(filename))
303 goto out;
304
305 error = do_execve(filename, uargv, uenvp, &regs);
306 putname(filename);
307out:
308 return error;
309}
310
220/* 311/*
221 * These bracket the sleeping functions.. 312 * These bracket the sleeping functions..
222 */ 313 */
diff --git a/arch/m32r/kernel/ptrace.c b/arch/m32r/kernel/ptrace.c
index 51f5e9aa490..20743754f2b 100644
--- a/arch/m32r/kernel/ptrace.c
+++ b/arch/m32r/kernel/ptrace.c
@@ -29,6 +29,7 @@
29#include <asm/io.h> 29#include <asm/io.h>
30#include <asm/uaccess.h> 30#include <asm/uaccess.h>
31#include <asm/pgtable.h> 31#include <asm/pgtable.h>
32#include <asm/system.h>
32#include <asm/processor.h> 33#include <asm/processor.h>
33#include <asm/mmu_context.h> 34#include <asm/mmu_context.h>
34 35
@@ -591,16 +592,17 @@ void user_enable_single_step(struct task_struct *child)
591 592
592 if (access_process_vm(child, pc&~3, &insn, sizeof(insn), 0) 593 if (access_process_vm(child, pc&~3, &insn, sizeof(insn), 0)
593 != sizeof(insn)) 594 != sizeof(insn))
594 return; 595 return -EIO;
595 596
596 compute_next_pc(insn, pc, &next_pc, child); 597 compute_next_pc(insn, pc, &next_pc, child);
597 if (next_pc & 0x80000000) 598 if (next_pc & 0x80000000)
598 return; 599 return -EIO;
599 600
600 if (embed_debug_trap(child, next_pc)) 601 if (embed_debug_trap(child, next_pc))
601 return; 602 return -EIO;
602 603
603 invalidate_cache(); 604 invalidate_cache();
605 return 0;
604} 606}
605 607
606void user_disable_single_step(struct task_struct *child) 608void user_disable_single_step(struct task_struct *child)
diff --git a/arch/m32r/kernel/signal.c b/arch/m32r/kernel/signal.c
index 6e3c26a1607..a08697f0886 100644
--- a/arch/m32r/kernel/signal.c
+++ b/arch/m32r/kernel/signal.c
@@ -20,6 +20,7 @@
20#include <linux/unistd.h> 20#include <linux/unistd.h>
21#include <linux/stddef.h> 21#include <linux/stddef.h>
22#include <linux/personality.h> 22#include <linux/personality.h>
23#include <linux/freezer.h>
23#include <linux/tracehook.h> 24#include <linux/tracehook.h>
24#include <asm/cacheflush.h> 25#include <asm/cacheflush.h>
25#include <asm/ucontext.h> 26#include <asm/ucontext.h>
@@ -27,6 +28,8 @@
27 28
28#define DEBUG_SIG 0 29#define DEBUG_SIG 0
29 30
31#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
32
30asmlinkage int 33asmlinkage int
31sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, 34sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
32 unsigned long r2, unsigned long r3, unsigned long r4, 35 unsigned long r2, unsigned long r3, unsigned long r4,
@@ -108,7 +111,11 @@ sys_rt_sigreturn(unsigned long r0, unsigned long r1,
108 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) 111 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
109 goto badframe; 112 goto badframe;
110 113
111 set_current_blocked(&set); 114 sigdelsetmask(&set, ~_BLOCKABLE);
115 spin_lock_irq(&current->sighand->siglock);
116 current->blocked = set;
117 recalc_sigpending();
118 spin_unlock_irq(&current->sighand->siglock);
112 119
113 if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &result)) 120 if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &result))
114 goto badframe; 121 goto badframe;
@@ -263,9 +270,9 @@ static int prev_insn(struct pt_regs *regs)
263 * OK, we're invoking a handler 270 * OK, we're invoking a handler
264 */ 271 */
265 272
266static void 273static int
267handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, 274handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
268 struct pt_regs *regs) 275 sigset_t *oldset, struct pt_regs *regs)
269{ 276{
270 /* Are we from a system call? */ 277 /* Are we from a system call? */
271 if (regs->syscall_nr >= 0) { 278 if (regs->syscall_nr >= 0) {
@@ -285,15 +292,21 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
285 case -ERESTARTNOINTR: 292 case -ERESTARTNOINTR:
286 regs->r0 = regs->orig_r0; 293 regs->r0 = regs->orig_r0;
287 if (prev_insn(regs) < 0) 294 if (prev_insn(regs) < 0)
288 return; 295 return -EFAULT;
289 } 296 }
290 } 297 }
291 298
292 /* Set up the stack frame */ 299 /* Set up the stack frame */
293 if (setup_rt_frame(sig, ka, info, sigmask_to_save(), regs)) 300 if (setup_rt_frame(sig, ka, info, oldset, regs))
294 return; 301 return -EFAULT;
295 302
296 signal_delivered(sig, info, ka, regs, 0); 303 spin_lock_irq(&current->sighand->siglock);
304 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
305 if (!(ka->sa.sa_flags & SA_NODEFER))
306 sigaddset(&current->blocked,sig);
307 recalc_sigpending();
308 spin_unlock_irq(&current->sighand->siglock);
309 return 0;
297} 310}
298 311
299/* 312/*
@@ -306,6 +319,7 @@ static void do_signal(struct pt_regs *regs)
306 siginfo_t info; 319 siginfo_t info;
307 int signr; 320 int signr;
308 struct k_sigaction ka; 321 struct k_sigaction ka;
322 sigset_t *oldset;
309 323
310 /* 324 /*
311 * We want the common case to go fast, which 325 * We want the common case to go fast, which
@@ -316,6 +330,14 @@ static void do_signal(struct pt_regs *regs)
316 if (!user_mode(regs)) 330 if (!user_mode(regs))
317 return; 331 return;
318 332
333 if (try_to_freeze())
334 goto no_signal;
335
336 if (test_thread_flag(TIF_RESTORE_SIGMASK))
337 oldset = &current->saved_sigmask;
338 else
339 oldset = &current->blocked;
340
319 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 341 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
320 if (signr > 0) { 342 if (signr > 0) {
321 /* Re-enable any watchpoints before delivering the 343 /* Re-enable any watchpoints before delivering the
@@ -325,11 +347,13 @@ static void do_signal(struct pt_regs *regs)
325 */ 347 */
326 348
327 /* Whee! Actually deliver the signal. */ 349 /* Whee! Actually deliver the signal. */
328 handle_signal(signr, &ka, &info, regs); 350 if (handle_signal(signr, &ka, &info, oldset, regs) == 0)
351 clear_thread_flag(TIF_RESTORE_SIGMASK);
329 352
330 return; 353 return;
331 } 354 }
332 355
356 no_signal:
333 /* Did we come from a system call? */ 357 /* Did we come from a system call? */
334 if (regs->syscall_nr >= 0) { 358 if (regs->syscall_nr >= 0) {
335 /* Restart the system call - no handlers present */ 359 /* Restart the system call - no handlers present */
@@ -344,7 +368,10 @@ static void do_signal(struct pt_regs *regs)
344 prev_insn(regs); 368 prev_insn(regs);
345 } 369 }
346 } 370 }
347 restore_saved_sigmask(); 371 if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
372 clear_thread_flag(TIF_RESTORE_SIGMASK);
373 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
374 }
348} 375}
349 376
350/* 377/*
@@ -364,5 +391,9 @@ void do_notify_resume(struct pt_regs *regs, __u32 thread_info_flags)
364 if (thread_info_flags & _TIF_NOTIFY_RESUME) { 391 if (thread_info_flags & _TIF_NOTIFY_RESUME) {
365 clear_thread_flag(TIF_NOTIFY_RESUME); 392 clear_thread_flag(TIF_NOTIFY_RESUME);
366 tracehook_notify_resume(regs); 393 tracehook_notify_resume(regs);
394 if (current->replacement_session_keyring)
395 key_replace_session_keyring();
367 } 396 }
397
398 clear_thread_flag(TIF_IRET);
368} 399}
diff --git a/arch/m32r/kernel/smpboot.c b/arch/m32r/kernel/smpboot.c
index 13168a769f8..cfdbe5d1500 100644
--- a/arch/m32r/kernel/smpboot.c
+++ b/arch/m32r/kernel/smpboot.c
@@ -109,8 +109,12 @@ static unsigned int calibration_result;
109/* Function Prototypes */ 109/* Function Prototypes */
110/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ 110/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
111 111
112void smp_prepare_boot_cpu(void);
113void smp_prepare_cpus(unsigned int);
112static void init_ipi_lock(void); 114static void init_ipi_lock(void);
113static void do_boot_cpu(int); 115static void do_boot_cpu(int);
116int __cpu_up(unsigned int);
117void smp_cpus_done(unsigned int);
114 118
115int start_secondary(void *); 119int start_secondary(void *);
116static void smp_callin(void); 120static void smp_callin(void);
@@ -127,7 +131,7 @@ static void unmap_cpu_to_physid(int, int);
127/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ 131/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
128/* Boot up APs Routines : BSP */ 132/* Boot up APs Routines : BSP */
129/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ 133/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
130void smp_prepare_boot_cpu(void) 134void __devinit smp_prepare_boot_cpu(void)
131{ 135{
132 bsp_phys_id = hard_smp_processor_id(); 136 bsp_phys_id = hard_smp_processor_id();
133 physid_set(bsp_phys_id, phys_cpu_present_map); 137 physid_set(bsp_phys_id, phys_cpu_present_map);
@@ -343,7 +347,7 @@ static void __init do_boot_cpu(int phys_id)
343 } 347 }
344} 348}
345 349
346int __cpuinit __cpu_up(unsigned int cpu_id, struct task_struct *tidle) 350int __cpuinit __cpu_up(unsigned int cpu_id)
347{ 351{
348 int timeout; 352 int timeout;
349 353
diff --git a/arch/m32r/kernel/sys_m32r.c b/arch/m32r/kernel/sys_m32r.c
index c3fdd632fba..d841fb6cc70 100644
--- a/arch/m32r/kernel/sys_m32r.c
+++ b/arch/m32r/kernel/sys_m32r.c
@@ -88,3 +88,24 @@ asmlinkage int sys_cachectl(char *addr, int nbytes, int op)
88 /* Not implemented yet. */ 88 /* Not implemented yet. */
89 return -ENOSYS; 89 return -ENOSYS;
90} 90}
91
92/*
93 * Do a system call from kernel instead of calling sys_execve so we
94 * end up with proper pt_regs.
95 */
96int kernel_execve(const char *filename,
97 const char *const argv[],
98 const char *const envp[])
99{
100 register long __scno __asm__ ("r7") = __NR_execve;
101 register long __arg3 __asm__ ("r2") = (long)(envp);
102 register long __arg2 __asm__ ("r1") = (long)(argv);
103 register long __res __asm__ ("r0") = (long)(filename);
104 __asm__ __volatile__ (
105 "trap #" SYSCALL_VECTOR "|| nop"
106 : "=r" (__res)
107 : "r" (__scno), "0" (__res), "r" (__arg2),
108 "r" (__arg3)
109 : "memory");
110 return __res;
111}
diff --git a/arch/m32r/kernel/traps.c b/arch/m32r/kernel/traps.c
index 3bcb207e5b6..ee6a9199561 100644
--- a/arch/m32r/kernel/traps.c
+++ b/arch/m32r/kernel/traps.c
@@ -18,6 +18,7 @@
18#include <asm/page.h> 18#include <asm/page.h>
19#include <asm/processor.h> 19#include <asm/processor.h>
20 20
21#include <asm/system.h>
21#include <asm/uaccess.h> 22#include <asm/uaccess.h>
22#include <asm/io.h> 23#include <asm/io.h>
23#include <linux/atomic.h> 24#include <linux/atomic.h>