diff options
Diffstat (limited to 'arch/x86/kernel/traps_32.c')
-rw-r--r-- | arch/x86/kernel/traps_32.c | 54 |
1 files changed, 21 insertions, 33 deletions
diff --git a/arch/x86/kernel/traps_32.c b/arch/x86/kernel/traps_32.c index 1e9d57256eb1..cc9acace7e23 100644 --- a/arch/x86/kernel/traps_32.c +++ b/arch/x86/kernel/traps_32.c | |||
@@ -63,6 +63,9 @@ | |||
63 | 63 | ||
64 | int panic_on_unrecovered_nmi; | 64 | int panic_on_unrecovered_nmi; |
65 | 65 | ||
66 | DECLARE_BITMAP(used_vectors, NR_VECTORS); | ||
67 | EXPORT_SYMBOL_GPL(used_vectors); | ||
68 | |||
66 | asmlinkage int system_call(void); | 69 | asmlinkage int system_call(void); |
67 | 70 | ||
68 | /* Do we ignore FPU interrupts ? */ | 71 | /* Do we ignore FPU interrupts ? */ |
@@ -288,33 +291,9 @@ EXPORT_SYMBOL(dump_stack); | |||
288 | void show_registers(struct pt_regs *regs) | 291 | void show_registers(struct pt_regs *regs) |
289 | { | 292 | { |
290 | int i; | 293 | int i; |
291 | int in_kernel = 1; | 294 | |
292 | unsigned long esp; | ||
293 | unsigned short ss, gs; | ||
294 | |||
295 | esp = (unsigned long) (®s->esp); | ||
296 | savesegment(ss, ss); | ||
297 | savesegment(gs, gs); | ||
298 | if (user_mode_vm(regs)) { | ||
299 | in_kernel = 0; | ||
300 | esp = regs->esp; | ||
301 | ss = regs->xss & 0xffff; | ||
302 | } | ||
303 | print_modules(); | 295 | print_modules(); |
304 | printk(KERN_EMERG "CPU: %d\n" | 296 | __show_registers(regs, 0); |
305 | KERN_EMERG "EIP: %04x:[<%08lx>] %s VLI\n" | ||
306 | KERN_EMERG "EFLAGS: %08lx (%s %.*s)\n", | ||
307 | smp_processor_id(), 0xffff & regs->xcs, regs->eip, | ||
308 | print_tainted(), regs->eflags, init_utsname()->release, | ||
309 | (int)strcspn(init_utsname()->version, " "), | ||
310 | init_utsname()->version); | ||
311 | print_symbol(KERN_EMERG "EIP is at %s\n", regs->eip); | ||
312 | printk(KERN_EMERG "eax: %08lx ebx: %08lx ecx: %08lx edx: %08lx\n", | ||
313 | regs->eax, regs->ebx, regs->ecx, regs->edx); | ||
314 | printk(KERN_EMERG "esi: %08lx edi: %08lx ebp: %08lx esp: %08lx\n", | ||
315 | regs->esi, regs->edi, regs->ebp, esp); | ||
316 | printk(KERN_EMERG "ds: %04x es: %04x fs: %04x gs: %04x ss: %04x\n", | ||
317 | regs->xds & 0xffff, regs->xes & 0xffff, regs->xfs & 0xffff, gs, ss); | ||
318 | printk(KERN_EMERG "Process %.*s (pid: %d, ti=%p task=%p task.ti=%p)", | 297 | printk(KERN_EMERG "Process %.*s (pid: %d, ti=%p task=%p task.ti=%p)", |
319 | TASK_COMM_LEN, current->comm, task_pid_nr(current), | 298 | TASK_COMM_LEN, current->comm, task_pid_nr(current), |
320 | current_thread_info(), current, task_thread_info(current)); | 299 | current_thread_info(), current, task_thread_info(current)); |
@@ -322,14 +301,14 @@ void show_registers(struct pt_regs *regs) | |||
322 | * When in-kernel, we also print out the stack and code at the | 301 | * When in-kernel, we also print out the stack and code at the |
323 | * time of the fault.. | 302 | * time of the fault.. |
324 | */ | 303 | */ |
325 | if (in_kernel) { | 304 | if (!user_mode_vm(regs)) { |
326 | u8 *eip; | 305 | u8 *eip; |
327 | unsigned int code_prologue = code_bytes * 43 / 64; | 306 | unsigned int code_prologue = code_bytes * 43 / 64; |
328 | unsigned int code_len = code_bytes; | 307 | unsigned int code_len = code_bytes; |
329 | unsigned char c; | 308 | unsigned char c; |
330 | 309 | ||
331 | printk("\n" KERN_EMERG "Stack: "); | 310 | printk("\n" KERN_EMERG "Stack: "); |
332 | show_stack_log_lvl(NULL, regs, (unsigned long *)esp, KERN_EMERG); | 311 | show_stack_log_lvl(NULL, regs, ®s->esp, KERN_EMERG); |
333 | 312 | ||
334 | printk(KERN_EMERG "Code: "); | 313 | printk(KERN_EMERG "Code: "); |
335 | 314 | ||
@@ -374,11 +353,11 @@ int is_valid_bugaddr(unsigned long eip) | |||
374 | void die(const char * str, struct pt_regs * regs, long err) | 353 | void die(const char * str, struct pt_regs * regs, long err) |
375 | { | 354 | { |
376 | static struct { | 355 | static struct { |
377 | spinlock_t lock; | 356 | raw_spinlock_t lock; |
378 | u32 lock_owner; | 357 | u32 lock_owner; |
379 | int lock_owner_depth; | 358 | int lock_owner_depth; |
380 | } die = { | 359 | } die = { |
381 | .lock = __SPIN_LOCK_UNLOCKED(die.lock), | 360 | .lock = __RAW_SPIN_LOCK_UNLOCKED, |
382 | .lock_owner = -1, | 361 | .lock_owner = -1, |
383 | .lock_owner_depth = 0 | 362 | .lock_owner_depth = 0 |
384 | }; | 363 | }; |
@@ -389,13 +368,14 @@ void die(const char * str, struct pt_regs * regs, long err) | |||
389 | 368 | ||
390 | if (die.lock_owner != raw_smp_processor_id()) { | 369 | if (die.lock_owner != raw_smp_processor_id()) { |
391 | console_verbose(); | 370 | console_verbose(); |
392 | spin_lock_irqsave(&die.lock, flags); | 371 | __raw_spin_lock(&die.lock); |
372 | raw_local_save_flags(flags); | ||
393 | die.lock_owner = smp_processor_id(); | 373 | die.lock_owner = smp_processor_id(); |
394 | die.lock_owner_depth = 0; | 374 | die.lock_owner_depth = 0; |
395 | bust_spinlocks(1); | 375 | bust_spinlocks(1); |
396 | } | 376 | } |
397 | else | 377 | else |
398 | local_save_flags(flags); | 378 | raw_local_save_flags(flags); |
399 | 379 | ||
400 | if (++die.lock_owner_depth < 3) { | 380 | if (++die.lock_owner_depth < 3) { |
401 | unsigned long esp; | 381 | unsigned long esp; |
@@ -439,7 +419,8 @@ void die(const char * str, struct pt_regs * regs, long err) | |||
439 | bust_spinlocks(0); | 419 | bust_spinlocks(0); |
440 | die.lock_owner = -1; | 420 | die.lock_owner = -1; |
441 | add_taint(TAINT_DIE); | 421 | add_taint(TAINT_DIE); |
442 | spin_unlock_irqrestore(&die.lock, flags); | 422 | __raw_spin_unlock(&die.lock); |
423 | raw_local_irq_restore(flags); | ||
443 | 424 | ||
444 | if (!regs) | 425 | if (!regs) |
445 | return; | 426 | return; |
@@ -1142,6 +1123,8 @@ static void __init set_task_gate(unsigned int n, unsigned int gdt_entry) | |||
1142 | 1123 | ||
1143 | void __init trap_init(void) | 1124 | void __init trap_init(void) |
1144 | { | 1125 | { |
1126 | int i; | ||
1127 | |||
1145 | #ifdef CONFIG_EISA | 1128 | #ifdef CONFIG_EISA |
1146 | void __iomem *p = ioremap(0x0FFFD9, 4); | 1129 | void __iomem *p = ioremap(0x0FFFD9, 4); |
1147 | if (readl(p) == 'E'+('I'<<8)+('S'<<16)+('A'<<24)) { | 1130 | if (readl(p) == 'E'+('I'<<8)+('S'<<16)+('A'<<24)) { |
@@ -1201,6 +1184,11 @@ void __init trap_init(void) | |||
1201 | 1184 | ||
1202 | set_system_gate(SYSCALL_VECTOR,&system_call); | 1185 | set_system_gate(SYSCALL_VECTOR,&system_call); |
1203 | 1186 | ||
1187 | /* Reserve all the builtin and the syscall vector. */ | ||
1188 | for (i = 0; i < FIRST_EXTERNAL_VECTOR; i++) | ||
1189 | set_bit(i, used_vectors); | ||
1190 | set_bit(SYSCALL_VECTOR, used_vectors); | ||
1191 | |||
1204 | /* | 1192 | /* |
1205 | * Should be a barrier for any external CPU state. | 1193 | * Should be a barrier for any external CPU state. |
1206 | */ | 1194 | */ |