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

View File

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