summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjake <jake@FreeBSD.org>2002-04-29 18:08:26 +0000
committerjake <jake@FreeBSD.org>2002-04-29 18:08:26 +0000
commit80ce8587d9c74fd10511253fa092aaaa3f0f54c2 (patch)
tree996687e669c92cbada1ef744da6e57072d97b19e
parentd139b64371b85b65e8459f460ae66cc76494182a (diff)
downloadFreeBSD-src-80ce8587d9c74fd10511253fa092aaaa3f0f54c2.zip
FreeBSD-src-80ce8587d9c74fd10511253fa092aaaa3f0f54c2.tar.gz
Add support for an alternate signal trampoline; add a sysarch call to register
an alternate trampoling with the kernel.
-rw-r--r--sys/sparc64/include/proc.h1
-rw-r--r--sys/sparc64/include/sysarch.h6
-rw-r--r--sys/sparc64/sparc64/machdep.c7
-rw-r--r--sys/sparc64/sparc64/sys_machdep.c22
-rw-r--r--sys/sparc64/sparc64/vm_machdep.c2
5 files changed, 37 insertions, 1 deletions
diff --git a/sys/sparc64/include/proc.h b/sys/sparc64/include/proc.h
index 108bc42..a5307d8 100644
--- a/sys/sparc64/include/proc.h
+++ b/sys/sparc64/include/proc.h
@@ -52,6 +52,7 @@ struct mdthread {
struct mdproc {
struct md_utrap *md_utrap;
+ void *md_sigtramp;
};
#endif /* !_MACHINE_PROC_H_ */
diff --git a/sys/sparc64/include/sysarch.h b/sys/sparc64/include/sysarch.h
index e9db27f..104a9e5 100644
--- a/sys/sparc64/include/sysarch.h
+++ b/sys/sparc64/include/sysarch.h
@@ -41,12 +41,18 @@
#define _MACHINE_SYSARCH_H_
#define SPARC_UTRAP_INSTALL 1
+#define SPARC_SIGTRAMP_INSTALL 2
struct sparc_utrap_install_args {
int num;
const struct sparc_utrap_args *handlers;
};
+struct sparc_sigtramp_install_args {
+ void *sia_new;
+ void **sia_old;
+};
+
struct sparc_utrap_args {
utrap_entry_t type;
utrap_handler_t new_precise;
diff --git a/sys/sparc64/sparc64/machdep.c b/sys/sparc64/sparc64/machdep.c
index 1436070..d68d18c 100644
--- a/sys/sparc64/sparc64/machdep.c
+++ b/sys/sparc64/sparc64/machdep.c
@@ -282,6 +282,7 @@ sparc64_init(caddr_t mdp, u_long o1, u_long o2, u_long o3, ofw_vec_t *vec)
* Initialize proc0 stuff (p_contested needs to be done early).
*/
proc_linkup(&proc0, &proc0.p_ksegrp, &proc0.p_kse, &thread0);
+ proc0.p_md.md_sigtramp = NULL;
proc0.p_md.md_utrap = NULL;
proc0.p_uarea = (struct user *)uarea0;
proc0.p_stats = &proc0.p_uarea->u_stats;
@@ -418,7 +419,10 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
/* NOTREACHED */
}
- tf->tf_tpc = PS_STRINGS - *(p->p_sysent->sv_szsigcode);
+ if (p->p_md.md_sigtramp != NULL)
+ tf->tf_tpc = (u_long)p->p_md.md_sigtramp;
+ else
+ tf->tf_tpc = PS_STRINGS - *(p->p_sysent->sv_szsigcode);
tf->tf_tnpc = tf->tf_tpc + 4;
tf->tf_sp = (u_long)fp - SPOFF;
@@ -580,6 +584,7 @@ setregs(struct thread *td, u_long entry, u_long stack, u_long ps_strings)
u_long sp;
/* XXX no cpu_exec */
+ td->td_proc->p_md.md_sigtramp = NULL;
if ((ut = td->td_proc->p_md.md_utrap) != NULL) {
ut->ut_refcnt--;
if (ut->ut_refcnt == 0)
diff --git a/sys/sparc64/sparc64/sys_machdep.c b/sys/sparc64/sparc64/sys_machdep.c
index 9025f59..34be95a 100644
--- a/sys/sparc64/sparc64/sys_machdep.c
+++ b/sys/sparc64/sparc64/sys_machdep.c
@@ -35,6 +35,7 @@
#include <machine/utrap.h>
#include <machine/sysarch.h>
+static int sparc_sigtramp_install(struct thread *td, char *args);
static int sparc_utrap_install(struct thread *td, char *args);
#ifndef _SYS_SYSPROTO_H_
@@ -51,6 +52,9 @@ sysarch(struct thread *td, struct sysarch_args *uap)
error = 0;
switch (uap->op) {
+ case SPARC_SIGTRAMP_INSTALL:
+ error = sparc_sigtramp_install(td, uap->parms);
+ break;
case SPARC_UTRAP_INSTALL:
error = sparc_utrap_install(td, uap->parms);
break;
@@ -62,6 +66,24 @@ sysarch(struct thread *td, struct sysarch_args *uap)
}
static int
+sparc_sigtramp_install(struct thread *td, char *args)
+{
+ struct sparc_sigtramp_install_args sia;
+ struct proc *p;
+ int error;
+
+ p = td->td_proc;
+ if ((error = copyin(args, &sia, sizeof(sia))) != 0)
+ return (error);
+ if (sia.sia_old != NULL) {
+ if (suword(sia.sia_old, (long)p->p_md.md_sigtramp) != 0)
+ return (EFAULT);
+ }
+ p->p_md.md_sigtramp = sia.sia_new;
+ return (0);
+}
+
+static int
sparc_utrap_install(struct thread *td, char *args)
{
struct sparc_utrap_install_args uia;
diff --git a/sys/sparc64/sparc64/vm_machdep.c b/sys/sparc64/sparc64/vm_machdep.c
index eb49c58..fe8eb00 100644
--- a/sys/sparc64/sparc64/vm_machdep.c
+++ b/sys/sparc64/sparc64/vm_machdep.c
@@ -77,6 +77,7 @@ cpu_exit(struct thread *td)
struct proc *p;
p = td->td_proc;
+ p->p_md.md_sigtramp = NULL;
if ((ut = p->p_md.md_utrap) != NULL) {
ut->ut_refcnt--;
if (ut->ut_refcnt == 0)
@@ -108,6 +109,7 @@ cpu_fork(struct thread *td1, struct proc *p2, struct thread *td2, int flags)
if ((flags & RFPROC) == 0)
return;
+ p2->p_md.md_sigtramp = td1->td_proc->p_md.md_sigtramp;
if ((ut = td1->td_proc->p_md.md_utrap) != NULL)
ut->ut_refcnt++;
p2->p_md.md_utrap = ut;
OpenPOWER on IntegriCloud