diff options
| author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2004-09-05 09:01:38 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2004-09-05 09:01:38 -0700 |
| commit | 5cdd97cbbc54f21f2ccea88b68898bb64441c8ef (patch) | |
| tree | fa14995d12841442b41fc7438c7e5a69a9d06710 | |
| parent | 4977b7a160a1c4c278210338ac734d62f92105d2 (diff) | |
| parent | f8ab48a7de37b1e97be3d8c776ef465a866ab102 (diff) | |
Merge bk://are.twiddle.net/axp-2.6
into ppc970.osdl.org:/home/torvalds/v2.6/linux
| -rw-r--r-- | arch/alpha/kernel/osf_sys.c | 40 | ||||
| -rw-r--r-- | include/asm-alpha/sysinfo.h | 1 |
2 files changed, 31 insertions, 10 deletions
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c index b45caf6aff9c..762a528bf20e 100644 --- a/arch/alpha/kernel/osf_sys.c +++ b/arch/alpha/kernel/osf_sys.c @@ -723,7 +723,8 @@ osf_setsysinfo(unsigned long op, void __user *buffer, unsigned long nbytes, { switch (op) { case SSI_IEEE_FP_CONTROL: { - unsigned long swcr, fpcr, fex; + unsigned long swcr, fpcr; + unsigned int *state; /* * Alpha Architecture Handbook 4.7.7.3: @@ -732,22 +733,42 @@ osf_setsysinfo(unsigned long op, void __user *buffer, unsigned long nbytes, * set in the trap shadow of a software-complete insn. */ - /* Update softare trap enable bits. */ if (get_user(swcr, (unsigned long __user *)buffer)) return -EFAULT; - current_thread_info()->ieee_state - = ((current_thread_info()->ieee_state & ~IEEE_SW_MASK) - | (swcr & IEEE_SW_MASK)); + state = ¤t_thread_info()->ieee_state; + + /* Update softare trap enable bits. */ + *state = (*state & ~IEEE_SW_MASK) | (swcr & IEEE_SW_MASK); + + /* Update the real fpcr. */ + fpcr = rdfpcr() & FPCR_DYN_MASK; + fpcr |= ieee_swcr_to_fpcr(swcr); + wrfpcr(fpcr); + + return 0; + } + + case SSI_IEEE_RAISE_EXCEPTION: { + unsigned long exc, swcr, fpcr, fex; + unsigned int *state; + + if (get_user(exc, (unsigned long __user *)buffer)) + return -EFAULT; + state = ¤t_thread_info()->ieee_state; + exc &= IEEE_STATUS_MASK; + + /* Update softare trap enable bits. */ + swcr = (*state & IEEE_SW_MASK) | exc; + *state |= exc; /* Update the real fpcr. */ fpcr = rdfpcr(); - fpcr &= FPCR_DYN_MASK; fpcr |= ieee_swcr_to_fpcr(swcr); wrfpcr(fpcr); - /* If any exceptions are now unmasked, send a signal. */ - fex = ((swcr & IEEE_STATUS_MASK) - >> IEEE_STATUS_TO_EXCSUM_SHIFT) & swcr; + /* If any exceptions set by this call, and are unmasked, + send a signal. Old exceptions are not signaled. */ + fex = (exc >> IEEE_STATUS_TO_EXCSUM_SHIFT) & swcr; if (fex) { siginfo_t info; int si_code = 0; @@ -765,7 +786,6 @@ osf_setsysinfo(unsigned long op, void __user *buffer, unsigned long nbytes, info.si_addr = NULL; /* FIXME */ send_sig_info(SIGFPE, &info, current); } - return 0; } diff --git a/include/asm-alpha/sysinfo.h b/include/asm-alpha/sysinfo.h index 1c65a021ac3b..086aba284df2 100644 --- a/include/asm-alpha/sysinfo.h +++ b/include/asm-alpha/sysinfo.h @@ -18,6 +18,7 @@ #define SSI_IEEE_FP_CONTROL 14 #define SSI_IEEE_STATE_AT_SIGNAL 15 #define SSI_IEEE_IGNORE_STATE_AT_SIGNAL 16 +#define SSI_IEEE_RAISE_EXCEPTION 1001 /* linux specific */ #define SSIN_UACPROC 6 |
