Add a couple of sysctls and implement sendsig/sigreturn.

Obtained from: signal code from NetBSD
This commit is contained in:
dfr 1998-07-12 16:10:52 +00:00
parent 0dd29639cc
commit 72e016ccc7

View File

@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: machdep.c,v 1.4 1998/06/28 00:45:50 dfr Exp $
* $Id: machdep.c,v 1.5 1998/07/05 12:24:17 dfr Exp $
*/
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -107,6 +107,7 @@
#include <sys/vmmeter.h>
#include <sys/msgbuf.h>
#include <sys/exec.h>
#include <sys/sysctl.h>
#include <net/netisr.h>
#include <vm/vm.h>
#include <vm/vm_kern.h>
@ -151,8 +152,6 @@ u_int32_t cycles_per_sec;
int whichqs, whichrtqs, whichidqs;
int adjkerntz;
int cold = 1;
char cpu_model[128];
char machine[] = "alpha";
struct platform platform;
alpha_chipset_t chipset;
struct bootinfo_kernel bootinfo;
@ -160,6 +159,12 @@ struct timeval switchtime;
struct user *proc0paddr;
char machine[] = "alpha";
SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD, machine, 0, "");
static char cpu_model[128];
SYSCTL_STRING(_hw, HW_MODEL, model, CTLFLAG_RD, cpu_model, 0, "");
#ifdef DDB
/* start and end of kernel symbol table */
void *ksym_start, *ksym_end;
@ -1166,6 +1171,131 @@ remrq(p)
void
sendsig(sig_t catcher, int sig, int mask, u_long code)
{
struct proc *p = curproc;
struct sigcontext *scp, ksc;
struct trapframe *frame;
struct sigacts *psp = p->p_sigacts;
int oonstack, fsize, rndfsize;
frame = p->p_md.md_tf;
oonstack = psp->ps_sigstk.ss_flags & SS_ONSTACK;
fsize = sizeof ksc;
rndfsize = ((fsize + 15) / 16) * 16;
/*
* Allocate and validate space for the signal handler
* context. Note that if the stack is in P0 space, the
* call to grow() is a nop, and the useracc() check
* will fail if the process has not already allocated
* the space with a `brk'.
*/
if ((psp->ps_flags & SAS_ALTSTACK) && !oonstack &&
(psp->ps_sigonstack & sigmask(sig))) {
scp = (struct sigcontext *)((caddr_t)psp->ps_sigstk.ss_sp +
psp->ps_sigstk.ss_size - rndfsize);
psp->ps_sigstk.ss_flags |= SS_ONSTACK;
} else
scp = (struct sigcontext *)(alpha_pal_rdusp() - rndfsize);
if ((u_long)scp <= USRSTACK - ctob(p->p_vmspace->vm_ssize))
#if defined(UVM)
(void)uvm_grow(p, (u_long)scp);
#else
(void)grow(p, (u_long)scp);
#endif
#ifdef DEBUG
if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
printf("sendsig(%d): sig %d ssp %p usp %p\n", p->p_pid,
sig, &oonstack, scp);
#endif
#if defined(UVM)
if (uvm_useracc((caddr_t)scp, fsize, B_WRITE) == 0) {
#else
if (useracc((caddr_t)scp, fsize, B_WRITE) == 0) {
#endif
#ifdef DEBUG
if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
printf("sendsig(%d): useracc failed on sig %d\n",
p->p_pid, sig);
#endif
/*
* Process has trashed its stack; give it an illegal
* instruction to halt it in its tracks.
*/
SIGACTION(p, SIGILL) = SIG_DFL;
sig = sigmask(SIGILL);
p->p_sigignore &= ~sig;
p->p_sigcatch &= ~sig;
p->p_sigmask &= ~sig;
psignal(p, SIGILL);
return;
#if !defined(UVM) /* this construct will balance braces for ctags(1) */
}
#else
}
#endif
/*
* Build the signal context to be used by sigreturn.
*/
ksc.sc_onstack = oonstack;
ksc.sc_mask = mask;
ksc.sc_pc = frame->tf_regs[FRAME_PC];
ksc.sc_ps = frame->tf_regs[FRAME_PS];
/* copy the registers. */
fill_regs(p, (struct reg *)ksc.sc_regs);
ksc.sc_regs[R_ZERO] = 0xACEDBADE; /* magic number */
ksc.sc_regs[R_SP] = alpha_pal_rdusp();
/* save the floating-point state, if necessary, then copy it. */
if (p == fpcurproc) {
alpha_pal_wrfen(1);
savefpstate(&p->p_addr->u_pcb.pcb_fp);
alpha_pal_wrfen(0);
fpcurproc = NULL;
}
ksc.sc_ownedfp = p->p_md.md_flags & MDP_FPUSED;
bcopy(&p->p_addr->u_pcb.pcb_fp, (struct fpreg *)ksc.sc_fpregs,
sizeof(struct fpreg));
ksc.sc_fp_control = 0; /* XXX ? */
bzero(ksc.sc_reserved, sizeof ksc.sc_reserved); /* XXX */
bzero(ksc.sc_xxx, sizeof ksc.sc_xxx); /* XXX */
#ifdef COMPAT_OSF1
/*
* XXX Create an OSF/1-style sigcontext and associated goo.
*/
#endif
/*
* copy the frame out to userland.
*/
(void) copyout((caddr_t)&ksc, (caddr_t)scp, fsize);
#ifdef DEBUG
if (sigdebug & SDB_FOLLOW)
printf("sendsig(%d): sig %d scp %p code %lx\n", p->p_pid, sig,
scp, code);
#endif
/*
* Set up the registers to return to sigcode.
*/
frame->tf_regs[FRAME_PC] =
(u_int64_t)PS_STRINGS - (esigcode - sigcode);
frame->tf_regs[FRAME_A0] = sig;
frame->tf_regs[FRAME_A1] = code;
frame->tf_regs[FRAME_A2] = (u_int64_t)scp;
frame->tf_regs[FRAME_T12] = (u_int64_t)catcher; /* t12 is pv */
alpha_pal_wrusp((unsigned long)scp);
#ifdef DEBUG
if (sigdebug & SDB_FOLLOW)
printf("sendsig(%d): pc %lx, catcher %lx\n", p->p_pid,
frame->tf_regs[FRAME_PC], frame->tf_regs[FRAME_A3]);
if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
printf("sendsig(%d): sig %d returns\n",
p->p_pid, sig);
#endif
}
/*
@ -1183,7 +1313,61 @@ sigreturn(struct proc *p,
struct sigcontext *sigcntxp;
} */ *uap)
{
return -1;
struct sigcontext *scp, ksc;
scp = uap->sigcntxp;
#ifdef DEBUG
if (sigdebug & SDB_FOLLOW)
printf("sigreturn: pid %d, scp %p\n", p->p_pid, scp);
#endif
if (ALIGN(scp) != (u_int64_t)scp)
return (EINVAL);
/*
* Test and fetch the context structure.
* We grab it all at once for speed.
*/
#if defined(UVM)
if (uvm_useracc((caddr_t)scp, sizeof (*scp), B_WRITE) == 0 ||
copyin((caddr_t)scp, (caddr_t)&ksc, sizeof ksc))
return (EINVAL);
#else
if (useracc((caddr_t)scp, sizeof (*scp), B_WRITE) == 0 ||
copyin((caddr_t)scp, (caddr_t)&ksc, sizeof ksc))
return (EINVAL);
#endif
if (ksc.sc_regs[R_ZERO] != 0xACEDBADE) /* magic number */
return (EINVAL);
/*
* Restore the user-supplied information
*/
if (ksc.sc_onstack)
p->p_sigacts->ps_sigstk.ss_flags |= SS_ONSTACK;
else
p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK;
p->p_sigmask = ksc.sc_mask &~ sigcantmask;
set_regs(p, (struct reg *)ksc.sc_regs);
p->p_md.md_tf->tf_regs[FRAME_PC] = ksc.sc_pc;
p->p_md.md_tf->tf_regs[FRAME_PS] =
(ksc.sc_ps | ALPHA_PSL_USERSET) & ~ALPHA_PSL_USERCLR;
alpha_pal_wrusp(ksc.sc_regs[R_SP]);
/* XXX ksc.sc_ownedfp ? */
if (p == fpcurproc)
fpcurproc = NULL;
bcopy((struct fpreg *)ksc.sc_fpregs, &p->p_addr->u_pcb.pcb_fp,
sizeof(struct fpreg));
/* XXX ksc.sc_fp_control ? */
#ifdef DEBUG
if (sigdebug & SDB_FOLLOW)
printf("sigreturn(%d): returns\n", p->p_pid);
#endif
return (EJUSTRETURN);
}
/*
@ -1313,23 +1497,21 @@ ptrace_write_u(struct proc *p, vm_offset_t off, long data)
}
int
alpha_pa_access(pa)
u_long pa;
alpha_pa_access(vm_offset_t pa)
{
#if 0
int i;
for (i = 0; i < mem_cluster_cnt; i++) {
if (pa < mem_clusters[i].start)
for (i = 0; phys_avail[i] != 0; i += 2) {
if (pa < phys_avail[i])
continue;
if ((pa - mem_clusters[i].start) >=
(mem_clusters[i].size & ~PAGE_MASK))
continue;
return (mem_clusters[i].size & PAGE_MASK); /* prot */
if (pa < phys_avail[i+1])
return VM_PROT_READ|VM_PROT_WRITE;
}
return (PROT_NONE);
#endif
return 0;
#else
return VM_PROT_READ|VM_PROT_WRITE;
#endif
}
int
@ -1455,18 +1637,3 @@ bounds_check_with_label(struct buf *bp, struct disklabel *lp, int wlabel)
return(-1);
}
#include <sys/interrupt.h>
struct intrec *
intr_create(void *dev_instance, int irq, inthand2_t handler, void *arg,
intrmask_t *maskptr, int flags)
{
return 0;
}
int
intr_connect(struct intrec *idesc)
{
return ENXIO;
}