From 18ef2712327dfe502cec9c7141c246878db2ac2c Mon Sep 17 00:00:00 2001 From: Jake Burkholder Date: Sun, 30 Sep 2001 18:48:37 +0000 Subject: [PATCH] Move the pcb the to the top of the kernel stack. Add a guard page at the bottom of the kernel stack. Its unclear how easy it will be to detect these faults and do something useful. Setup the registers on exec how the c runtime expects. Implement various {fill,set}_*regs. Fix proc locking. --- sys/sparc64/include/param.h | 5 +- sys/sparc64/sparc64/locore.S | 4 +- sys/sparc64/sparc64/locore.s | 4 +- sys/sparc64/sparc64/machdep.c | 118 ++++++++++++++++++------------- sys/sparc64/sparc64/vm_machdep.c | 5 +- 5 files changed, 75 insertions(+), 61 deletions(-) diff --git a/sys/sparc64/include/param.h b/sys/sparc64/include/param.h index 2f8d6a6d492a..66997781d010 100644 --- a/sys/sparc64/include/param.h +++ b/sys/sparc64/include/param.h @@ -115,12 +115,11 @@ #define MAXPHYS (128 * 1024) /* max raw I/O transfer size */ #define MAXDUMPPGS (DFLTPHYS/PAGE_SIZE) -#define IOPAGES 2 /* pages of i/o permission bitmap */ - #define KSTACK_PAGES 4 /* pages of kernel stack (with pcb) */ #define UAREA_PAGES 1 /* pages of user area */ -/* #define KSTACK_GUARD */ /* compile in kstack guard page */ +#define KSTACK_GUARD /* compile in kstack guard page */ +#define KSTACK_GUARD_PAGES 1 /* * Constants related to network buffer management. diff --git a/sys/sparc64/sparc64/locore.S b/sys/sparc64/sparc64/locore.S index fabc03ee37c0..a007fefce188 100644 --- a/sys/sparc64/sparc64/locore.S +++ b/sys/sparc64/sparc64/locore.S @@ -48,8 +48,8 @@ ENTRY(_start) wrpr %g0, 0, %cleanwin wrpr %g0, 0, %pil - setx kstack0 + KSTACK_PAGES * PAGE_SIZE - SPOFF, %l0, %o5 - save %o5, -CCFSZ, %sp + set kstack0 + KSTACK_PAGES * PAGE_SIZE - PCB_SIZEOF, %o0 + sub %o0, SPOFF + CCFSZ, %sp mov %g1, %o0 call sparc64_init diff --git a/sys/sparc64/sparc64/locore.s b/sys/sparc64/sparc64/locore.s index fabc03ee37c0..a007fefce188 100644 --- a/sys/sparc64/sparc64/locore.s +++ b/sys/sparc64/sparc64/locore.s @@ -48,8 +48,8 @@ ENTRY(_start) wrpr %g0, 0, %cleanwin wrpr %g0, 0, %pil - setx kstack0 + KSTACK_PAGES * PAGE_SIZE - SPOFF, %l0, %o5 - save %o5, -CCFSZ, %sp + set kstack0 + KSTACK_PAGES * PAGE_SIZE - PCB_SIZEOF, %o0 + sub %o0, SPOFF + CCFSZ, %sp mov %g1, %o0 call sparc64_init diff --git a/sys/sparc64/sparc64/machdep.c b/sys/sparc64/sparc64/machdep.c index 413a765b9d22..a3940923d44e 100644 --- a/sys/sparc64/sparc64/machdep.c +++ b/sys/sparc64/sparc64/machdep.c @@ -94,24 +94,25 @@ extern char tl0_base[]; extern char _end[]; -int physmem = 0; +int physmem; int cold = 1; long dumplo; -int Maxmem = 0; +int Maxmem; u_long debug_mask; struct mtx Giant; struct mtx sched_lock; -struct globaldata __globaldata; +static struct globaldata __globaldata; /* * This needs not be aligned as the other user areas, provided that process 0 * does not have an fp state (which it doesn't normally). * This constraint is only here for debugging. */ -char uarea0[UAREA_PAGES * PAGE_SIZE] __attribute__ ((aligned (64))); -char kstack0[KSTACK_PAGES * PAGE_SIZE] __attribute__ ((aligned (64))); +char kstack0[KSTACK_PAGES * PAGE_SIZE] __attribute__((aligned(64))); +static char uarea0[UAREA_PAGES * PAGE_SIZE] __attribute__((aligned(64))); +static struct trapframe frame0; struct user *proc0uarea; vm_offset_t proc0kstack; @@ -133,10 +134,8 @@ cpu_startup(void *arg) { phandle_t child; phandle_t root; - char name[32]; char type[8]; u_int clock; - caddr_t p; root = OF_peer(0); for (child = OF_child(root); child != 0; child = OF_peer(child)) { @@ -146,7 +145,6 @@ cpu_startup(void *arg) } if (child == 0) panic("cpu_startup: no cpu\n"); - OF_getprop(child, "name", name, sizeof(name)); OF_getprop(child, "clock-frequency", &clock, sizeof(clock)); tick_tc.tc_get_timecount = tick_get_timecount; @@ -156,17 +154,7 @@ cpu_startup(void *arg) tick_tc.tc_name = "tick"; tc_init(&tick_tc); - p = name; - if (bcmp(p, "SUNW,", 5) == 0) - p += 5; - printf("CPU: %s Processor (%d.%02d MHz CPU)\n", p, - (clock + 4999) / 1000000, ((clock + 4999) / 10000) % 100); -#if 0 - ver = rdpr(ver); - printf("manuf: %#lx impl: %#lx mask: %#lx maxtl: %#lx maxwin: %#lx\n", - VER_MANUF(ver), VER_IMPL(ver), VER_MASK(ver), VER_MAXTL(ver), - VER_MAXWIN(ver)); -#endif + cpu_identify(clock); vm_ksubmap_init(&kmi); @@ -174,9 +162,8 @@ cpu_startup(void *arg) vm_pager_bufferinit(); globaldata_register(globalp); -#if 0 + tick_start(clock, tick_hardclock); -#endif } unsigned @@ -188,7 +175,6 @@ tick_get_timecount(struct timecounter *tc) void sparc64_init(struct bootinfo *bi, ofw_vec_t *vec) { - struct trapframe *tf; u_long ps; /* @@ -245,11 +231,9 @@ sparc64_init(struct bootinfo *bi, ofw_vec_t *vec) proc0.p_stats = &proc0.p_uarea->u_stats; thread0 = &proc0.p_thread; thread0->td_kstack = proc0kstack; - thread0->td_pcb = (struct pcb *)thread0->td_kstack; - tf = (struct trapframe *)(thread0->td_kstack + KSTACK_PAGES * - PAGE_SIZE) - 1; - tf->tf_tstate = TSTATE_IE; - thread0->td_frame = tf; + thread0->td_pcb = (struct pcb *) + (thread0->td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1; + thread0->td_frame = &frame0; LIST_INIT(&thread0->td_contested); /* @@ -319,7 +303,6 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) oonstack = 0; td = curthread; p = td->td_proc; - PROC_LOCK(p); psp = p->p_sigacts; tf = td->td_frame; sp = tf->tf_sp + SPOFF; @@ -373,7 +356,6 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) SIGDELSET(p->p_sigcatch, SIGILL); SIGDELSET(p->p_sigmask, SIGILL); psignal(p, SIGILL); - PROC_UNLOCK(p); return; } @@ -419,6 +401,8 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) CTR3(KTR_SIG, "sendsig: return td=%p pc=%#lx sp=%#lx", td, tf->tf_tpc, tf->tf_sp); + + PROC_LOCK(p); } #ifndef _SYS_SYSPROTO_H_ @@ -448,6 +432,10 @@ sigreturn(struct thread *td, struct sigreturn_args *uap) if (((uc.uc_mcontext.mc_tpc | uc.uc_mcontext.mc_tnpc) & 3) != 0) return (EINVAL); +#if 0 + if (!TSTATE_SECURE(uc.uc_mcontext.mc_tstate)) + return (EINVAL); +#endif tf = td->td_frame; bcopy(uc.uc_mcontext.mc_global, tf->tf_global, @@ -476,7 +464,8 @@ sigreturn(struct thread *td, struct sigreturn_args *uap) void cpu_halt(void) { - TODO; + + OF_exit(); } int @@ -500,9 +489,10 @@ setregs(struct thread *td, u_long entry, u_long stack, u_long ps_strings) { struct pcb *pcb; struct frame *fp; + u_long sp; /* Round the stack down to a multiple of 16 bytes. */ - stack = ((stack) / 16) * 16; + sp = ((stack) / 16) * 16; pcb = td->td_pcb; /* XXX: honor the real number of windows... */ bzero(pcb->pcb_rw, sizeof(pcb->pcb_rw)); @@ -529,8 +519,12 @@ setregs(struct thread *td, u_long entry, u_long stack, u_long ps_strings) bzero(td->td_frame->tf_out, sizeof(td->td_frame->tf_out)); bzero(td->td_frame->tf_global, sizeof(td->td_frame->tf_global)); /* Set up user stack. */ - fp->f_fp = stack - SPOFF; - td->td_frame->tf_out[6] = stack - SPOFF - sizeof(struct frame); + fp->f_fp = sp - SPOFF; + td->td_frame->tf_out[0] = stack; + td->td_frame->tf_out[1] = 0; + td->td_frame->tf_out[2] = 0; + td->td_frame->tf_out[3] = PS_STRINGS; + td->td_frame->tf_out[6] = sp - SPOFF - sizeof(struct frame); wr(y, 0, 0); mtx_unlock_spin(&sched_lock); } @@ -543,44 +537,66 @@ Debugger(const char *msg) breakpoint(); } -int -fill_dbregs(struct thread *td, struct dbreg *dbregs) -{ - TODO; - return (0); -} - -int -set_dbregs(struct thread *td, struct dbreg *dbregs) -{ - TODO; - return (0); -} - int fill_regs(struct thread *td, struct reg *regs) { - TODO; + struct trapframe *tf; + struct pcb *pcb; + + tf = td->td_frame; + pcb = td->td_pcb; + bcopy(tf->tf_global, regs->r_global, sizeof(tf->tf_global)); + bcopy(tf->tf_out, regs->r_out, sizeof(tf->tf_out)); + regs->r_tstate = tf->tf_tstate; + regs->r_pc = tf->tf_tpc; + regs->r_npc = tf->tf_tnpc; + regs->r_y = pcb->pcb_y; return (0); } int set_regs(struct thread *td, struct reg *regs) { - TODO; + struct trapframe *tf; + struct pcb *pcb; + + tf = td->td_frame; + pcb = td->td_pcb; + if (((regs->r_pc | regs->r_npc) & 3) != 0) + return (EINVAL); +#if 0 + if (!TSTATE_SECURE(regs->r_tstate)) + return (EINVAL); +#endif + bcopy(regs->r_global, tf->tf_global, sizeof(regs->r_global)); + bcopy(regs->r_out, tf->tf_out, sizeof(regs->r_out)); + tf->tf_tstate = regs->r_tstate; + tf->tf_tpc = regs->r_pc; + tf->tf_tnpc = regs->r_npc; + pcb->pcb_y = regs->r_y; return (0); } int fill_fpregs(struct thread *td, struct fpreg *fpregs) { - TODO; + struct pcb *pcb; + + pcb = td->td_pcb; + bcopy(pcb->pcb_fpstate.fp_fb, fpregs->fr_regs, + sizeof(pcb->pcb_fpstate.fp_fb)); + fpregs->fr_fsr = pcb->pcb_fpstate.fp_fsr; return (0); } int set_fpregs(struct thread *td, struct fpreg *fpregs) { - TODO; + struct pcb *pcb; + + pcb = td->td_pcb; + bcopy(fpregs->fr_regs, pcb->pcb_fpstate.fp_fb, + sizeof(fpregs->fr_regs)); + pcb->pcb_fpstate.fp_fsr = fpregs->fr_fsr; return (0); } diff --git a/sys/sparc64/sparc64/vm_machdep.c b/sys/sparc64/sparc64/vm_machdep.c index 1e94d40d4ef2..c3c31fe469e5 100644 --- a/sys/sparc64/sparc64/vm_machdep.c +++ b/sys/sparc64/sparc64/vm_machdep.c @@ -88,7 +88,7 @@ cpu_fork(struct thread *td1, struct proc *p2, int flags) return; td2 = &p2->p_thread; - pcb = (struct pcb *)td2->td_kstack; + pcb = (struct pcb *)(td2->td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1; td2->td_pcb = pcb; /* @@ -112,8 +112,7 @@ cpu_fork(struct thread *td1, struct proc *p2, int flags) * Copy the trap frame for the return to user mode as if from a * syscall. This copies most of the user mode register values. */ - tf = (struct trapframe *) - (td2->td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1; + tf = (struct trapframe *)pcb - 1; bcopy(td1->td_frame, tf, sizeof(*tf)); tf->tf_out[0] = 0; /* Child returns zero */