summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2005-12-17 16:08:36 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2005-12-17 16:08:36 +0000
commit1efabd602581b7ac811d1f628d9d9f1d8bcfa096 (patch)
treedea8703d6bdfdec9e4254b0014de1d4438429f93
parent00f8cc47ebb95c2a6d74080b7ad654e8db039c4a (diff)
Fix PT_{GET|SET}FPREGS. Make sure we flush the fpu before reading/modifying
the state in the pcb. Make sure we don't thrash the initial fpu state for (currently unsupported) 32-bit processes. ok miod@
-rw-r--r--sys/arch/sparc64/sparc64/process_machdep.c48
1 files changed, 26 insertions, 22 deletions
diff --git a/sys/arch/sparc64/sparc64/process_machdep.c b/sys/arch/sparc64/sparc64/process_machdep.c
index 2053ff0fb2b..221ba392a41 100644
--- a/sys/arch/sparc64/sparc64/process_machdep.c
+++ b/sys/arch/sparc64/sparc64/process_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: process_machdep.c,v 1.8 2005/12/16 21:37:05 miod Exp $ */
+/* $OpenBSD: process_machdep.c,v 1.9 2005/12/17 16:08:35 kettenis Exp $ */
/* $NetBSD: process_machdep.c,v 1.10 2000/09/26 22:05:50 eeh Exp $ */
/*
@@ -117,22 +117,24 @@ process_read_fpregs(p, regs)
struct fpreg *regs;
{
extern struct fpstate64 initfpstate;
- struct fpstate64 *statep = &initfpstate;
- struct fpreg32 *regp = (struct fpreg32 *)regs;
+ struct fpstate64 *statep = &initfpstate;
+ struct fpreg32 *regp = (struct fpreg32 *)regs;
int i;
+ /* NOTE: struct fpreg == struct fpstate */
+ if (p->p_md.md_fpstate) {
+ if (p == fpproc)
+ savefpstate(p->p_md.md_fpstate);
+ statep = p->p_md.md_fpstate;
+ }
+
if (!(curproc->p_flag & P_32)) {
/* 64-bit mode -- copy in fregs */
- /* NOTE: struct fpreg == struct fpstate */
- if (p->p_md.md_fpstate)
- statep = p->p_md.md_fpstate;
bcopy(statep, regs, sizeof(struct fpreg64));
return 0;
}
/* 32-bit mode -- copy out & convert 32-bit fregs */
- if (p->p_md.md_fpstate)
- statep = p->p_md.md_fpstate;
- for (i=0; i<32; i++)
+ for (i = 0; i < 32; i++)
regp->fr_regs[i] = statep->fs_regs[i];
return 0;
@@ -205,27 +207,29 @@ process_write_fpregs(p, regs)
struct proc *p;
struct fpreg *regs;
{
-
- extern struct fpstate64 initfpstate;
- struct fpstate64 *statep = &initfpstate;
- struct fpreg32 *regp = (struct fpreg32 *)regs;
+ struct fpstate64 *statep;
+ struct fpreg32 *regp = (struct fpreg32 *)regs;
int i;
+ if (p->p_md.md_fpstate == NULL)
+ return EINVAL;
+ else
+ statep = p->p_md.md_fpstate;
+
+ if (p == fpproc) {
+ /* Release the fpu. */
+ savefpstate(p->p_md.md_fpstate);
+ fpproc = NULL;
+ }
+
if (!(curproc->p_flag & P_32)) {
/* 64-bit mode -- copy in fregs */
- if (p->p_md.md_fpstate == NULL)
- return EINVAL;
-
- /* NOTE: struct fpreg == struct fpstate */
- bcopy(regs, p->p_md.md_fpstate, sizeof(struct fpreg64));
- statep = p->p_md.md_fpstate;
+ bcopy(regs, statep, sizeof(struct fpreg64));
statep->fs_qsize = 0;
return 0;
}
/* 32-bit mode -- copy in & convert 32-bit fregs */
- if (p->p_md.md_fpstate)
- statep = p->p_md.md_fpstate;
- for (i=0; i<32; i++)
+ for (i = 0; i < 32; i++)
statep->fs_regs[i] = regp->fr_regs[i];
statep->fs_fsr = regp->fr_fsr;
statep->fs_qsize = 0;