1114987Speter/*- 2114987Speter * Copyright (C) 1994, David Greenman 3114987Speter * Copyright (c) 1990, 1993 4114987Speter * The Regents of the University of California. All rights reserved. 5114987Speter * 6114987Speter * This code is derived from software contributed to Berkeley by 7114987Speter * the University of Utah, and William Jolitz. 8114987Speter * 9114987Speter * Redistribution and use in source and binary forms, with or without 10114987Speter * modification, are permitted provided that the following conditions 11114987Speter * are met: 12114987Speter * 1. Redistributions of source code must retain the above copyright 13114987Speter * notice, this list of conditions and the following disclaimer. 14114987Speter * 2. Redistributions in binary form must reproduce the above copyright 15114987Speter * notice, this list of conditions and the following disclaimer in the 16114987Speter * documentation and/or other materials provided with the distribution. 17114987Speter * 3. All advertising materials mentioning features or use of this software 18114987Speter * must display the following acknowledgement: 19114987Speter * This product includes software developed by the University of 20114987Speter * California, Berkeley and its contributors. 21114987Speter * 4. Neither the name of the University nor the names of its contributors 22114987Speter * may be used to endorse or promote products derived from this software 23114987Speter * without specific prior written permission. 24114987Speter * 25114987Speter * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 26114987Speter * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27114987Speter * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28114987Speter * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 29114987Speter * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30114987Speter * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31114987Speter * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32114987Speter * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33114987Speter * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34114987Speter * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35114987Speter * SUCH DAMAGE. 36114987Speter */ 37114987Speter 38118031Sobrien#include <sys/cdefs.h> 39118031Sobrien__FBSDID("$FreeBSD: releng/10.3/sys/amd64/ia32/ia32_syscall.c 276601 2015-01-03 01:41:10Z kib $"); 40118031Sobrien 41114987Speter/* 42114987Speter * 386 Trap and System call handling 43114987Speter */ 44114987Speter 45114987Speter#include "opt_clock.h" 46220238Skib#include "opt_compat.h" 47114987Speter#include "opt_cpu.h" 48114987Speter#include "opt_isa.h" 49114987Speter 50114987Speter#include <sys/param.h> 51114987Speter#include <sys/bus.h> 52114987Speter#include <sys/systm.h> 53114987Speter#include <sys/proc.h> 54114987Speter#include <sys/pioctl.h> 55114987Speter#include <sys/kernel.h> 56114987Speter#include <sys/ktr.h> 57114987Speter#include <sys/lock.h> 58114987Speter#include <sys/mutex.h> 59208453Skib#include <sys/proc.h> 60160764Sjhb#include <sys/ptrace.h> 61114987Speter#include <sys/resourcevar.h> 62114987Speter#include <sys/signalvar.h> 63114987Speter#include <sys/syscall.h> 64114987Speter#include <sys/sysctl.h> 65114987Speter#include <sys/sysent.h> 66114987Speter#include <sys/uio.h> 67114987Speter#include <sys/vmmeter.h> 68155313Swsalamon#include <security/audit/audit.h> 69114987Speter 70114987Speter#include <vm/vm.h> 71114987Speter#include <vm/vm_param.h> 72114987Speter#include <vm/pmap.h> 73114987Speter#include <vm/vm_kern.h> 74114987Speter#include <vm/vm_map.h> 75114987Speter#include <vm/vm_page.h> 76114987Speter#include <vm/vm_extern.h> 77114987Speter 78114987Speter#include <machine/cpu.h> 79122849Speter#include <machine/intr_machdep.h> 80114987Speter#include <machine/md_var.h> 81114987Speter 82220238Skib#include <compat/freebsd32/freebsd32_signal.h> 83208453Skib#include <compat/freebsd32/freebsd32_util.h> 84220238Skib#include <compat/ia32/ia32_signal.h> 85220238Skib#include <machine/psl.h> 86220238Skib#include <machine/segments.h> 87220238Skib#include <machine/specialreg.h> 88220238Skib#include <machine/sysarch.h> 89220238Skib#include <machine/frame.h> 90220238Skib#include <machine/md_var.h> 91220238Skib#include <machine/pcb.h> 92220238Skib#include <machine/cpufunc.h> 93208453Skib 94114987Speter#define IDTVEC(name) __CONCAT(X,name) 95114987Speter 96114987Speterextern inthand_t IDTVEC(int0x80_syscall), IDTVEC(rsvd); 97114987Speter 98165303Skmacyvoid ia32_syscall(struct trapframe *frame); /* Called from asm code */ 99114987Speter 100208453Skibvoid 101208453Skibia32_set_syscall_retval(struct thread *td, int error) 102208453Skib{ 103202882Skib 104208453Skib cpu_set_syscall_retval(td, error); 105208453Skib} 106208453Skib 107208453Skibint 108208453Skibia32_fetch_syscall_args(struct thread *td, struct syscall_args *sa) 109202882Skib{ 110202882Skib struct proc *p; 111202882Skib struct trapframe *frame; 112208453Skib caddr_t params; 113274648Skib u_int32_t args[8], tmp; 114202882Skib int error, i; 115114987Speter 116202882Skib p = td->td_proc; 117202882Skib frame = td->td_frame; 118114987Speter 119208453Skib params = (caddr_t)frame->tf_rsp + sizeof(u_int32_t); 120202882Skib sa->code = frame->tf_rax; 121202882Skib 122208453Skib /* 123208453Skib * Need to check if this is a 32 bit or 64 bit syscall. 124208453Skib */ 125208453Skib if (sa->code == SYS_syscall) { 126114987Speter /* 127208453Skib * Code is first argument, followed by actual args. 128114987Speter */ 129274648Skib error = fueword32(params, &tmp); 130274648Skib if (error == -1) 131274648Skib return (EFAULT); 132274648Skib sa->code = tmp; 133208453Skib params += sizeof(int); 134208453Skib } else if (sa->code == SYS___syscall) { 135114987Speter /* 136208453Skib * Like syscall, but code is a quad, so as to maintain 137208453Skib * quad alignment for the rest of the arguments. 138208453Skib * We use a 32-bit fetch in case params is not 139208453Skib * aligned. 140114987Speter */ 141274648Skib error = fueword32(params, &tmp); 142274648Skib if (error == -1) 143274648Skib return (EFAULT); 144274648Skib sa->code = tmp; 145208453Skib params += sizeof(quad_t); 146114987Speter } 147114987Speter if (p->p_sysent->sv_mask) 148202882Skib sa->code &= p->p_sysent->sv_mask; 149202882Skib if (sa->code >= p->p_sysent->sv_size) 150202882Skib sa->callp = &p->p_sysent->sv_table[0]; 151114987Speter else 152202882Skib sa->callp = &p->p_sysent->sv_table[sa->code]; 153202882Skib sa->narg = sa->callp->sy_narg; 154114987Speter 155208453Skib if (params != NULL && sa->narg != 0) 156208453Skib error = copyin(params, (caddr_t)args, 157202882Skib (u_int)(sa->narg * sizeof(int))); 158114987Speter else 159114987Speter error = 0; 160114987Speter 161202882Skib for (i = 0; i < sa->narg; i++) 162208453Skib sa->args[i] = args[i]; 163114987Speter 164208453Skib if (error == 0) { 165208453Skib td->td_retval[0] = 0; 166208453Skib td->td_retval[1] = frame->tf_rdx; 167208453Skib } 168202882Skib 169202882Skib return (error); 170202882Skib} 171202882Skib 172225474Skib#include "../../kern/subr_syscall.c" 173225474Skib 174202882Skibvoid 175202882Skibia32_syscall(struct trapframe *frame) 176202882Skib{ 177202882Skib struct thread *td; 178208453Skib struct syscall_args sa; 179202882Skib register_t orig_tf_rflags; 180202882Skib int error; 181202882Skib ksiginfo_t ksi; 182202882Skib 183208453Skib orig_tf_rflags = frame->tf_rflags; 184202882Skib td = curthread; 185202882Skib td->td_frame = frame; 186202882Skib 187208453Skib error = syscallenter(td, &sa); 188160770Sjhb 189114987Speter /* 190114987Speter * Traced syscall. 191114987Speter */ 192114987Speter if (orig_tf_rflags & PSL_T) { 193165303Skmacy frame->tf_rflags &= ~PSL_T; 194151316Sdavidxu ksiginfo_init_trap(&ksi); 195151316Sdavidxu ksi.ksi_signo = SIGTRAP; 196151316Sdavidxu ksi.ksi_code = TRAP_TRACE; 197165303Skmacy ksi.ksi_addr = (void *)frame->tf_rip; 198151316Sdavidxu trapsignal(td, &ksi); 199114987Speter } 200114987Speter 201208453Skib syscallret(td, error, &sa); 202114987Speter} 203114987Speter 204114987Speterstatic void 205114987Speteria32_syscall_enable(void *dummy) 206114987Speter{ 207114987Speter 208120346Speter setidt(IDT_SYSCALL, &IDTVEC(int0x80_syscall), SDT_SYSIGT, SEL_UPL, 0); 209114987Speter} 210114987Speter 211114987Speterstatic void 212114987Speteria32_syscall_disable(void *dummy) 213114987Speter{ 214114987Speter 215120346Speter setidt(IDT_SYSCALL, &IDTVEC(rsvd), SDT_SYSIGT, SEL_KPL, 0); 216114987Speter} 217114987Speter 218114987SpeterSYSINIT(ia32_syscall, SI_SUB_EXEC, SI_ORDER_ANY, ia32_syscall_enable, NULL); 219114987SpeterSYSUNINIT(ia32_syscall, SI_SUB_EXEC, SI_ORDER_ANY, ia32_syscall_disable, NULL); 220220238Skib 221220238Skib#ifdef COMPAT_43 222220238Skibint 223220238Skibsetup_lcall_gate(void) 224220238Skib{ 225220238Skib struct i386_ldt_args uap; 226276601Skib struct user_segment_descriptor desc; 227220238Skib uint32_t lcall_addr; 228220238Skib int error; 229220238Skib 230220238Skib bzero(&uap, sizeof(uap)); 231220238Skib uap.start = 0; 232276601Skib uap.num = 1; 233276601Skib lcall_addr = curproc->p_sysent->sv_psstrings - sz_lcall_tramp; 234276601Skib bzero(&desc, sizeof(desc)); 235276601Skib desc.sd_type = SDT_MEMERA; 236276601Skib desc.sd_dpl = SEL_UPL; 237276601Skib desc.sd_p = 1; 238276601Skib desc.sd_def32 = 1; 239276601Skib desc.sd_gran = 1; 240276601Skib desc.sd_lolimit = 0xffff; 241276601Skib desc.sd_hilimit = 0xf; 242276601Skib desc.sd_lobase = lcall_addr; 243276601Skib desc.sd_hibase = lcall_addr >> 24; 244276601Skib error = amd64_set_ldt(curthread, &uap, &desc); 245220238Skib if (error != 0) 246220238Skib return (error); 247220238Skib 248220238Skib return (0); 249220238Skib} 250220238Skib#endif 251