more portable fpu devprocio on the architecture of the new sse support for the pae kernel 1. there is no support for x87. an early version of this work had a FPArch structure, so that instead of fpclear, one wrote fp->clear(). while really clean, and potentially helpful for arm, this results in a lot of churn and incompatability. other than devarch, there should be no dependence on sse except in fpsse.c 2. in order to reduce churn, the assembly code does the proper rounding to insure alignment of the fxsave area. 3. devprocio is the only place where we care where the fxsave area is. the least churn was to add a default devprocio (the same as the old one), and allow architectures to override it. this saves us from having to import sse-specific ideas about alignment into the portable code. 4. odd bit: we are clearing the xmm registers by hand when fp is intialized to provide a consistent register state for new processes, and to avoid leaking register information. Reference: /n/atom/patch/applied2013/fpuprocio Date: Mon Jun 3 18:12:05 CES 2013 Signed-off-by: quanstro@quanstro.net --- /sys/src/9/port/devproc.c Mon Jun 3 18:00:25 2013 +++ /sys/src/9/port/devproc.c Mon Jun 3 18:00:26 2013 @@ -80,7 +80,7 @@ "args", {Qargs}, 0, 0660, "ctl", {Qctl}, 0, 0000, "fd", {Qfd}, 0, 0444, - "fpregs", {Qfpregs}, sizeof(FPsave), 0000, + "fpregs", {Qfpregs}, 0, 0000, "kregs", {Qkregs}, sizeof(Ureg), 0600, "mem", {Qmem}, 0, 0000, "note", {Qnote}, 0, 0000, @@ -178,6 +178,29 @@ } } +static long +·fpudevprocio(Proc *p, void *va, long n, uvlong offset, int write) +{ + uchar *fp; + int sz; + + fp = (uchar*)&p->fpsave; + sz = sizeof(FPsave); + + if(offset >= sz) + n = 0; + else if(offset+n > sz) + n = sz - offset; + + if(write) + memmove(fp+offset, va, n); + else + memmove(va, fp+offset, n); + return n; +} + +long (*fpudevprocio)(Proc*, void*, long, uvlong, int) = ·fpudevprocio; + static int procgen(Chan *c, char *name, Dirtab *tab, int, int s, Dir *dp) { @@ -805,11 +828,6 @@ setkernur(&kur, p); rptr = (uchar*)&kur; rsize = sizeof(Ureg); - goto regread; - - case Qfpregs: - rptr = (uchar*)&p->fpsave; - rsize = sizeof(FPsave); regread: if(rptr == 0) error(Enoreg); @@ -820,6 +838,9 @@ memmove(a, rptr+offset, n); return n; + case Qfpregs: + return fpudevprocio(p, va, n, offset, 0); + case Qstatus: if(offset >= STATSIZE) return 0; @@ -1070,11 +1091,7 @@ break; case Qfpregs: - if(offset >= sizeof(FPsave)) - n = 0; - else if(offset+n > sizeof(FPsave)) - n = sizeof(FPsave) - offset; - memmove((uchar*)&p->fpsave+offset, va, n); + n = fpudevprocio(p, va, n, offset, 1); break; case Qctl: