Merge from sys/i386/i386/machdep.c 1.480 (Julian's KSE changes)

Reviewed by: julian, bde, jhb
This commit is contained in:
Warner Losh 2001-09-14 04:27:42 +00:00
parent 2af8d76dad
commit 2fb670e0b5
2 changed files with 148 additions and 156 deletions

View File

@ -302,14 +302,16 @@ osendsig(catcher, sig, mask, code)
struct osigframe sf; struct osigframe sf;
struct osigframe *fp; struct osigframe *fp;
struct proc *p; struct proc *p;
struct thread *td;
struct sigacts *psp; struct sigacts *psp;
struct trapframe *regs; struct trapframe *regs;
int oonstack; int oonstack;
p = curproc; td = curthread;
p = td->td_proc;
PROC_LOCK_ASSERT(p, MA_OWNED); PROC_LOCK_ASSERT(p, MA_OWNED);
psp = p->p_sigacts; psp = p->p_sigacts;
regs = p->p_frame; regs = td->td_frame;
oonstack = sigonstack(regs->tf_esp); oonstack = sigonstack(regs->tf_esp);
/* Allocate and validate space for the signal handler context. */ /* Allocate and validate space for the signal handler context. */
@ -399,7 +401,7 @@ osendsig(catcher, sig, mask, code)
if (regs->tf_eflags & PSL_VM) { if (regs->tf_eflags & PSL_VM) {
/* XXX confusing names: `tf' isn't a trapframe; `regs' is. */ /* XXX confusing names: `tf' isn't a trapframe; `regs' is. */
struct trapframe_vm86 *tf = (struct trapframe_vm86 *)regs; struct trapframe_vm86 *tf = (struct trapframe_vm86 *)regs;
struct vm86_kernel *vm86 = &p->p_addr->u_pcb.pcb_ext->ext_vm86; struct vm86_kernel *vm86 = &td->td_pcb->pcb_ext->ext_vm86;
sf.sf_siginfo.si_sc.sc_gs = tf->tf_vm86_gs; sf.sf_siginfo.si_sc.sc_gs = tf->tf_vm86_gs;
sf.sf_siginfo.si_sc.sc_fs = tf->tf_vm86_fs; sf.sf_siginfo.si_sc.sc_fs = tf->tf_vm86_fs;
@ -422,7 +424,7 @@ osendsig(catcher, sig, mask, code)
* ...Kill the process. * ...Kill the process.
*/ */
PROC_LOCK(p); PROC_LOCK(p);
sigexit(p, SIGILL); sigexit(td, SIGILL);
/* NOTREACHED */ /* NOTREACHED */
} }
@ -447,12 +449,14 @@ sendsig(catcher, sig, mask, code)
{ {
struct sigframe sf; struct sigframe sf;
struct proc *p; struct proc *p;
struct thread *td;
struct sigacts *psp; struct sigacts *psp;
struct trapframe *regs; struct trapframe *regs;
struct sigframe *sfp; struct sigframe *sfp;
int oonstack; int oonstack;
p = curproc; td = curthread;
p = td->td_proc;
PROC_LOCK_ASSERT(p, MA_OWNED); PROC_LOCK_ASSERT(p, MA_OWNED);
psp = p->p_sigacts; psp = p->p_sigacts;
#ifdef COMPAT_43 #ifdef COMPAT_43
@ -461,7 +465,7 @@ sendsig(catcher, sig, mask, code)
return; return;
} }
#endif #endif
regs = p->p_frame; regs = td->td_frame;
oonstack = sigonstack(regs->tf_esp); oonstack = sigonstack(regs->tf_esp);
/* Save user context. */ /* Save user context. */
@ -541,7 +545,7 @@ sendsig(catcher, sig, mask, code)
*/ */
if (regs->tf_eflags & PSL_VM) { if (regs->tf_eflags & PSL_VM) {
struct trapframe_vm86 *tf = (struct trapframe_vm86 *)regs; struct trapframe_vm86 *tf = (struct trapframe_vm86 *)regs;
struct vm86_kernel *vm86 = &p->p_addr->u_pcb.pcb_ext->ext_vm86; struct vm86_kernel *vm86 = &td->td_pcb->pcb_ext->ext_vm86;
sf.sf_uc.uc_mcontext.mc_gs = tf->tf_vm86_gs; sf.sf_uc.uc_mcontext.mc_gs = tf->tf_vm86_gs;
sf.sf_uc.uc_mcontext.mc_fs = tf->tf_vm86_fs; sf.sf_uc.uc_mcontext.mc_fs = tf->tf_vm86_fs;
@ -574,7 +578,7 @@ sendsig(catcher, sig, mask, code)
* ...Kill the process. * ...Kill the process.
*/ */
PROC_LOCK(p); PROC_LOCK(p);
sigexit(p, SIGILL); sigexit(td, SIGILL);
/* NOTREACHED */ /* NOTREACHED */
} }
@ -599,17 +603,18 @@ sendsig(catcher, sig, mask, code)
*/ */
#ifdef COMPAT_43 #ifdef COMPAT_43
int int
osigreturn(p, uap) osigreturn(td, uap)
struct proc *p; struct thread *td;
struct osigreturn_args /* { struct osigreturn_args /* {
struct osigcontext *sigcntxp; struct osigcontext *sigcntxp;
} */ *uap; } */ *uap;
{ {
struct trapframe *regs; struct trapframe *regs;
struct osigcontext *scp; struct osigcontext *scp;
struct proc *p = td->td_proc;
int eflags; int eflags;
regs = p->p_frame; regs = td->td_frame;
scp = uap->sigcntxp; scp = uap->sigcntxp;
if (!useracc((caddr_t)scp, sizeof(*scp), VM_PROT_READ)) if (!useracc((caddr_t)scp, sizeof(*scp), VM_PROT_READ))
return (EFAULT); return (EFAULT);
@ -622,9 +627,9 @@ osigreturn(p, uap)
* if pcb_ext == 0 or vm86_inited == 0, the user hasn't * if pcb_ext == 0 or vm86_inited == 0, the user hasn't
* set up the vm86 area, and we can't enter vm86 mode. * set up the vm86 area, and we can't enter vm86 mode.
*/ */
if (p->p_addr->u_pcb.pcb_ext == 0) if (td->td_pcb->pcb_ext == 0)
return (EINVAL); return (EINVAL);
vm86 = &p->p_addr->u_pcb.pcb_ext->ext_vm86; vm86 = &td->td_pcb->pcb_ext->ext_vm86;
if (vm86->vm86_inited == 0) if (vm86->vm86_inited == 0)
return (EINVAL); return (EINVAL);
@ -710,12 +715,13 @@ osigreturn(p, uap)
#endif #endif
int int
sigreturn(p, uap) sigreturn(td, uap)
struct proc *p; struct thread *td;
struct sigreturn_args /* { struct sigreturn_args /* {
ucontext_t *sigcntxp; ucontext_t *sigcntxp;
} */ *uap; } */ *uap;
{ {
struct proc *p = td->td_proc;
struct trapframe *regs; struct trapframe *regs;
ucontext_t *ucp; ucontext_t *ucp;
int cs, eflags; int cs, eflags;
@ -725,7 +731,7 @@ sigreturn(p, uap)
if (!useracc((caddr_t)ucp, sizeof(struct osigcontext), VM_PROT_READ)) if (!useracc((caddr_t)ucp, sizeof(struct osigcontext), VM_PROT_READ))
return (EFAULT); return (EFAULT);
if (((struct osigcontext *)ucp)->sc_trapno == 0x01d516) if (((struct osigcontext *)ucp)->sc_trapno == 0x01d516)
return (osigreturn(p, (struct osigreturn_args *)uap)); return (osigreturn(td, (struct osigreturn_args *)uap));
/* /*
* Since ucp is not an osigcontext but a ucontext_t, we have to * Since ucp is not an osigcontext but a ucontext_t, we have to
* check again if all of it is accessible. A ucontext_t is * check again if all of it is accessible. A ucontext_t is
@ -737,7 +743,7 @@ sigreturn(p, uap)
if (!useracc((caddr_t)ucp, sizeof(*ucp), VM_PROT_READ)) if (!useracc((caddr_t)ucp, sizeof(*ucp), VM_PROT_READ))
return (EFAULT); return (EFAULT);
regs = p->p_frame; regs = td->td_frame;
eflags = ucp->uc_mcontext.mc_eflags; eflags = ucp->uc_mcontext.mc_eflags;
if (eflags & PSL_VM) { if (eflags & PSL_VM) {
struct trapframe_vm86 *tf = (struct trapframe_vm86 *)regs; struct trapframe_vm86 *tf = (struct trapframe_vm86 *)regs;
@ -747,9 +753,9 @@ sigreturn(p, uap)
* if pcb_ext == 0 or vm86_inited == 0, the user hasn't * if pcb_ext == 0 or vm86_inited == 0, the user hasn't
* set up the vm86 area, and we can't enter vm86 mode. * set up the vm86 area, and we can't enter vm86 mode.
*/ */
if (p->p_addr->u_pcb.pcb_ext == 0) if (td->td_pcb->pcb_ext == 0)
return (EINVAL); return (EINVAL);
vm86 = &p->p_addr->u_pcb.pcb_ext->ext_vm86; vm86 = &td->td_pcb->pcb_ext->ext_vm86;
if (vm86->vm86_inited == 0) if (vm86->vm86_inited == 0)
return (EINVAL); return (EINVAL);
@ -878,14 +884,14 @@ cpu_idle(void)
* Clear registers on exec * Clear registers on exec
*/ */
void void
setregs(p, entry, stack, ps_strings) setregs(td, entry, stack, ps_strings)
struct proc *p; struct thread *td;
u_long entry; u_long entry;
u_long stack; u_long stack;
u_long ps_strings; u_long ps_strings;
{ {
struct trapframe *regs = p->p_frame; struct trapframe *regs = td->td_frame;
struct pcb *pcb = &p->p_addr->u_pcb; struct pcb *pcb = td->td_pcb;
if (pcb->pcb_ldt) if (pcb->pcb_ldt)
user_ldt_free(pcb); user_ldt_free(pcb);
@ -938,7 +944,7 @@ setregs(p, entry, stack, ps_strings)
* traps to the emulator (if it is done at all) mainly because * traps to the emulator (if it is done at all) mainly because
* emulators don't provide an entry point for initialization. * emulators don't provide an entry point for initialization.
*/ */
p->p_addr->u_pcb.pcb_flags &= ~FP_SOFTFP; td->td_pcb->pcb_flags &= ~FP_SOFTFP;
/* /*
* Arrange to trap the next npx or `fwait' instruction (see npx.c * Arrange to trap the next npx or `fwait' instruction (see npx.c
@ -961,7 +967,7 @@ setregs(p, entry, stack, ps_strings)
* Make sure sure edx is 0x0 on entry. Linux binaries depend * Make sure sure edx is 0x0 on entry. Linux binaries depend
* on it. * on it.
*/ */
p->p_retval[1] = 0; td->td_retval[1] = 0;
} }
void void
@ -1029,7 +1035,8 @@ extern int has_f00f_bug;
static struct i386tss dblfault_tss; static struct i386tss dblfault_tss;
static char dblfault_stack[PAGE_SIZE]; static char dblfault_stack[PAGE_SIZE];
extern struct user *proc0paddr; extern struct user *proc0uarea;
extern vm_offset_t proc0kstack;
/* software prototypes -- in more palatable form */ /* software prototypes -- in more palatable form */
@ -1718,8 +1725,12 @@ init386(first)
struct region_descriptor r_gdt, r_idt; struct region_descriptor r_gdt, r_idt;
#endif #endif
proc0.p_addr = proc0paddr; proc_linkup(&proc0);
proc0.p_uarea = proc0uarea;
thread0 = &proc0.p_thread;
thread0->td_kstack = proc0kstack;
thread0->td_pcb = (struct pcb *)
(thread0->td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1;
atdevbase = ISA_HOLE_START + KERNBASE; atdevbase = ISA_HOLE_START + KERNBASE;
#ifdef PC98 #ifdef PC98
@ -1785,10 +1796,11 @@ init386(first)
lgdt(&r_gdt); lgdt(&r_gdt);
/* setup curproc so that mutexes work */ /* setup curproc so that mutexes work */
PCPU_SET(curproc, &proc0);
PCPU_SET(curthread, thread0);
PCPU_SET(spinlocks, NULL); PCPU_SET(spinlocks, NULL);
LIST_INIT(&proc0.p_contested); LIST_INIT(&thread0->td_contested);
/* /*
* Initialize mutexes. * Initialize mutexes.
@ -1892,8 +1904,9 @@ init386(first)
initializecpu(); /* Initialize CPU registers */ initializecpu(); /* Initialize CPU registers */
/* make an initial tss so cpu can get interrupt stack on syscall! */ /* make an initial tss so cpu can get interrupt stack on syscall! */
PCPU_SET(common_tss.tss_esp0, /* Note: -16 is so we can grow the trapframe if we came from vm86 */
(int) proc0.p_addr + UPAGES*PAGE_SIZE - 16); PCPU_SET(common_tss.tss_esp0, thread0->td_kstack +
KSTACK_PAGES * PAGE_SIZE - sizeof(struct pcb) - 16);
PCPU_SET(common_tss.tss_ss0, GSEL(GDATA_SEL, SEL_KPL)); PCPU_SET(common_tss.tss_ss0, GSEL(GDATA_SEL, SEL_KPL));
gsel_tss = GSEL(GPROC0_SEL, SEL_KPL); gsel_tss = GSEL(GPROC0_SEL, SEL_KPL);
private_tss = 0; private_tss = 0;
@ -1948,10 +1961,10 @@ init386(first)
_udatasel = LSEL(LUDATA_SEL, SEL_UPL); _udatasel = LSEL(LUDATA_SEL, SEL_UPL);
/* setup proc 0's pcb */ /* setup proc 0's pcb */
proc0.p_addr->u_pcb.pcb_flags = 0; thread0->td_pcb->pcb_flags = 0; /* XXXKSE */
proc0.p_addr->u_pcb.pcb_cr3 = (int)IdlePTD; thread0->td_pcb->pcb_cr3 = (int)IdlePTD;
proc0.p_addr->u_pcb.pcb_ext = 0; thread0->td_pcb->pcb_ext = 0;
proc0.p_frame = &proc0_tf; thread0->td_frame = &proc0_tf;
} }
#if defined(I586_CPU) && !defined(NO_F00F_HACK) #if defined(I586_CPU) && !defined(NO_F00F_HACK)
@ -1994,31 +2007,26 @@ f00f_hack(void *unused) {
#endif /* defined(I586_CPU) && !NO_F00F_HACK */ #endif /* defined(I586_CPU) && !NO_F00F_HACK */
int int
ptrace_set_pc(p, addr) ptrace_set_pc(struct thread *td, unsigned long addr)
struct proc *p;
unsigned long addr;
{ {
p->p_frame->tf_eip = addr; td->td_frame->tf_eip = addr;
return (0); return (0);
} }
int int
ptrace_single_step(p) ptrace_single_step(struct thread *td)
struct proc *p;
{ {
p->p_frame->tf_eflags |= PSL_T; td->td_frame->tf_eflags |= PSL_T;
return (0); return (0);
} }
int int
fill_regs(p, regs) fill_regs(struct thread *td, struct reg *regs)
struct proc *p;
struct reg *regs;
{ {
struct pcb *pcb; struct pcb *pcb;
struct trapframe *tp; struct trapframe *tp;
tp = p->p_frame; tp = td->td_frame;
regs->r_fs = tp->tf_fs; regs->r_fs = tp->tf_fs;
regs->r_es = tp->tf_es; regs->r_es = tp->tf_es;
regs->r_ds = tp->tf_ds; regs->r_ds = tp->tf_ds;
@ -2034,20 +2042,18 @@ fill_regs(p, regs)
regs->r_eflags = tp->tf_eflags; regs->r_eflags = tp->tf_eflags;
regs->r_esp = tp->tf_esp; regs->r_esp = tp->tf_esp;
regs->r_ss = tp->tf_ss; regs->r_ss = tp->tf_ss;
pcb = &p->p_addr->u_pcb; pcb = td->td_pcb;
regs->r_gs = pcb->pcb_gs; regs->r_gs = pcb->pcb_gs;
return (0); return (0);
} }
int int
set_regs(p, regs) set_regs(struct thread *td, struct reg *regs)
struct proc *p;
struct reg *regs;
{ {
struct pcb *pcb; struct pcb *pcb;
struct trapframe *tp; struct trapframe *tp;
tp = p->p_frame; tp = td->td_frame;
if (!EFL_SECURE(regs->r_eflags, tp->tf_eflags) || if (!EFL_SECURE(regs->r_eflags, tp->tf_eflags) ||
!CS_SECURE(regs->r_cs)) !CS_SECURE(regs->r_cs))
return (EINVAL); return (EINVAL);
@ -2066,7 +2072,7 @@ set_regs(p, regs)
tp->tf_eflags = regs->r_eflags; tp->tf_eflags = regs->r_eflags;
tp->tf_esp = regs->r_esp; tp->tf_esp = regs->r_esp;
tp->tf_ss = regs->r_ss; tp->tf_ss = regs->r_ss;
pcb = &p->p_addr->u_pcb; pcb = td->td_pcb;
pcb->pcb_gs = regs->r_gs; pcb->pcb_gs = regs->r_gs;
return (0); return (0);
} }
@ -2126,45 +2132,39 @@ set_fpregs_xmm(sv_87, sv_xmm)
#endif /* CPU_ENABLE_SSE */ #endif /* CPU_ENABLE_SSE */
int int
fill_fpregs(p, fpregs) fill_fpregs(struct thread *td, struct fpreg *fpregs)
struct proc *p;
struct fpreg *fpregs;
{ {
#ifdef CPU_ENABLE_SSE #ifdef CPU_ENABLE_SSE
if (cpu_fxsr) { if (cpu_fxsr) {
fill_fpregs_xmm(&p->p_addr->u_pcb.pcb_save.sv_xmm, fill_fpregs_xmm(&td->td_pcb->pcb_save.sv_xmm,
(struct save87 *)fpregs); (struct save87 *)fpregs);
return (0); return (0);
} }
#endif /* CPU_ENABLE_SSE */ #endif /* CPU_ENABLE_SSE */
bcopy(&p->p_addr->u_pcb.pcb_save.sv_87, fpregs, sizeof *fpregs); bcopy(&td->td_pcb->pcb_save.sv_87, fpregs, sizeof *fpregs);
return (0); return (0);
} }
int int
set_fpregs(p, fpregs) set_fpregs(struct thread *td, struct fpreg *fpregs)
struct proc *p;
struct fpreg *fpregs;
{ {
#ifdef CPU_ENABLE_SSE #ifdef CPU_ENABLE_SSE
if (cpu_fxsr) { if (cpu_fxsr) {
set_fpregs_xmm((struct save87 *)fpregs, set_fpregs_xmm((struct save87 *)fpregs,
&p->p_addr->u_pcb.pcb_save.sv_xmm); &td->td_pcb->pcb_save.sv_xmm);
return (0); return (0);
} }
#endif /* CPU_ENABLE_SSE */ #endif /* CPU_ENABLE_SSE */
bcopy(fpregs, &p->p_addr->u_pcb.pcb_save.sv_87, sizeof *fpregs); bcopy(fpregs, &td->td_pcb->pcb_save.sv_87, sizeof *fpregs);
return (0); return (0);
} }
int int
fill_dbregs(p, dbregs) fill_dbregs(struct thread *td, struct dbreg *dbregs)
struct proc *p;
struct dbreg *dbregs;
{ {
struct pcb *pcb; struct pcb *pcb;
if (p == NULL) { if (td == NULL) {
dbregs->dr0 = rdr0(); dbregs->dr0 = rdr0();
dbregs->dr1 = rdr1(); dbregs->dr1 = rdr1();
dbregs->dr2 = rdr2(); dbregs->dr2 = rdr2();
@ -2173,9 +2173,8 @@ fill_dbregs(p, dbregs)
dbregs->dr5 = rdr5(); dbregs->dr5 = rdr5();
dbregs->dr6 = rdr6(); dbregs->dr6 = rdr6();
dbregs->dr7 = rdr7(); dbregs->dr7 = rdr7();
} } else {
else { pcb = td->td_pcb;
pcb = &p->p_addr->u_pcb;
dbregs->dr0 = pcb->pcb_dr0; dbregs->dr0 = pcb->pcb_dr0;
dbregs->dr1 = pcb->pcb_dr1; dbregs->dr1 = pcb->pcb_dr1;
dbregs->dr2 = pcb->pcb_dr2; dbregs->dr2 = pcb->pcb_dr2;
@ -2189,15 +2188,13 @@ fill_dbregs(p, dbregs)
} }
int int
set_dbregs(p, dbregs) set_dbregs(struct thread *td, struct dbreg *dbregs)
struct proc *p;
struct dbreg *dbregs;
{ {
struct pcb *pcb; struct pcb *pcb;
int i; int i;
u_int32_t mask1, mask2; u_int32_t mask1, mask2;
if (p == NULL) { if (td == NULL) {
load_dr0(dbregs->dr0); load_dr0(dbregs->dr0);
load_dr1(dbregs->dr1); load_dr1(dbregs->dr1);
load_dr2(dbregs->dr2); load_dr2(dbregs->dr2);
@ -2206,8 +2203,7 @@ set_dbregs(p, dbregs)
load_dr5(dbregs->dr5); load_dr5(dbregs->dr5);
load_dr6(dbregs->dr6); load_dr6(dbregs->dr6);
load_dr7(dbregs->dr7); load_dr7(dbregs->dr7);
} } else {
else {
/* /*
* Don't let an illegal value for dr7 get set. Specifically, * Don't let an illegal value for dr7 get set. Specifically,
* check for undefined settings. Setting these bit patterns * check for undefined settings. Setting these bit patterns
@ -2219,7 +2215,7 @@ set_dbregs(p, dbregs)
if ((dbregs->dr7 & mask1) == mask2) if ((dbregs->dr7 & mask1) == mask2)
return (EINVAL); return (EINVAL);
pcb = &p->p_addr->u_pcb; pcb = td->td_pcb;
/* /*
* Don't let a process set a breakpoint that is not within the * Don't let a process set a breakpoint that is not within the
@ -2236,7 +2232,7 @@ set_dbregs(p, dbregs)
* from within kernel mode? * from within kernel mode?
*/ */
if (suser(p) != 0) { if (suser_td(td) != 0) {
if (dbregs->dr7 & 0x3) { if (dbregs->dr7 & 0x3) {
/* dr0 is enabled */ /* dr0 is enabled */
if (dbregs->dr0 >= VM_MAXUSER_ADDRESS) if (dbregs->dr0 >= VM_MAXUSER_ADDRESS)

View File

@ -302,14 +302,16 @@ osendsig(catcher, sig, mask, code)
struct osigframe sf; struct osigframe sf;
struct osigframe *fp; struct osigframe *fp;
struct proc *p; struct proc *p;
struct thread *td;
struct sigacts *psp; struct sigacts *psp;
struct trapframe *regs; struct trapframe *regs;
int oonstack; int oonstack;
p = curproc; td = curthread;
p = td->td_proc;
PROC_LOCK_ASSERT(p, MA_OWNED); PROC_LOCK_ASSERT(p, MA_OWNED);
psp = p->p_sigacts; psp = p->p_sigacts;
regs = p->p_frame; regs = td->td_frame;
oonstack = sigonstack(regs->tf_esp); oonstack = sigonstack(regs->tf_esp);
/* Allocate and validate space for the signal handler context. */ /* Allocate and validate space for the signal handler context. */
@ -399,7 +401,7 @@ osendsig(catcher, sig, mask, code)
if (regs->tf_eflags & PSL_VM) { if (regs->tf_eflags & PSL_VM) {
/* XXX confusing names: `tf' isn't a trapframe; `regs' is. */ /* XXX confusing names: `tf' isn't a trapframe; `regs' is. */
struct trapframe_vm86 *tf = (struct trapframe_vm86 *)regs; struct trapframe_vm86 *tf = (struct trapframe_vm86 *)regs;
struct vm86_kernel *vm86 = &p->p_addr->u_pcb.pcb_ext->ext_vm86; struct vm86_kernel *vm86 = &td->td_pcb->pcb_ext->ext_vm86;
sf.sf_siginfo.si_sc.sc_gs = tf->tf_vm86_gs; sf.sf_siginfo.si_sc.sc_gs = tf->tf_vm86_gs;
sf.sf_siginfo.si_sc.sc_fs = tf->tf_vm86_fs; sf.sf_siginfo.si_sc.sc_fs = tf->tf_vm86_fs;
@ -422,7 +424,7 @@ osendsig(catcher, sig, mask, code)
* ...Kill the process. * ...Kill the process.
*/ */
PROC_LOCK(p); PROC_LOCK(p);
sigexit(p, SIGILL); sigexit(td, SIGILL);
/* NOTREACHED */ /* NOTREACHED */
} }
@ -447,12 +449,14 @@ sendsig(catcher, sig, mask, code)
{ {
struct sigframe sf; struct sigframe sf;
struct proc *p; struct proc *p;
struct thread *td;
struct sigacts *psp; struct sigacts *psp;
struct trapframe *regs; struct trapframe *regs;
struct sigframe *sfp; struct sigframe *sfp;
int oonstack; int oonstack;
p = curproc; td = curthread;
p = td->td_proc;
PROC_LOCK_ASSERT(p, MA_OWNED); PROC_LOCK_ASSERT(p, MA_OWNED);
psp = p->p_sigacts; psp = p->p_sigacts;
#ifdef COMPAT_43 #ifdef COMPAT_43
@ -461,7 +465,7 @@ sendsig(catcher, sig, mask, code)
return; return;
} }
#endif #endif
regs = p->p_frame; regs = td->td_frame;
oonstack = sigonstack(regs->tf_esp); oonstack = sigonstack(regs->tf_esp);
/* Save user context. */ /* Save user context. */
@ -541,7 +545,7 @@ sendsig(catcher, sig, mask, code)
*/ */
if (regs->tf_eflags & PSL_VM) { if (regs->tf_eflags & PSL_VM) {
struct trapframe_vm86 *tf = (struct trapframe_vm86 *)regs; struct trapframe_vm86 *tf = (struct trapframe_vm86 *)regs;
struct vm86_kernel *vm86 = &p->p_addr->u_pcb.pcb_ext->ext_vm86; struct vm86_kernel *vm86 = &td->td_pcb->pcb_ext->ext_vm86;
sf.sf_uc.uc_mcontext.mc_gs = tf->tf_vm86_gs; sf.sf_uc.uc_mcontext.mc_gs = tf->tf_vm86_gs;
sf.sf_uc.uc_mcontext.mc_fs = tf->tf_vm86_fs; sf.sf_uc.uc_mcontext.mc_fs = tf->tf_vm86_fs;
@ -574,7 +578,7 @@ sendsig(catcher, sig, mask, code)
* ...Kill the process. * ...Kill the process.
*/ */
PROC_LOCK(p); PROC_LOCK(p);
sigexit(p, SIGILL); sigexit(td, SIGILL);
/* NOTREACHED */ /* NOTREACHED */
} }
@ -599,17 +603,18 @@ sendsig(catcher, sig, mask, code)
*/ */
#ifdef COMPAT_43 #ifdef COMPAT_43
int int
osigreturn(p, uap) osigreturn(td, uap)
struct proc *p; struct thread *td;
struct osigreturn_args /* { struct osigreturn_args /* {
struct osigcontext *sigcntxp; struct osigcontext *sigcntxp;
} */ *uap; } */ *uap;
{ {
struct trapframe *regs; struct trapframe *regs;
struct osigcontext *scp; struct osigcontext *scp;
struct proc *p = td->td_proc;
int eflags; int eflags;
regs = p->p_frame; regs = td->td_frame;
scp = uap->sigcntxp; scp = uap->sigcntxp;
if (!useracc((caddr_t)scp, sizeof(*scp), VM_PROT_READ)) if (!useracc((caddr_t)scp, sizeof(*scp), VM_PROT_READ))
return (EFAULT); return (EFAULT);
@ -622,9 +627,9 @@ osigreturn(p, uap)
* if pcb_ext == 0 or vm86_inited == 0, the user hasn't * if pcb_ext == 0 or vm86_inited == 0, the user hasn't
* set up the vm86 area, and we can't enter vm86 mode. * set up the vm86 area, and we can't enter vm86 mode.
*/ */
if (p->p_addr->u_pcb.pcb_ext == 0) if (td->td_pcb->pcb_ext == 0)
return (EINVAL); return (EINVAL);
vm86 = &p->p_addr->u_pcb.pcb_ext->ext_vm86; vm86 = &td->td_pcb->pcb_ext->ext_vm86;
if (vm86->vm86_inited == 0) if (vm86->vm86_inited == 0)
return (EINVAL); return (EINVAL);
@ -710,12 +715,13 @@ osigreturn(p, uap)
#endif #endif
int int
sigreturn(p, uap) sigreturn(td, uap)
struct proc *p; struct thread *td;
struct sigreturn_args /* { struct sigreturn_args /* {
ucontext_t *sigcntxp; ucontext_t *sigcntxp;
} */ *uap; } */ *uap;
{ {
struct proc *p = td->td_proc;
struct trapframe *regs; struct trapframe *regs;
ucontext_t *ucp; ucontext_t *ucp;
int cs, eflags; int cs, eflags;
@ -725,7 +731,7 @@ sigreturn(p, uap)
if (!useracc((caddr_t)ucp, sizeof(struct osigcontext), VM_PROT_READ)) if (!useracc((caddr_t)ucp, sizeof(struct osigcontext), VM_PROT_READ))
return (EFAULT); return (EFAULT);
if (((struct osigcontext *)ucp)->sc_trapno == 0x01d516) if (((struct osigcontext *)ucp)->sc_trapno == 0x01d516)
return (osigreturn(p, (struct osigreturn_args *)uap)); return (osigreturn(td, (struct osigreturn_args *)uap));
/* /*
* Since ucp is not an osigcontext but a ucontext_t, we have to * Since ucp is not an osigcontext but a ucontext_t, we have to
* check again if all of it is accessible. A ucontext_t is * check again if all of it is accessible. A ucontext_t is
@ -737,7 +743,7 @@ sigreturn(p, uap)
if (!useracc((caddr_t)ucp, sizeof(*ucp), VM_PROT_READ)) if (!useracc((caddr_t)ucp, sizeof(*ucp), VM_PROT_READ))
return (EFAULT); return (EFAULT);
regs = p->p_frame; regs = td->td_frame;
eflags = ucp->uc_mcontext.mc_eflags; eflags = ucp->uc_mcontext.mc_eflags;
if (eflags & PSL_VM) { if (eflags & PSL_VM) {
struct trapframe_vm86 *tf = (struct trapframe_vm86 *)regs; struct trapframe_vm86 *tf = (struct trapframe_vm86 *)regs;
@ -747,9 +753,9 @@ sigreturn(p, uap)
* if pcb_ext == 0 or vm86_inited == 0, the user hasn't * if pcb_ext == 0 or vm86_inited == 0, the user hasn't
* set up the vm86 area, and we can't enter vm86 mode. * set up the vm86 area, and we can't enter vm86 mode.
*/ */
if (p->p_addr->u_pcb.pcb_ext == 0) if (td->td_pcb->pcb_ext == 0)
return (EINVAL); return (EINVAL);
vm86 = &p->p_addr->u_pcb.pcb_ext->ext_vm86; vm86 = &td->td_pcb->pcb_ext->ext_vm86;
if (vm86->vm86_inited == 0) if (vm86->vm86_inited == 0)
return (EINVAL); return (EINVAL);
@ -878,14 +884,14 @@ cpu_idle(void)
* Clear registers on exec * Clear registers on exec
*/ */
void void
setregs(p, entry, stack, ps_strings) setregs(td, entry, stack, ps_strings)
struct proc *p; struct thread *td;
u_long entry; u_long entry;
u_long stack; u_long stack;
u_long ps_strings; u_long ps_strings;
{ {
struct trapframe *regs = p->p_frame; struct trapframe *regs = td->td_frame;
struct pcb *pcb = &p->p_addr->u_pcb; struct pcb *pcb = td->td_pcb;
if (pcb->pcb_ldt) if (pcb->pcb_ldt)
user_ldt_free(pcb); user_ldt_free(pcb);
@ -938,7 +944,7 @@ setregs(p, entry, stack, ps_strings)
* traps to the emulator (if it is done at all) mainly because * traps to the emulator (if it is done at all) mainly because
* emulators don't provide an entry point for initialization. * emulators don't provide an entry point for initialization.
*/ */
p->p_addr->u_pcb.pcb_flags &= ~FP_SOFTFP; td->td_pcb->pcb_flags &= ~FP_SOFTFP;
/* /*
* Arrange to trap the next npx or `fwait' instruction (see npx.c * Arrange to trap the next npx or `fwait' instruction (see npx.c
@ -961,7 +967,7 @@ setregs(p, entry, stack, ps_strings)
* Make sure sure edx is 0x0 on entry. Linux binaries depend * Make sure sure edx is 0x0 on entry. Linux binaries depend
* on it. * on it.
*/ */
p->p_retval[1] = 0; td->td_retval[1] = 0;
} }
void void
@ -1029,7 +1035,8 @@ extern int has_f00f_bug;
static struct i386tss dblfault_tss; static struct i386tss dblfault_tss;
static char dblfault_stack[PAGE_SIZE]; static char dblfault_stack[PAGE_SIZE];
extern struct user *proc0paddr; extern struct user *proc0uarea;
extern vm_offset_t proc0kstack;
/* software prototypes -- in more palatable form */ /* software prototypes -- in more palatable form */
@ -1718,8 +1725,12 @@ init386(first)
struct region_descriptor r_gdt, r_idt; struct region_descriptor r_gdt, r_idt;
#endif #endif
proc0.p_addr = proc0paddr; proc_linkup(&proc0);
proc0.p_uarea = proc0uarea;
thread0 = &proc0.p_thread;
thread0->td_kstack = proc0kstack;
thread0->td_pcb = (struct pcb *)
(thread0->td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1;
atdevbase = ISA_HOLE_START + KERNBASE; atdevbase = ISA_HOLE_START + KERNBASE;
#ifdef PC98 #ifdef PC98
@ -1785,10 +1796,11 @@ init386(first)
lgdt(&r_gdt); lgdt(&r_gdt);
/* setup curproc so that mutexes work */ /* setup curproc so that mutexes work */
PCPU_SET(curproc, &proc0);
PCPU_SET(curthread, thread0);
PCPU_SET(spinlocks, NULL); PCPU_SET(spinlocks, NULL);
LIST_INIT(&proc0.p_contested); LIST_INIT(&thread0->td_contested);
/* /*
* Initialize mutexes. * Initialize mutexes.
@ -1892,8 +1904,9 @@ init386(first)
initializecpu(); /* Initialize CPU registers */ initializecpu(); /* Initialize CPU registers */
/* make an initial tss so cpu can get interrupt stack on syscall! */ /* make an initial tss so cpu can get interrupt stack on syscall! */
PCPU_SET(common_tss.tss_esp0, /* Note: -16 is so we can grow the trapframe if we came from vm86 */
(int) proc0.p_addr + UPAGES*PAGE_SIZE - 16); PCPU_SET(common_tss.tss_esp0, thread0->td_kstack +
KSTACK_PAGES * PAGE_SIZE - sizeof(struct pcb) - 16);
PCPU_SET(common_tss.tss_ss0, GSEL(GDATA_SEL, SEL_KPL)); PCPU_SET(common_tss.tss_ss0, GSEL(GDATA_SEL, SEL_KPL));
gsel_tss = GSEL(GPROC0_SEL, SEL_KPL); gsel_tss = GSEL(GPROC0_SEL, SEL_KPL);
private_tss = 0; private_tss = 0;
@ -1948,10 +1961,10 @@ init386(first)
_udatasel = LSEL(LUDATA_SEL, SEL_UPL); _udatasel = LSEL(LUDATA_SEL, SEL_UPL);
/* setup proc 0's pcb */ /* setup proc 0's pcb */
proc0.p_addr->u_pcb.pcb_flags = 0; thread0->td_pcb->pcb_flags = 0; /* XXXKSE */
proc0.p_addr->u_pcb.pcb_cr3 = (int)IdlePTD; thread0->td_pcb->pcb_cr3 = (int)IdlePTD;
proc0.p_addr->u_pcb.pcb_ext = 0; thread0->td_pcb->pcb_ext = 0;
proc0.p_frame = &proc0_tf; thread0->td_frame = &proc0_tf;
} }
#if defined(I586_CPU) && !defined(NO_F00F_HACK) #if defined(I586_CPU) && !defined(NO_F00F_HACK)
@ -1994,31 +2007,26 @@ f00f_hack(void *unused) {
#endif /* defined(I586_CPU) && !NO_F00F_HACK */ #endif /* defined(I586_CPU) && !NO_F00F_HACK */
int int
ptrace_set_pc(p, addr) ptrace_set_pc(struct thread *td, unsigned long addr)
struct proc *p;
unsigned long addr;
{ {
p->p_frame->tf_eip = addr; td->td_frame->tf_eip = addr;
return (0); return (0);
} }
int int
ptrace_single_step(p) ptrace_single_step(struct thread *td)
struct proc *p;
{ {
p->p_frame->tf_eflags |= PSL_T; td->td_frame->tf_eflags |= PSL_T;
return (0); return (0);
} }
int int
fill_regs(p, regs) fill_regs(struct thread *td, struct reg *regs)
struct proc *p;
struct reg *regs;
{ {
struct pcb *pcb; struct pcb *pcb;
struct trapframe *tp; struct trapframe *tp;
tp = p->p_frame; tp = td->td_frame;
regs->r_fs = tp->tf_fs; regs->r_fs = tp->tf_fs;
regs->r_es = tp->tf_es; regs->r_es = tp->tf_es;
regs->r_ds = tp->tf_ds; regs->r_ds = tp->tf_ds;
@ -2034,20 +2042,18 @@ fill_regs(p, regs)
regs->r_eflags = tp->tf_eflags; regs->r_eflags = tp->tf_eflags;
regs->r_esp = tp->tf_esp; regs->r_esp = tp->tf_esp;
regs->r_ss = tp->tf_ss; regs->r_ss = tp->tf_ss;
pcb = &p->p_addr->u_pcb; pcb = td->td_pcb;
regs->r_gs = pcb->pcb_gs; regs->r_gs = pcb->pcb_gs;
return (0); return (0);
} }
int int
set_regs(p, regs) set_regs(struct thread *td, struct reg *regs)
struct proc *p;
struct reg *regs;
{ {
struct pcb *pcb; struct pcb *pcb;
struct trapframe *tp; struct trapframe *tp;
tp = p->p_frame; tp = td->td_frame;
if (!EFL_SECURE(regs->r_eflags, tp->tf_eflags) || if (!EFL_SECURE(regs->r_eflags, tp->tf_eflags) ||
!CS_SECURE(regs->r_cs)) !CS_SECURE(regs->r_cs))
return (EINVAL); return (EINVAL);
@ -2066,7 +2072,7 @@ set_regs(p, regs)
tp->tf_eflags = regs->r_eflags; tp->tf_eflags = regs->r_eflags;
tp->tf_esp = regs->r_esp; tp->tf_esp = regs->r_esp;
tp->tf_ss = regs->r_ss; tp->tf_ss = regs->r_ss;
pcb = &p->p_addr->u_pcb; pcb = td->td_pcb;
pcb->pcb_gs = regs->r_gs; pcb->pcb_gs = regs->r_gs;
return (0); return (0);
} }
@ -2126,45 +2132,39 @@ set_fpregs_xmm(sv_87, sv_xmm)
#endif /* CPU_ENABLE_SSE */ #endif /* CPU_ENABLE_SSE */
int int
fill_fpregs(p, fpregs) fill_fpregs(struct thread *td, struct fpreg *fpregs)
struct proc *p;
struct fpreg *fpregs;
{ {
#ifdef CPU_ENABLE_SSE #ifdef CPU_ENABLE_SSE
if (cpu_fxsr) { if (cpu_fxsr) {
fill_fpregs_xmm(&p->p_addr->u_pcb.pcb_save.sv_xmm, fill_fpregs_xmm(&td->td_pcb->pcb_save.sv_xmm,
(struct save87 *)fpregs); (struct save87 *)fpregs);
return (0); return (0);
} }
#endif /* CPU_ENABLE_SSE */ #endif /* CPU_ENABLE_SSE */
bcopy(&p->p_addr->u_pcb.pcb_save.sv_87, fpregs, sizeof *fpregs); bcopy(&td->td_pcb->pcb_save.sv_87, fpregs, sizeof *fpregs);
return (0); return (0);
} }
int int
set_fpregs(p, fpregs) set_fpregs(struct thread *td, struct fpreg *fpregs)
struct proc *p;
struct fpreg *fpregs;
{ {
#ifdef CPU_ENABLE_SSE #ifdef CPU_ENABLE_SSE
if (cpu_fxsr) { if (cpu_fxsr) {
set_fpregs_xmm((struct save87 *)fpregs, set_fpregs_xmm((struct save87 *)fpregs,
&p->p_addr->u_pcb.pcb_save.sv_xmm); &td->td_pcb->pcb_save.sv_xmm);
return (0); return (0);
} }
#endif /* CPU_ENABLE_SSE */ #endif /* CPU_ENABLE_SSE */
bcopy(fpregs, &p->p_addr->u_pcb.pcb_save.sv_87, sizeof *fpregs); bcopy(fpregs, &td->td_pcb->pcb_save.sv_87, sizeof *fpregs);
return (0); return (0);
} }
int int
fill_dbregs(p, dbregs) fill_dbregs(struct thread *td, struct dbreg *dbregs)
struct proc *p;
struct dbreg *dbregs;
{ {
struct pcb *pcb; struct pcb *pcb;
if (p == NULL) { if (td == NULL) {
dbregs->dr0 = rdr0(); dbregs->dr0 = rdr0();
dbregs->dr1 = rdr1(); dbregs->dr1 = rdr1();
dbregs->dr2 = rdr2(); dbregs->dr2 = rdr2();
@ -2173,9 +2173,8 @@ fill_dbregs(p, dbregs)
dbregs->dr5 = rdr5(); dbregs->dr5 = rdr5();
dbregs->dr6 = rdr6(); dbregs->dr6 = rdr6();
dbregs->dr7 = rdr7(); dbregs->dr7 = rdr7();
} } else {
else { pcb = td->td_pcb;
pcb = &p->p_addr->u_pcb;
dbregs->dr0 = pcb->pcb_dr0; dbregs->dr0 = pcb->pcb_dr0;
dbregs->dr1 = pcb->pcb_dr1; dbregs->dr1 = pcb->pcb_dr1;
dbregs->dr2 = pcb->pcb_dr2; dbregs->dr2 = pcb->pcb_dr2;
@ -2189,15 +2188,13 @@ fill_dbregs(p, dbregs)
} }
int int
set_dbregs(p, dbregs) set_dbregs(struct thread *td, struct dbreg *dbregs)
struct proc *p;
struct dbreg *dbregs;
{ {
struct pcb *pcb; struct pcb *pcb;
int i; int i;
u_int32_t mask1, mask2; u_int32_t mask1, mask2;
if (p == NULL) { if (td == NULL) {
load_dr0(dbregs->dr0); load_dr0(dbregs->dr0);
load_dr1(dbregs->dr1); load_dr1(dbregs->dr1);
load_dr2(dbregs->dr2); load_dr2(dbregs->dr2);
@ -2206,8 +2203,7 @@ set_dbregs(p, dbregs)
load_dr5(dbregs->dr5); load_dr5(dbregs->dr5);
load_dr6(dbregs->dr6); load_dr6(dbregs->dr6);
load_dr7(dbregs->dr7); load_dr7(dbregs->dr7);
} } else {
else {
/* /*
* Don't let an illegal value for dr7 get set. Specifically, * Don't let an illegal value for dr7 get set. Specifically,
* check for undefined settings. Setting these bit patterns * check for undefined settings. Setting these bit patterns
@ -2219,7 +2215,7 @@ set_dbregs(p, dbregs)
if ((dbregs->dr7 & mask1) == mask2) if ((dbregs->dr7 & mask1) == mask2)
return (EINVAL); return (EINVAL);
pcb = &p->p_addr->u_pcb; pcb = td->td_pcb;
/* /*
* Don't let a process set a breakpoint that is not within the * Don't let a process set a breakpoint that is not within the
@ -2236,7 +2232,7 @@ set_dbregs(p, dbregs)
* from within kernel mode? * from within kernel mode?
*/ */
if (suser(p) != 0) { if (suser_td(td) != 0) {
if (dbregs->dr7 & 0x3) { if (dbregs->dr7 & 0x3) {
/* dr0 is enabled */ /* dr0 is enabled */
if (dbregs->dr0 >= VM_MAXUSER_ADDRESS) if (dbregs->dr0 >= VM_MAXUSER_ADDRESS)