aesni: Switch to using FPU_KERN_NOCTX.

Reviewed by:	kib
Differential Revision:	https://reviews.freebsd.org/D41577
This commit is contained in:
John Baldwin 2023-08-28 16:22:15 -07:00
parent d1e4c63d9e
commit 937b4473be

View file

@ -40,11 +40,9 @@
#include <sys/kernel.h> #include <sys/kernel.h>
#include <sys/kobj.h> #include <sys/kobj.h>
#include <sys/libkern.h> #include <sys/libkern.h>
#include <sys/lock.h>
#include <sys/malloc.h> #include <sys/malloc.h>
#include <sys/mbuf.h> #include <sys/mbuf.h>
#include <sys/module.h> #include <sys/module.h>
#include <sys/mutex.h>
#include <sys/smp.h> #include <sys/smp.h>
#include <sys/systm.h> #include <sys/systm.h>
#include <sys/uio.h> #include <sys/uio.h>
@ -63,28 +61,12 @@
#include <machine/specialreg.h> #include <machine/specialreg.h>
#include <machine/fpu.h> #include <machine/fpu.h>
static struct mtx_padalign *ctx_mtx;
static struct fpu_kern_ctx **ctx_fpu;
struct aesni_softc { struct aesni_softc {
int32_t cid; int32_t cid;
bool has_aes; bool has_aes;
bool has_sha; bool has_sha;
}; };
#define ACQUIRE_CTX(i, ctx) \
do { \
(i) = PCPU_GET(cpuid); \
mtx_lock(&ctx_mtx[(i)]); \
(ctx) = ctx_fpu[(i)]; \
} while (0)
#define RELEASE_CTX(i, ctx) \
do { \
mtx_unlock(&ctx_mtx[(i)]); \
(i) = -1; \
(ctx) = NULL; \
} while (0)
static int aesni_cipher_setup(struct aesni_session *ses, static int aesni_cipher_setup(struct aesni_session *ses,
const struct crypto_session_params *csp); const struct crypto_session_params *csp);
static int aesni_cipher_process(struct aesni_session *ses, struct cryptop *crp); static int aesni_cipher_process(struct aesni_session *ses, struct cryptop *crp);
@ -136,30 +118,10 @@ aesni_probe(device_t dev)
return (0); return (0);
} }
static void
aesni_cleanctx(void)
{
int i;
/* XXX - no way to return driverid */
CPU_FOREACH(i) {
if (ctx_fpu[i] != NULL) {
mtx_destroy(&ctx_mtx[i]);
fpu_kern_free_ctx(ctx_fpu[i]);
}
ctx_fpu[i] = NULL;
}
free(ctx_mtx, M_AESNI);
ctx_mtx = NULL;
free(ctx_fpu, M_AESNI);
ctx_fpu = NULL;
}
static int static int
aesni_attach(device_t dev) aesni_attach(device_t dev)
{ {
struct aesni_softc *sc; struct aesni_softc *sc;
int i;
sc = device_get_softc(dev); sc = device_get_softc(dev);
@ -171,21 +133,6 @@ aesni_attach(device_t dev)
return (ENOMEM); return (ENOMEM);
} }
ctx_mtx = malloc(sizeof *ctx_mtx * (mp_maxid + 1), M_AESNI,
M_WAITOK|M_ZERO);
ctx_fpu = malloc(sizeof *ctx_fpu * (mp_maxid + 1), M_AESNI,
M_WAITOK|M_ZERO);
CPU_FOREACH(i) {
#ifdef __amd64__
ctx_fpu[i] = fpu_kern_alloc_ctx_domain(
pcpu_find(i)->pc_domain, FPU_KERN_NORMAL);
#else
ctx_fpu[i] = fpu_kern_alloc_ctx(FPU_KERN_NORMAL);
#endif
mtx_init(&ctx_mtx[i], "anifpumtx", NULL, MTX_DEF|MTX_NEW);
}
detect_cpu_features(&sc->has_aes, &sc->has_sha); detect_cpu_features(&sc->has_aes, &sc->has_sha);
return (0); return (0);
} }
@ -199,8 +146,6 @@ aesni_detach(device_t dev)
crypto_unregister_all(sc->cid); crypto_unregister_all(sc->cid);
aesni_cleanctx();
return (0); return (0);
} }
@ -551,9 +496,9 @@ static int
aesni_cipher_setup(struct aesni_session *ses, aesni_cipher_setup(struct aesni_session *ses,
const struct crypto_session_params *csp) const struct crypto_session_params *csp)
{ {
struct fpu_kern_ctx *ctx;
uint8_t *schedbase; uint8_t *schedbase;
int kt, ctxidx, error; int error;
bool kt;
schedbase = (uint8_t *)roundup2((uintptr_t)ses->schedules, schedbase = (uint8_t *)roundup2((uintptr_t)ses->schedules,
AES_SCHED_ALIGN); AES_SCHED_ALIGN);
@ -607,11 +552,10 @@ aesni_cipher_setup(struct aesni_session *ses,
ses->mlen = csp->csp_auth_mlen; ses->mlen = csp->csp_auth_mlen;
} }
kt = is_fpu_kern_thread(0) || (csp->csp_cipher_alg == 0); kt = (csp->csp_cipher_alg == 0);
if (!kt) { if (!kt) {
ACQUIRE_CTX(ctxidx, ctx); fpu_kern_enter(curthread, NULL,
fpu_kern_enter(curthread, ctx, FPU_KERN_NORMAL | FPU_KERN_NOCTX);
FPU_KERN_NORMAL | FPU_KERN_KTHR);
} }
error = 0; error = 0;
@ -620,8 +564,7 @@ aesni_cipher_setup(struct aesni_session *ses,
csp->csp_cipher_klen); csp->csp_cipher_klen);
if (!kt) { if (!kt) {
fpu_kern_leave(curthread, ctx); fpu_kern_leave(curthread, NULL);
RELEASE_CTX(ctxidx, ctx);
} }
return (error); return (error);
} }
@ -630,9 +573,7 @@ static int
aesni_cipher_process(struct aesni_session *ses, struct cryptop *crp) aesni_cipher_process(struct aesni_session *ses, struct cryptop *crp)
{ {
const struct crypto_session_params *csp; const struct crypto_session_params *csp;
struct fpu_kern_ctx *ctx; int error;
int error, ctxidx;
bool kt;
csp = crypto_get_params(crp->crp_session); csp = crypto_get_params(crp->crp_session);
switch (csp->csp_cipher_alg) { switch (csp->csp_cipher_alg) {
@ -653,15 +594,7 @@ aesni_cipher_process(struct aesni_session *ses, struct cryptop *crp)
break; break;
} }
ctx = NULL; fpu_kern_enter(curthread, NULL, FPU_KERN_NORMAL | FPU_KERN_NOCTX);
ctxidx = 0;
error = 0;
kt = is_fpu_kern_thread(0);
if (!kt) {
ACQUIRE_CTX(ctxidx, ctx);
fpu_kern_enter(curthread, ctx,
FPU_KERN_NORMAL | FPU_KERN_KTHR);
}
/* Do work */ /* Do work */
if (csp->csp_mode == CSP_MODE_ETA) { if (csp->csp_mode == CSP_MODE_ETA) {
@ -679,10 +612,7 @@ aesni_cipher_process(struct aesni_session *ses, struct cryptop *crp)
else else
error = aesni_cipher_crypt(ses, crp, csp); error = aesni_cipher_crypt(ses, crp, csp);
if (!kt) { fpu_kern_leave(curthread, NULL);
fpu_kern_leave(curthread, ctx);
RELEASE_CTX(ctxidx, ctx);
}
return (error); return (error);
} }