# HG changeset patch # User Taylor R Campbell # Date 1594060629 0 # Mon Jul 06 18:37:09 2020 +0000 # Branch trunk # Node ID ec0152a800f32b42b4e761b90eecb49d5a77d2a5 # Parent f5f91efd688827dfb27026b977bb9ccfab60d799 Limit x86 fpu_kern_enter/leave to IPL_VM or below. There are no users of crypto at IPL_SCHED or IPL_HIGH as far as I know, and although we generally limit the amount of time spent in any one crypto operation -- e.g., cgd is usually limited to processing 512 or 4096 bytes at a time -- it's better not to block IPL_SCHED and IPL_HIGH interrupts at all. This should make ddb a little more accessible during crypto-heavy workloads. This means the aes_* API cannot be used at IPL_SCHED or IPL_HIGH; the same will go for any new crypto subsystems, like the ChaCha and Poly1305 ones I'm drafting. It might be better to prohibit them altogether in hard interrupt context, but right now cprng_fast and cprng_strong are both technically allowed at IPL_VM and are sometimes used there (e.g., for opencrypto CBC IV generation). KASSERT the ilevel to detect violation of this constraint in case I'm wrong. diff -r f5f91efd6888 -r ec0152a800f3 sys/arch/x86/x86/fpu.c --- a/sys/arch/x86/x86/fpu.c Sun Jul 05 14:24:05 2020 +0000 +++ b/sys/arch/x86/x86/fpu.c Mon Jul 06 18:37:09 2020 +0000 @@ -370,11 +370,14 @@ fpu_lwp_abandon(struct lwp *l) /* * fpu_kern_enter() * - * Begin using the FPU. Raises to splhigh, disabling all + * Begin using the FPU. Raises to splvm, disabling most * interrupts and rendering the thread non-preemptible; caller * should not use this for long periods of time, and must call * fpu_kern_leave() afterward. Non-recursive -- you cannot call * fpu_kern_enter() again without calling fpu_kern_leave() first. + * + * Must be used only at IPL_VM or below -- never in IPL_SCHED or + * IPL_HIGH interrupt handlers. */ void fpu_kern_enter(void) @@ -383,9 +386,10 @@ fpu_kern_enter(void) struct cpu_info *ci; int s; - s = splhigh(); + s = splvm(); ci = curcpu(); + KASSERTMSG(ci->ci_ilevel <= IPL_VM, "ilevel=%d", ci->ci_ilevel); KASSERT(ci->ci_kfpu_spl == -1); ci->ci_kfpu_spl = s; @@ -423,7 +427,7 @@ fpu_kern_leave(void) struct cpu_info *ci = curcpu(); int s; - KASSERT(ci->ci_ilevel == IPL_HIGH); + KASSERT(ci->ci_ilevel == IPL_VM); KASSERT(ci->ci_kfpu_spl != -1); /*