FreeBSD/sys/amd64/amd64/trap.c
/*
 * System call handler for native binaries.  The trap frame is already
 * set up by the assembler trampoline and a pointer to it is saved in
 * td_frame.
 */
System call handler for native binaries.  The trap frame is already
set up by the assembler trampoline and a pointer to it is saved in
td_frame.
System call handler for native binaries . The trap frame is already set up by the assembler trampoline and a pointer to it is saved in td_frame .
void
amd64_syscall(struct thread *td, int traced)
{
	struct syscall_args sa;
	int error;
	ksiginfo_t ksi;
#ifdef DIAGNOSTIC
	if (ISPL(td->td_frame->tf_cs) != SEL_UPL) {
		panic("syscall");
	}
#endif
	error = syscallenter(td, &sa);
	if (__predict_false(traced)) {
		td->td_frame->tf_rflags &= ~PSL_T;
		ksiginfo_init_trap(&ksi);
		ksi.ksi_signo = SIGTRAP;
		ksi.ksi_code = TRAP_TRACE;
		ksi.ksi_addr = (void *)td->td_frame->tf_rip;
		trapsignal(td, &ksi);
	}
	KASSERT(PCB_USER_FPU(td->td_pcb),
	    ("System call %s returing with kernel FPU ctx leaked",
	     syscallname(td->td_proc, sa.code)));
	KASSERT(td->td_pcb->pcb_save == get_pcb_user_save_td(td),
	    ("System call %s returning with mangled pcb_save",
	     syscallname(td->td_proc, sa.code)));
	KASSERT(td->td_md.md_invl_gen.gen == 0,
	    ("System call %s returning with leaked invl_gen %lu",
	    syscallname(td->td_proc, sa.code), td->td_md.md_invl_gen.gen));
	syscallret(td, error, &sa);
	if (td->td_frame->tf_rip >= VM_MAXUSER_ADDRESS)
		set_pcb_flags(td->td_pcb, PCB_FULL_IRET);
}
void amd64_syscall ( struct thread * td , int traced ) { struct syscall_args sa ; int error ; ksiginfo_t ksi ; #ifdef DIAGNOSTIC if ( ISPL ( td -> td_frame -> tf_cs ) != SEL_UPL ) { panic ( " " ) ; } #endif error = syscallenter ( td , & sa ) ; if ( __predict_false ( traced ) ) { td -> td_frame -> tf_rflags &= ~ PSL_T ; ksiginfo_init_trap ( & ksi ) ; ksi . ksi_signo = SIGTRAP ; ksi . ksi_code = TRAP_TRACE ; ksi . ksi_addr = ( void * ) td -> td_frame -> tf_rip ; trapsignal ( td , & ksi ) ; } KASSERT ( PCB_USER_FPU ( td -> td_pcb ) , ( " " , syscallname ( td -> td_proc , sa . code ) ) ) ; KASSERT ( td -> td_pcb -> pcb_save == get_pcb_user_save_td ( td ) , ( " " , syscallname ( td -> td_proc , sa . code ) ) ) ; KASSERT ( td -> td_md . md_invl_gen . gen == 0 , ( " " , syscallname ( td -> td_proc , sa . code ) , td -> td_md . md_invl_gen . gen ) ) ; syscallret ( td , error , & sa ) ; if ( td -> td_frame -> tf_rip >= VM_MAXUSER_ADDRESS ) set_pcb_flags ( td -> td_pcb , PCB_FULL_IRET ) ; }
System call handler for native binaries.
System call handler for native binaries .
/* NOT REACHED */ /*
	 * Traced syscall.
	 */ /*
	 * If the user-supplied value of %rip is not a canonical
	 * address, then some CPUs will trigger a ring 0 #GP during
	 * the sysret instruction.  However, the fault handler would
	 * execute in ring 0 with the user's %gs and %rsp which would
	 * not be safe.  Instead, use the full return path which
	 * catches the problem safely.
	 */