* 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. */
| 1143 | * td_frame. |
| 1144 | */ |
| 1145 | void |
| 1146 | amd64_syscall(struct thread *td, int traced) |
| 1147 | { |
| 1148 | ksiginfo_t ksi; |
| 1149 | |
| 1150 | #ifdef DIAGNOSTIC |
| 1151 | if (!TRAPF_USERMODE(td->td_frame)) { |
| 1152 | panic("syscall"); |
| 1153 | /* NOT REACHED */ |
| 1154 | } |
| 1155 | #endif |
| 1156 | syscallenter(td); |
| 1157 | |
| 1158 | /* |
| 1159 | * Traced syscall. |
| 1160 | */ |
| 1161 | if (__predict_false(traced)) { |
| 1162 | td->td_frame->tf_rflags &= ~PSL_T; |
| 1163 | ksiginfo_init_trap(&ksi); |
| 1164 | ksi.ksi_signo = SIGTRAP; |
| 1165 | ksi.ksi_code = TRAP_TRACE; |
| 1166 | ksi.ksi_addr = (void *)td->td_frame->tf_rip; |
| 1167 | trapsignal(td, &ksi); |
| 1168 | } |
| 1169 | |
| 1170 | KASSERT(PCB_USER_FPU(td->td_pcb), |
| 1171 | ("System call %s returning with kernel FPU ctx leaked", |
| 1172 | syscallname(td->td_proc, td->td_sa.code))); |
| 1173 | KASSERT(td->td_pcb->pcb_save == get_pcb_user_save_td(td), |
| 1174 | ("System call %s returning with mangled pcb_save", |
| 1175 | syscallname(td->td_proc, td->td_sa.code))); |
| 1176 | KASSERT(pmap_not_in_di(), |
| 1177 | ("System call %s returning with leaked invl_gen %lu", |
| 1178 | syscallname(td->td_proc, td->td_sa.code), |
| 1179 | td->td_md.md_invl_gen.gen)); |
| 1180 | |
| 1181 | syscallret(td); |
| 1182 | |
| 1183 | /* |
| 1184 | * If the user-supplied value of %rip is not a canonical |
| 1185 | * address, then some CPUs will trigger a ring 0 #GP during |
| 1186 | * the sysret instruction. However, the fault handler would |
| 1187 | * execute in ring 0 with the user's %gs and %rsp which would |
| 1188 | * not be safe. Instead, use the full return path which |
| 1189 | * catches the problem safely. |
| 1190 | */ |
| 1191 | if (__predict_false(td->td_frame->tf_rip >= (la57 ? |
| 1192 | VM_MAXUSER_ADDRESS_LA57 : VM_MAXUSER_ADDRESS_LA48))) |
| 1193 | set_pcb_flags(td->td_pcb, PCB_FULL_IRET); |
| 1194 | |
| 1195 | amd64_syscall_ret_flush_l1d_check_inline(td->td_errno); |
| 1196 | } |
no test coverage detected