summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/alpha/alpha/sys_machdep.c48
-rw-r--r--sys/alpha/alpha/trap.c16
-rw-r--r--sys/alpha/alpha/vm_machdep.c2
-rw-r--r--sys/alpha/include/proc.h5
-rw-r--r--sys/alpha/include/sysarch.h2
-rw-r--r--sys/powerpc/aim/vm_machdep.c2
-rw-r--r--sys/powerpc/powerpc/vm_machdep.c2
7 files changed, 68 insertions, 9 deletions
diff --git a/sys/alpha/alpha/sys_machdep.c b/sys/alpha/alpha/sys_machdep.c
index 9a85e97..4e0c3c8 100644
--- a/sys/alpha/alpha/sys_machdep.c
+++ b/sys/alpha/alpha/sys_machdep.c
@@ -66,6 +66,8 @@ struct sysarch_args {
static int alpha_sethae(struct proc *p, char *args);
static int alpha_get_fpmask(struct proc *p, char *args);
static int alpha_set_fpmask(struct proc *p, char *args);
+static int alpha_set_uac(struct proc *p, char *args);
+static int alpha_get_uac(struct proc *p, char *args);
int
sysarch(p, uap)
@@ -84,6 +86,12 @@ sysarch(p, uap)
case ALPHA_SET_FPMASK:
error = alpha_set_fpmask(p, uap->parms);
break;
+ case ALPHA_SET_UAC:
+ error = alpha_set_uac(p, uap->parms);
+ break;
+ case ALPHA_GET_UAC:
+ error = alpha_get_uac(p, uap->parms);
+ break;
default:
error = EINVAL;
@@ -154,3 +162,43 @@ alpha_set_fpmask(struct proc *p, char *args)
error = copyout(&ua, args, sizeof(struct alpha_fpmask_args));
return (error);
}
+
+static int
+alpha_set_uac(struct proc *p, char *args)
+{
+ int error, s;
+ unsigned long uac;
+
+ error = copyin(args, &uac, sizeof(uac));
+ if (error)
+ return (error);
+
+ if (p->p_pptr) {
+ s = splimp();
+ if (p->p_pptr) {
+ p->p_pptr->p_md.md_flags &= ~MDP_UAC_MASK;
+ p->p_pptr->p_md.md_flags |= uac & MDP_UAC_MASK;
+ } else
+ error = ESRCH;
+ splx(s);
+ }
+ return error;
+}
+
+static int
+alpha_get_uac(struct proc *p, char *args)
+{
+ int error, s;
+ unsigned long uac;
+
+ error = ESRCH;
+ if (p->p_pptr) {
+ s = splimp();
+ if (p->p_pptr) {
+ uac = p->p_pptr->p_md.md_flags & MDP_UAC_MASK;
+ error = copyout(&uac, args, sizeof(uac));
+ }
+ splx(s);
+ }
+ return error;
+}
diff --git a/sys/alpha/alpha/trap.c b/sys/alpha/alpha/trap.c
index fc04abc..7e9b15e 100644
--- a/sys/alpha/alpha/trap.c
+++ b/sys/alpha/alpha/trap.c
@@ -923,7 +923,7 @@ unaligned_fixup(va, opcode, reg, p)
int doprint, dofix, dosigbus;
int signal, size;
const char *type;
- unsigned long *regptr, longdata;
+ unsigned long *regptr, longdata, uac;
int intdata; /* signed to get extension when storing */
struct {
const char *type; /* opcode name */
@@ -950,12 +950,16 @@ unaligned_fixup(va, opcode, reg, p)
/*
* Figure out what actions to take.
*
- * XXX In the future, this should have a per-process component
- * as well.
*/
- doprint = alpha_unaligned_print;
- dofix = alpha_unaligned_fix;
- dosigbus = alpha_unaligned_sigbus;
+
+ if (p)
+ uac = p->p_md.md_flags & MDP_UAC_MASK;
+ else
+ uac = 0;
+
+ doprint = alpha_unaligned_print && !(uac & MDP_UAC_NOPRINT);
+ dofix = alpha_unaligned_fix && !(uac & MDP_UAC_NOFIX);
+ dosigbus = alpha_unaligned_sigbus | (uac & MDP_UAC_SIGBUS);
/*
* Find out which opcode it is. Arrange to have the opcode
diff --git a/sys/alpha/alpha/vm_machdep.c b/sys/alpha/alpha/vm_machdep.c
index 247f1b6..bb2bbfd 100644
--- a/sys/alpha/alpha/vm_machdep.c
+++ b/sys/alpha/alpha/vm_machdep.c
@@ -126,7 +126,7 @@ cpu_fork(p1, p2, flags)
return;
p2->p_md.md_tf = p1->p_md.md_tf;
- p2->p_md.md_flags = p1->p_md.md_flags & MDP_FPUSED;
+ p2->p_md.md_flags = p1->p_md.md_flags & (MDP_FPUSED | MDP_UAC_MASK);
/*
* Cache the physical address of the pcb, so we can
diff --git a/sys/alpha/include/proc.h b/sys/alpha/include/proc.h
index b2a28df..11c9289 100644
--- a/sys/alpha/include/proc.h
+++ b/sys/alpha/include/proc.h
@@ -50,3 +50,8 @@ struct mdproc {
#define MDP_STEP1 0x0002 /* Single step normal instruction */
#define MDP_STEP2 0x0004 /* Single step branch instruction */
#define MDP_HAEUSED 0x0008 /* Process used the HAE */
+#define MDP_UAC_NOPRINT 0x0010 /* Don't print unaligned traps */
+#define MDP_UAC_NOFIX 0x0020 /* Don't fixup unaligned traps */
+#define MDP_UAC_SIGBUS 0x0040 /* Deliver SIGBUS upon
+ unalinged access */
+#define MDP_UAC_MASK (MDP_UAC_NOPRINT | MDP_UAC_NOFIX | MDP_UAC_SIGBUS)
diff --git a/sys/alpha/include/sysarch.h b/sys/alpha/include/sysarch.h
index 6024399..93ff1ee 100644
--- a/sys/alpha/include/sysarch.h
+++ b/sys/alpha/include/sysarch.h
@@ -42,6 +42,8 @@
#define ALPHA_SETHAE 0
#define ALPHA_GET_FPMASK 1
#define ALPHA_SET_FPMASK 2
+#define ALPHA_GET_UAC 3
+#define ALPHA_SET_UAC 4
#ifndef _KERNEL
#include <sys/cdefs.h>
diff --git a/sys/powerpc/aim/vm_machdep.c b/sys/powerpc/aim/vm_machdep.c
index 247f1b6..bb2bbfd 100644
--- a/sys/powerpc/aim/vm_machdep.c
+++ b/sys/powerpc/aim/vm_machdep.c
@@ -126,7 +126,7 @@ cpu_fork(p1, p2, flags)
return;
p2->p_md.md_tf = p1->p_md.md_tf;
- p2->p_md.md_flags = p1->p_md.md_flags & MDP_FPUSED;
+ p2->p_md.md_flags = p1->p_md.md_flags & (MDP_FPUSED | MDP_UAC_MASK);
/*
* Cache the physical address of the pcb, so we can
diff --git a/sys/powerpc/powerpc/vm_machdep.c b/sys/powerpc/powerpc/vm_machdep.c
index 247f1b6..bb2bbfd 100644
--- a/sys/powerpc/powerpc/vm_machdep.c
+++ b/sys/powerpc/powerpc/vm_machdep.c
@@ -126,7 +126,7 @@ cpu_fork(p1, p2, flags)
return;
p2->p_md.md_tf = p1->p_md.md_tf;
- p2->p_md.md_flags = p1->p_md.md_flags & MDP_FPUSED;
+ p2->p_md.md_flags = p1->p_md.md_flags & (MDP_FPUSED | MDP_UAC_MASK);
/*
* Cache the physical address of the pcb, so we can
OpenPOWER on IntegriCloud