diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2017-11-12 22:55:54 +0100 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2017-11-12 22:55:54 +0100 |
commit | 4f27f6a04f8c8709e20767b50bd7c2a22ab29340 (patch) | |
tree | bae2cf8f21f38bf9551bbc66c3d3156e9d6d0bf9 /sys/src/9/pc64/dat.h | |
parent | 3ccd53549f245d61a1d7e4369934c502fba9c2cb (diff) |
pc64: allow using the FPU in syscall and pagefault handlers
The aim is to take advantage of SSE instructions such as AES-NI
in the kernel by lazily saving and restoring FPU state across
system calls and pagefaults. (everything can can do I/O)
This is accomplished by the functions fpusave() and fpurestore().
fpusave() remembers the current state and disables the FPU if it
was active by setting the TS flag. In case the FPU gets used,
the current state gets saved and a new PFPU.fpslot is allocated
by mathemu().
fpurestore() restores the previous FPU state, reenabling the FPU
if fpusave() disabled it.
In the most common case, when userspace is not using the FPU,
then fpusave()/fpurestore() just toggle the FPpush bit in
up->fpstate.
When the FPU was active, but we do not use the FPU, then nothing
needs to be saved or restored. We just switched the TS flag on
and off agaian.
Note, this is done for the amd64 kernel only.
Diffstat (limited to 'sys/src/9/pc64/dat.h')
-rw-r--r-- | sys/src/9/pc64/dat.h | 29 |
1 files changed, 21 insertions, 8 deletions
diff --git a/sys/src/9/pc64/dat.h b/sys/src/9/pc64/dat.h index 4dde0ec1b..8106cf1cb 100644 --- a/sys/src/9/pc64/dat.h +++ b/sys/src/9/pc64/dat.h @@ -65,12 +65,6 @@ struct FPsave uchar ign[96]; /* reserved, ignored */ }; -struct PFPU -{ - int fpstate; - FPsave *fpsave; -}; - enum { /* this is a state */ @@ -78,8 +72,27 @@ enum FPactive= 1, FPinactive= 2, - /* the following is a bit that can be or'd into the state */ - FPillegal= 0x100, + /* + * the following are bits that can be or'd into the state. + * + * this is biased so that FPinit, FPactive and FPinactive + * without any flags refer to user fp state in fpslot[0]. + */ + FPillegal= 1<<8, /* fp forbidden in note handler */ + FPpush= 2<<8, /* trap on use and initialize new fpslot */ + FPnouser= 4<<8, /* fpslot[0] is kernel regs */ + FPkernel= 8<<8, /* fp use in kernel (user in fpslot[0] when !FPnouser) */ + + FPindexs= 16, + FPindex1= 1<<FPindexs, + FPindexm= 3<<FPindexs, +}; + +struct PFPU +{ + int fpstate; + FPsave *fpsave; /* fpslot[fpstate>>FPindexs] */ + FPsave *fpslot[(FPindexm+1)>>FPindexs]; }; struct Confmem |