diff options
-rw-r--r-- | sys/alpha/alpha/sys_machdep.c | 48 | ||||
-rw-r--r-- | sys/alpha/alpha/trap.c | 16 | ||||
-rw-r--r-- | sys/alpha/alpha/vm_machdep.c | 2 | ||||
-rw-r--r-- | sys/alpha/include/proc.h | 5 | ||||
-rw-r--r-- | sys/alpha/include/sysarch.h | 2 | ||||
-rw-r--r-- | sys/powerpc/aim/vm_machdep.c | 2 | ||||
-rw-r--r-- | sys/powerpc/powerpc/vm_machdep.c | 2 |
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 |