3 * Shared between UX and native IA32.
5 INTERFACE [ia32,amd64,ux]:
7 #include "trap_state.h"
11 EXTENSION class Thread
15 * Return code segment used for exception reflection to user mode
17 static Mword exception_cs();
20 static Trap_state::Handler nested_trap_handler FIASCO_FASTCALL;
24 //----------------------------------------------------------------------------
25 INTERFACE [ia32,amd64]:
29 EXTENSION class Thread
32 static int (*int3_handler)(Trap_state*);
36 //----------------------------------------------------------------------------
37 IMPLEMENTATION [ia32,amd64,ux]:
45 #include "mem_layout.h"
48 #include "processor.h" // for cli/sti
50 #include "std_macros.h"
53 #include "trap_state.h"
55 Trap_state::Handler Thread::nested_trap_handler FIASCO_FASTCALL;
60 Sender(0), // select optimized version of constructor
61 _pager(Thread_ptr::Invalid),
62 _exc_handler(Thread_ptr::Invalid),
65 assert (state(false) == Thread_invalid);
68 _space.space(Kernel_task::kernel_task());
70 if (Config::Stack_depth)
71 std::memset((char*)this + sizeof(Thread), '5',
72 Thread::Size-sizeof(Thread)-64);
78 *reinterpret_cast<void(**)()> (--_kernel_sp) = user_invoke;
82 state_add_dirty(Thread_dead, false);
84 // ok, we're ready to go!
87 IMPLEMENT inline NEEDS[Thread::exception_triggered]
89 Thread::user_ip() const
90 { return exception_triggered()?_exc_cont.ip():regs()->ip(); }
94 Thread::user_flags() const
95 { return regs()->flags(); }
97 /** Check if the pagefault occured at a special place: At some places in the
98 kernel we want to ensure that a specific address is mapped. The regular
99 case is "mapped", the exception or slow case is "not mapped". The fastest
100 way to check this is to touch into the memory. If there is no mapping for
101 the address we get a pagefault. Now the pagefault exception handler can
102 recognize that situation by scanning the code. The trick is that the
103 assembler instruction "andl $0xffffffff, %ss:(%ecx)" _clears_ the carry
104 flag normally (see Intel reference manual). The pager wants to inform the
105 code that there was a pagefault and therefore _sets_ the carry flag. So
106 the code has only to check if the carry flag is set. If yes, there was
107 a pagefault at this instruction.
108 @param ip pagefault address */
111 Thread::pagein_tcb_request(Return_frame *regs)
113 unsigned long new_ip = regs->ip();
114 if (*(Unsigned8*)new_ip == 0x48) // REX.W
117 register Unsigned16 op = *(Unsigned16*)new_ip;
118 //LOG_MSG_3VAL(current(),"TCB", op, new_ip, 0);
119 if ((op & 0xc0ff) == 0x8b) // Context::is_tcb_mapped() and Context::state()
121 regs->ip(new_ip + 2);
129 Mword *reg = ((Mword*)regs) - 2 - Return_frame::Pf_ax_offset;
131 LOG_MSG_3VAL(current(),"TCB", op, regs->ip(), (Mword)reg);
132 LOG_MSG_3VAL(current(),"TCBX", reg[-3], reg[-4], reg[-5]);
133 LOG_MSG_3VAL(current(),"TCB0", reg[0], reg[-1], reg[-2]);
134 LOG_MSG_3VAL(current(),"TCB1", reg[1], reg[2], reg[3]);
136 assert((op >> 11) <= 2);
137 reg[-(op>>11)] = 0; // op==0 => eax, op==1 => ecx, op==2 => edx
139 // tell program that a pagefault occured we cannot handle
140 regs->flags(regs->flags() | 0x41); // set carry and zero flag in EFLAGS
143 else if (*(Unsigned32*)regs->ip() == 0xff01f636) // used in shortcut.S
145 regs->ip(regs->ip() + 4);
146 regs->flags(regs->flags() | 1); // set carry flag in EFLAGS
154 extern "C" FIASCO_FASTCALL
156 thread_restore_exc_state()
158 current_thread()->restore_exc_state();
163 Thread::print_page_fault_error(Mword e)
169 * The global trap handler switch.
170 * This function handles CPU-exception reflection, emulation of CPU
171 * instructions (LIDT, WRMSR, RDMSR), int3 debug messages,
172 * kernel-debugger invocation, and thread crashes (if a trap cannot be
174 * @param state trap state
175 * @return 0 if trap has been consumed by handler;
176 * -1 if trap could not be handled.
180 Thread::handle_slow_trap(Trap_state *ts)
183 int from_user = ts->cs() & 3;
185 if (EXPECT_FALSE(ts->_trapno == 0xee)) //debug IPI
187 Ipi::eoi(Ipi::Debug, cpu());
191 if (from_user && _space.user_mode())
193 if (ts->_trapno == 14 && Kmem::is_io_bitmap_page_fault(ts->_cr2))
199 if (send_exception(ts))
203 // XXX We might be forced to raise an excepton. In this case, our return
204 // CS:IP points to leave_by_trigger_exception() which will trigger the
205 // exception just before returning to userland. But if we were inside an
206 // IPC while we was ex-regs'd, we will generate the 'exception after the
207 // syscall' _before_ we leave the kernel.
208 if (ts->_trapno == 13 && (ts->_err & 6) == 6)
209 goto check_exception;
213 if (!check_trap13_kernel (ts))
216 if (EXPECT_FALSE(!from_user))
218 // get also here if a pagefault was not handled by the user level pager
219 if (ts->_trapno == 14)
220 goto check_exception;
222 goto generic_debug; // we were in kernel mode -- nothing to emulate
225 if (EXPECT_FALSE(ts->_trapno == 2))
226 goto generic_debug; // NMI always enters kernel debugger
228 if (EXPECT_FALSE(ts->_trapno == 0xffffffff))
229 goto generic_debug; // debugger interrupt
233 // so we were in user mode -- look for something to emulate
235 // We continue running with interrupts off -- no sti() here. But
236 // interrupts may be enabled by the pagefault handler if we get a
237 // pagefault in peek_user().
239 // Set up exception handling. If we suffer an un-handled user-space
240 // page fault, kill the thread.
243 if (EXPECT_FALSE ((error = setjmp(pf_recovery)) != 0) )
246 "\033[1mUnhandled page fault, code=%08x\033[m\n", this, error);
250 _recover_jmpbuf = &pf_recovery;
252 switch (handle_io_page_fault(ts))
254 case 1: goto success;
261 // just print out some warning, we do the normal exception handling
262 handle_sysenter_trap(ts, ip, from_user);
267 // send exception IPC if requested
268 if (send_exception(ts))
271 // backward compatibility cruft: check for those insane "int3" debug
272 // messaging command sequences
273 if (ts->_trapno == 3)
275 if (int3_handler && int3_handler(ts))
281 // privileged tasks also may invoke the kernel debugger with a debug
283 if (ts->_trapno == 1)
288 // can't handle trap -- kill the thread
290 "\033[1mUnhandled trap \033[m\n", this);
293 if ((int)Config::Warn_level >= Warning)
305 if (!nested_trap_handler)
306 return handle_not_nested_trap(ts);
308 return call_nested_trap_handler(ts);
312 * The low-level page fault handler called from entry.S. We're invoked with
313 * interrupts turned off. Apart from turning on interrupts in almost
314 * all cases (except for kernel page faults in TCB area), just forwards
315 * the call to Thread::handle_page_fault().
316 * @param pfa page-fault virtual address
317 * @param error_code CPU error code
318 * @return true if page fault could be resolved, false otherwise
320 extern "C" FIASCO_FASTCALL
322 thread_page_fault(Address pfa, Mword error_code, Address ip, Mword flags,
326 // XXX: need to do in a different way, if on debug stack e.g.
328 // If we're in the GDB stub -- let generic handler handle it
329 if (EXPECT_FALSE (!in_context_area((void*)Proc::stack_pointer())))
333 // Pagefault in user mode or interrupts were enabled
334 if (PF::is_usermode_error(error_code))
336 if (current_thread()->vcpu_pagefault(pfa, error_code, ip))
341 else if(flags & EFLAGS_IF)
344 // Pagefault in kernel mode and interrupts were disabled
347 // page fault in kernel memory region
348 if (Kmem::is_kmem_page_fault(pfa, error_code))
350 // We've interrupted a context in the kernel with disabled interrupts,
351 // the page fault address is in the kernel region, the error code is
352 // "not mapped" (as opposed to "access error"), and the region is
353 // actually valid (that is, mapped in Kmem's shared page directory,
354 // just not in the currently active page directory)
357 else if (!Kmem::is_kmem_page_fault(pfa, error_code))
359 // No error -- just enable interrupts.
364 // Error: We interrupted a cli'd kernel context touching kernel space
365 if (!Thread::log_page_fault())
366 printf("*P[%lx,%lx,%lx] ", pfa, error_code & 0xffff, ip);
368 kdb_ke ("page fault in cli mode");
372 return current_thread()->handle_page_fault(pfa, error_code, ip, regs);
375 /** The catch-all trap entry point. Called by assembly code when a
376 CPU trap (that's not specially handled, such as system calls) occurs.
377 Just forwards the call to Thread::handle_slow_trap().
378 @param state trap state
379 @return 0 if trap has been consumed by handler;
380 -1 if trap could not be handled.
382 extern "C" FIASCO_FASTCALL
384 thread_handle_trap(Trap_state *ts, unsigned)
386 return current_thread()->handle_slow_trap(ts);
396 Thread::handle_sigma0_page_fault(Address pfa)
400 // Check if mapping a superpage doesn't exceed the size of physical memory
401 if (Cpu::have_superpages()
402 // Some distributions do not allow to mmap below a certain threshold
403 // (like 64k on Ubuntu 8.04) so we cannot map a superpage at 0 if
405 && (!Config::Is_ux || !(pfa < Config::SUPERPAGE_SIZE)))
407 pfa &= Config::SUPERPAGE_MASK;
408 size = Config::SUPERPAGE_SIZE;
412 pfa &= Config::PAGE_MASK;
413 size = Config::PAGE_SIZE;
416 return mem_space()->v_insert(Mem_space::Phys_addr(pfa), Mem_space::Addr(pfa),
417 Mem_space::Size(size),
418 Mem_space::Page_writable
419 | Mem_space::Page_user_accessible)
420 != Mem_space::Insert_err_nomem;
423 PRIVATE static inline
425 Thread::save_fpu_state_to_utcb(Trap_state *, Utcb *)
428 /* return 1 if this exception should be sent, return 0 if not
430 PUBLIC inline NEEDS["trap_state.h"]
432 Thread::send_exception_arch(Trap_state *ts)
434 // Do not send exception IPC but return 'not for us' if thread is a normal
435 // thread (not alien) and it's a debug trap,
436 // debug traps for aliens are always reflected as exception IPCs
437 if (!(state() & Thread_alien)
438 && (ts->_trapno == 1 || ts->_trapno == 3))
439 return 0; // we do not handle this
441 if (ts->_trapno == 3)
443 if (state() & Thread_dis_alien)
445 state_del(Thread_dis_alien);
446 return 0; // no exception
449 // set IP back on the int3 instruction
450 ts->ip(ts->ip() - 1);
453 return 1; // make it an exception
457 //----------------------------------------------------------------------------
458 IMPLEMENTATION [ia32 || amd64]:
462 Thread::vcpu_resume_user_arch()
465 //----------------------------------------------------------------------------
470 Thread::vcpu_resume_user_arch()
472 switch_gdt_user_entries(this);
475 //----------------------------------------------------------------------------
476 IMPLEMENTATION [ux || amd64]:
478 IMPLEMENT inline NEEDS[Thread::exception_triggered]
480 Thread::user_ip(Mword ip)
482 if (exception_triggered())
486 Entry_frame *r = regs();
491 //----------------------------------------------------------------------------
492 IMPLEMENTATION [(ia32,amd64,ux) && !io]:
496 Thread::handle_io_page_fault(Trap_state *)
501 Thread::get_ioport(Address /*eip*/, Trap_state * /*ts*/,
502 unsigned * /*port*/, unsigned * /*size*/)
506 //---------------------------------------------------------------------------
507 IMPLEMENTATION[ia32 || amd64]:
510 #include "fpu_alloc.h"
511 #include "fpu_state.h"
513 #include "globalconfig.h"
515 #include "simpleio.h"
516 #include "static_init.h"
517 #include "terminate.h"
519 int (*Thread::int3_handler)(Trap_state*);
520 DEFINE_PER_CPU Per_cpu<Thread::Dbg_stack> Thread::dbg_stack;
522 STATIC_INITIALIZER_P (int3_handler_init, KDB_INIT_PRIO);
528 Thread::set_int3_handler(Thread::handle_int3);
531 IMPLEMENT static inline NEEDS ["gdt.h"]
533 Thread::exception_cs()
535 return Gdt::gdt_code_user | Gdt::Selector_user;
539 * The ia32 specific part of the thread constructor.
541 PRIVATE inline NEEDS ["gdt.h"]
545 // clear out user regs that can be returned from the thread_ex_regs
546 // system call to prevent covert channel
547 Entry_frame *r = regs();
548 r->flags(EFLAGS_IOPL_K | EFLAGS_IF | 2); // ei
549 r->cs(Gdt::gdt_code_user | Gdt::Selector_user);
550 r->ss(Gdt::gdt_data_user | Gdt::Selector_user);
553 // after cs initialisation as ip() requires proper cs
558 /** A C interface for Context::handle_fpu_trap, callable from assembly code.
561 // The "FPU not available" trap entry point
564 thread_handle_fputrap()
568 return current_thread()->switchin_fpu();
573 Thread::set_int3_handler(int (*handler)(Trap_state *ts))
575 int3_handler = handler;
579 * Default handle for int3 extensions if JDB is disabled. If the JDB is
580 * available, Jdb::handle_int3_threadctx is called instead.
581 * @return 0 not handled, wait for user response
582 * 1 successfully handled
586 Thread::handle_int3(Trap_state *ts)
588 Mem_space *s = current()->mem_space();
589 int from_user = ts->cs() & 3;
590 Address ip = ts->ip();
591 Unsigned8 todo = s->peek((Unsigned8*)ip, from_user);
598 case 0xeb: // jmp == enter_kdebug()
599 len = s->peek((Unsigned8*)(ip+1), from_user);
600 str = (Unsigned8*)(ip + 2);
606 putchar(s->peek(str++, from_user));
611 case 0x90: // nop == l4kd_display()
612 if ( s->peek((Unsigned8*)(ip+1), from_user) != 0xeb /*jmp*/
613 || (len = s->peek((Unsigned8*)(ip+2), from_user)) <= 0)
616 str = (Unsigned8*)(ip + 3);
618 putchar(s->peek(str++, from_user));
622 todo = s->peek((Unsigned8*)(ip+1), from_user);
625 case 0: // l4kd_outchar
626 putchar(ts->value() & 0xff);
628 case 1: // l4kd_outnstring
629 str = (Unsigned8*)ts->value();
631 for(; len > 0; len--)
632 putchar(s->peek(str++, from_user));
634 case 2: // l4kd_outstr
635 str = (Unsigned8*)ts->value();
636 for (; (c=s->peek(str++, from_user)); )
639 case 5: // l4kd_outhex32
640 printf("%08lx", ts->value() & 0xffffffff);
642 case 6: // l4kd_outhex20
643 printf("%05lx", ts->value() & 0xfffff);
645 case 7: // l4kd_outhex16
646 printf("%04lx", ts->value() & 0xffff);
648 case 8: // l4kd_outhex12
649 printf("%03lx", ts->value() & 0xfff);
651 case 9: // l4kd_outhex8
652 printf("%02lx", ts->value() & 0xff);
654 case 11: // l4kd_outdec
655 printf("%ld", ts->value());
658 switch (ts->value2())
662 Watchdog::user_enable();
666 Watchdog::user_disable();
669 // user takes over the control of watchdog and is from now on
670 // responsible for calling "I'm still alive" events (function 5)
671 Watchdog::user_takeover_control();
674 // user returns control of watchdog to kernel
675 Watchdog::user_giveback_control();
703 Thread::check_f00f_bug(Trap_state *ts)
705 // If we page fault on the IDT, it must be because of the F00F bug.
706 // Figure out exception slot and raise the corresponding exception.
707 // XXX: Should we also modify the error code?
708 if (ts->_trapno == 14 // page fault?
709 && ts->_cr2 >= Idt::idt()
710 && ts->_cr2 < Idt::idt() + Idt::_idt_max * 8)
711 ts->_trapno = (ts->_cr2 - Idt::idt()) / 8;
717 Thread::check_io_bitmap_delimiter_fault(Trap_state *ts)
719 // check for page fault at the byte following the IO bitmap
720 if (ts->_trapno == 14 // page fault?
721 && (ts->_err & 4) == 0 // in supervisor mode?
722 && ts->ip() < Kmem::mem_user_max // delimiter byte accessed?
723 && (ts->_cr2 == Mem_layout::Io_bitmap + Mem_layout::Io_port_max / 8))
725 // page fault in the first byte following the IO bitmap
726 // map in the cpu_page read_only at the place
727 Mem_space::Status result =
728 mem_space()->v_insert(
729 Mem_space::Phys_addr(mem_space()->virt_to_phys_s0((void*)Kmem::io_bitmap_delimiter_page())),
730 Mem_space::Addr::create(Mem_layout::Io_bitmap + Mem_layout::Io_port_max / 8),
731 Mem_space::Size::create(Config::PAGE_SIZE),
736 case Mem_space::Insert_ok:
738 case Mem_space::Insert_err_nomem:
739 // kernel failure, translate this into a general protection
740 // violation and hope that somebody handles it
745 // no other error code possible
755 Thread::handle_sysenter_trap(Trap_state *ts, Address eip, bool from_user)
758 ((ts->_trapno == 6 || ts->_trapno == 13)
759 && (ts->_err & 0xffff) == 0
760 && (eip < Kmem::mem_user_max - 2)
761 && (mem_space()->peek((Unsigned16*) eip, from_user)) == 0x340f))
763 // somebody tried to do sysenter on a machine without support for it
764 WARN("tcb=%p killed:\n"
765 "\033[1;31mSYSENTER not supported on this machine\033[0m",
768 if (Cpu::have_sysenter())
769 // GP exception if sysenter is not correctly set up..
770 WARN("MSR_SYSENTER_CS: %llx", Cpu::rdmsr(MSR_SYSENTER_CS));
772 // We get UD exception on processors without SYSENTER/SYSEXIT.
773 WARN("SYSENTER/EXIT not available.");
783 Thread::handle_not_nested_trap(Trap_state *ts)
785 // no kernel debugger present
786 printf(" %p IP=" L4_PTR_FMT " Trap=%02lx [Ret/Esc]\n",
787 this, ts->ip(), ts->_trapno);
790 // cannot use normal getchar because it may block with hlt and irq's
792 while ((r = Kconsole::console()->getchar(false)) == -1)
803 Thread::sys_control_arch(Utcb *)
808 //---------------------------------------------------------------------------
809 IMPLEMENTATION [(ia32 | amd64) & (debug | kdb) & !mp]:
811 PRIVATE static inline unsigned Thread::dbg_find_cpu() { return 0; }
813 //---------------------------------------------------------------------------
814 IMPLEMENTATION [(ia32 | amd64) & (debug | kdb) & mp]:
818 PRIVATE static inline NEEDS["apic.h"]
820 Thread::dbg_find_cpu()
822 unsigned long phys_cpu = Apic::get_id();
823 unsigned log_cpu = Apic::find_cpu(phys_cpu);
826 printf("Trap on unknown CPU phys_id=%lx\n", phys_cpu);
833 //---------------------------------------------------------------------------
834 IMPLEMENTATION [(ia32 |amd64) & !(debug | kdb)]:
836 /** There is no nested trap handler if both jdb and kdb are disabled.
837 * Important: We don't need the nested_handler_stack here.
839 PRIVATE static inline
841 Thread::call_nested_trap_handler(Trap_state *)