View | Details | Raw Unified | Return to bug 132622
Collapse All | Expand All

(-)glxsb.c (-41 / +80 lines)
Lines 40-49 __FBSDID("$FreeBSD: src/sys/dev/glxsb/gl Link Here
40
#include <sys/random.h>
40
#include <sys/random.h>
41
#include <sys/rman.h>
41
#include <sys/rman.h>
42
#include <sys/rwlock.h>
42
#include <sys/rwlock.h>
43
#include <sys/sysctl.h>
43
#include <sys/sysctl.h>
44
#include <sys/taskqueue.h>
44
#include <sys/taskqueue.h>
45
#include <vm/uma.h>
45
46
46
#include <machine/bus.h>
47
#include <machine/bus.h>
47
#include <machine/cpufunc.h>
48
#include <machine/cpufunc.h>
48
#include <machine/resource.h>
49
#include <machine/resource.h>
49
50
Lines 172-181 struct glxsb_dma_map { Link Here
172
struct glxsb_taskop {
173
struct glxsb_taskop {
173
	struct glxsb_session	*to_ses;	/* crypto session */
174
	struct glxsb_session	*to_ses;	/* crypto session */
174
	struct cryptop		*to_crp;	/* cryptop to perfom */
175
	struct cryptop		*to_crp;	/* cryptop to perfom */
175
	struct cryptodesc	*to_enccrd;	/* enccrd to perform */
176
	struct cryptodesc	*to_enccrd;	/* enccrd to perform */
176
	struct cryptodesc	*to_maccrd;	/* maccrd to perform */
177
	struct cryptodesc	*to_maccrd;	/* maccrd to perform */
178
	TAILQ_ENTRY(glxsb_taskop) to_next;
177
};
179
};
178
180
179
struct glxsb_softc {
181
struct glxsb_softc {
180
	device_t		sc_dev;		/* device backpointer */
182
	device_t		sc_dev;		/* device backpointer */
181
	struct resource		*sc_sr;		/* resource */
183
	struct resource		*sc_sr;		/* resource */
Lines 190-201 struct glxsb_softc { Link Here
190
				sc_sessions;	/* crypto sessions */
192
				sc_sessions;	/* crypto sessions */
191
	struct rwlock		sc_sessions_lock;/* sessions lock */
193
	struct rwlock		sc_sessions_lock;/* sessions lock */
192
	struct mtx		sc_task_mtx;	/* task mutex */
194
	struct mtx		sc_task_mtx;	/* task mutex */
193
	struct taskqueue	*sc_tq;		/* task queue */
195
	struct taskqueue	*sc_tq;		/* task queue */
194
	struct task		sc_cryptotask;	/* task */
196
	struct task		sc_cryptotask;	/* task */
195
	struct glxsb_taskop	sc_to;		/* task's crypto operation */
197
	TAILQ_HEAD(to_head, glxsb_taskop)
196
	int			sc_task_count;	/* tasks count */
198
				sc_taskops;	/* tasks operations */
199
	uma_zone_t 		sc_taskops_zone;/* tasks operations' zone */
197
};
200
};
198
201
199
static int glxsb_probe(device_t);
202
static int glxsb_probe(device_t);
200
static int glxsb_attach(device_t);
203
static int glxsb_attach(device_t);
201
static int glxsb_detach(device_t);
204
static int glxsb_detach(device_t);
Lines 347-363 static int Link Here
347
glxsb_detach(device_t dev)
350
glxsb_detach(device_t dev)
348
{
351
{
349
	struct glxsb_softc *sc = device_get_softc(dev);
352
	struct glxsb_softc *sc = device_get_softc(dev);
350
	struct glxsb_session *ses;
353
	struct glxsb_session *ses;
351
354
355
	/* do not detach if there are pending tasks */
356
	if (!mtx_trylock(&sc->sc_task_mtx))
357
		goto busy;
358
	if (!TAILQ_EMPTY(&sc->sc_taskops)) {
359
		mtx_unlock(&sc->sc_task_mtx);
360
		goto busy;
361
	}
362
	mtx_unlock(&sc->sc_task_mtx);
363
	
364
	/* do not detach if there are active sessions */
352
	rw_wlock(&sc->sc_sessions_lock);
365
	rw_wlock(&sc->sc_sessions_lock);
353
	TAILQ_FOREACH(ses, &sc->sc_sessions, ses_next) {
366
	TAILQ_FOREACH(ses, &sc->sc_sessions, ses_next) {
354
		if (ses->ses_used) {
367
		if (ses->ses_used) {
355
			rw_wunlock(&sc->sc_sessions_lock);
368
			rw_wunlock(&sc->sc_sessions_lock);
356
			device_printf(dev,
369
			goto busy;
357
				"cannot detach, sessions still active.\n");
358
			return (EBUSY);
359
		}
370
		}
360
	}
371
	}
361
	while (!TAILQ_EMPTY(&sc->sc_sessions)) {
372
	while (!TAILQ_EMPTY(&sc->sc_sessions)) {
362
		ses = TAILQ_FIRST(&sc->sc_sessions);
373
		ses = TAILQ_FIRST(&sc->sc_sessions);
363
		TAILQ_REMOVE(&sc->sc_sessions, ses, ses_next);
374
		TAILQ_REMOVE(&sc->sc_sessions, ses, ses_next);
Lines 371-381 glxsb_detach(device_t dev) Link Here
371
	glxsb_dma_free(sc, &sc->sc_dma);
382
	glxsb_dma_free(sc, &sc->sc_dma);
372
	bus_release_resource(dev, SYS_RES_MEMORY, sc->sc_rid, sc->sc_sr);
383
	bus_release_resource(dev, SYS_RES_MEMORY, sc->sc_rid, sc->sc_sr);
373
	taskqueue_free(sc->sc_tq);
384
	taskqueue_free(sc->sc_tq);
374
	rw_destroy(&sc->sc_sessions_lock);
385
	rw_destroy(&sc->sc_sessions_lock);
375
	mtx_destroy(&sc->sc_task_mtx);
386
	mtx_destroy(&sc->sc_task_mtx);
387
	uma_zdestroy(sc->sc_taskops_zone);
376
	return (0);
388
	return (0);
389
390
busy:
391
	device_printf(dev,
392
	    "cannot detach, sessions still active.\n");
393
	return (EBUSY);
377
}
394
}
378
395
379
/*
396
/*
380
 *	callback for bus_dmamap_load()
397
 *	callback for bus_dmamap_load()
381
 */
398
 */
Lines 493-505 glxsb_crypto_setup(struct glxsb_softc *s Link Here
493
		return (ENOMEM);
510
		return (ENOMEM);
494
	}
511
	}
495
512
496
	TAILQ_INIT(&sc->sc_sessions);
513
	TAILQ_INIT(&sc->sc_sessions);
497
	sc->sc_sid = 1;
514
	sc->sc_sid = 1;
515
	TAILQ_INIT(&sc->sc_taskops);
516
	sc->sc_taskops_zone = uma_zcreate("glxsb_taskop", 
517
	    sizeof(struct glxsb_taskop), 0, 0, 0, 0,
518
	    UMA_ALIGN_PTR, UMA_ZONE_ZINIT);	
498
	rw_init(&sc->sc_sessions_lock, "glxsb_sessions_lock");
519
	rw_init(&sc->sc_sessions_lock, "glxsb_sessions_lock");
499
	mtx_init(&sc->sc_task_mtx, "glxsb_crypto_mtx", NULL, MTX_DEF);
520
	mtx_init(&sc->sc_task_mtx, "glxsb_crypto_mtx", NULL, MTX_DEF);
500
521
522
	if (sc->sc_taskops_zone == NULL) {
523
		device_printf(sc->sc_dev, "cannot setup taskops zone\n");
524
		goto crypto_fail;
525
	}
501
	if (crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0) != 0)
526
	if (crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0) != 0)
502
		goto crypto_fail;
527
		goto crypto_fail;
503
	if (crypto_register(sc->sc_cid, CRYPTO_NULL_HMAC, 0, 0) != 0)
528
	if (crypto_register(sc->sc_cid, CRYPTO_NULL_HMAC, 0, 0) != 0)
504
		goto crypto_fail;
529
		goto crypto_fail;
505
	if (crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0) != 0)
530
	if (crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0) != 0)
Lines 520-529 glxsb_crypto_setup(struct glxsb_softc *s Link Here
520
crypto_fail:
545
crypto_fail:
521
	device_printf(sc->sc_dev, "cannot register crypto\n");
546
	device_printf(sc->sc_dev, "cannot register crypto\n");
522
	crypto_unregister_all(sc->sc_cid);
547
	crypto_unregister_all(sc->sc_cid);
523
	rw_destroy(&sc->sc_sessions_lock);
548
	rw_destroy(&sc->sc_sessions_lock);
524
	mtx_destroy(&sc->sc_task_mtx);
549
	mtx_destroy(&sc->sc_task_mtx);
550
	uma_zdestroy(sc->sc_taskops_zone);
525
	return (ENOMEM);
551
	return (ENOMEM);
526
}
552
}
527
553
528
static int
554
static int
529
glxsb_crypto_newsession(device_t dev, uint32_t *sidp, struct cryptoini *cri)
555
glxsb_crypto_newsession(device_t dev, uint32_t *sidp, struct cryptoini *cri)
Lines 818-870 glxsb_crypto_encdec(struct cryptop *crp, Link Here
818
844
819
static void
845
static void
820
glxsb_crypto_task(void *arg, int pending)
846
glxsb_crypto_task(void *arg, int pending)
821
{
847
{
822
	struct glxsb_softc *sc = arg;
848
	struct glxsb_softc *sc = arg;
849
	struct glxsb_taskop *taskop;
823
	struct glxsb_session *ses;
850
	struct glxsb_session *ses;
824
	struct cryptop *crp;
851
	struct cryptop *crp;
825
	struct cryptodesc *enccrd, *maccrd;
852
	struct cryptodesc *enccrd, *maccrd;
826
	int error;
853
	int error;
827
854
828
	maccrd = sc->sc_to.to_maccrd;
855
	for (; pending > 0; pending--) {
829
	enccrd = sc->sc_to.to_enccrd;
856
		/* pop crypto request */
830
	crp = sc->sc_to.to_crp;
857
		mtx_lock(&sc->sc_task_mtx);
831
	ses = sc->sc_to.to_ses;
858
		taskop = TAILQ_FIRST(&sc->sc_taskops);
832
859
		if (taskop != NULL) {
833
	/* Perform data authentication if requested before encryption */
860
			TAILQ_REMOVE(&sc->sc_taskops, taskop, to_next);
834
	if (maccrd != NULL && maccrd->crd_next == enccrd) {
861
			mtx_unlock(&sc->sc_task_mtx);
835
		error = glxsb_hash_process(ses, maccrd, crp);
862
		} else {
836
		if (error != 0)
863
			/* should not happen */
837
			goto out;
864
			mtx_unlock(&sc->sc_task_mtx);
838
	}
865
			continue;
839
866
		}
840
	error = glxsb_crypto_encdec(crp, enccrd, ses, sc);
867
		maccrd = taskop->to_maccrd;
841
	if (error != 0)
868
		enccrd = taskop->to_enccrd;
842
		goto out;
869
		crp = taskop->to_crp;
870
		ses = taskop->to_ses;
871
		uma_zfree(sc->sc_taskops_zone, taskop);
872
873
		/* Perform data authentication if requested before encryption */
874
		if (maccrd != NULL && maccrd->crd_next == enccrd) {
875
			error = glxsb_hash_process(ses, maccrd, crp);
876
			if (error != 0)
877
				goto crypto_out;
878
		}
843
879
844
	/* Perform data authentication if requested after encryption */
880
		error = glxsb_crypto_encdec(crp, enccrd, ses, sc);
845
	if (maccrd != NULL && enccrd->crd_next == maccrd) {
846
		error = glxsb_hash_process(ses, maccrd, crp);
847
		if (error != 0)
881
		if (error != 0)
848
			goto out;
882
			goto crypto_out;
849
	}
850
out:
851
	mtx_lock(&sc->sc_task_mtx);
852
	sc->sc_task_count--;
853
	mtx_unlock(&sc->sc_task_mtx);
854
883
855
	crp->crp_etype = error;
884
		/* Perform data authentication if requested after encryption */
856
	crypto_unblock(sc->sc_cid, CRYPTO_SYMQ);
885
		if (maccrd != NULL && enccrd->crd_next == maccrd) {
857
	crypto_done(crp);
886
			error = glxsb_hash_process(ses, maccrd, crp);
887
			if (error != 0)
888
				goto crypto_out;
889
		}
890
891
crypto_out:
892
		crp->crp_etype = error;
893
		crypto_done(crp);
894
	} /* for */
858
}
895
}
859
896
860
static int
897
static int
861
glxsb_crypto_process(device_t dev, struct cryptop *crp, int hint)
898
glxsb_crypto_process(device_t dev, struct cryptop *crp, int hint)
862
{
899
{
863
	struct glxsb_softc *sc = device_get_softc(dev);
900
	struct glxsb_softc *sc = device_get_softc(dev);
864
	struct glxsb_session *ses;
901
	struct glxsb_session *ses;
865
	struct cryptodesc *crd, *enccrd, *maccrd;
902
	struct cryptodesc *crd, *enccrd, *maccrd;
903
	struct glxsb_taskop *taskop;
866
	uint32_t sid;
904
	uint32_t sid;
867
	int error = 0;
905
	int error = 0;
868
906
869
	enccrd = maccrd = NULL;
907
	enccrd = maccrd = NULL;
870
908
Lines 920-942 glxsb_crypto_process(device_t dev, struc Link Here
920
	if (ses == NULL || !ses->ses_used) {
958
	if (ses == NULL || !ses->ses_used) {
921
		error = EINVAL;
959
		error = EINVAL;
922
		goto fail;
960
		goto fail;
923
	}
961
	}
924
962
963
	/* queue the crypto request */
925
	mtx_lock(&sc->sc_task_mtx);
964
	mtx_lock(&sc->sc_task_mtx);
926
	if (sc->sc_task_count != 0) {
965
	taskop = uma_zalloc(sc->sc_taskops_zone, M_NOWAIT);
966
	if (taskop == NULL) {
927
		mtx_unlock(&sc->sc_task_mtx);
967
		mtx_unlock(&sc->sc_task_mtx);
928
		return (ERESTART);
968
		error = ENOMEM;
969
		goto fail;
929
	}
970
	}
930
	sc->sc_task_count++;
971
	taskop->to_maccrd = maccrd;
931
972
	taskop->to_enccrd = enccrd;
932
	sc->sc_to.to_maccrd = maccrd;
973
	taskop->to_crp = crp;
933
	sc->sc_to.to_enccrd = enccrd;
974
	taskop->to_ses = ses;
934
	sc->sc_to.to_crp = crp;
975
	TAILQ_INSERT_TAIL(&sc->sc_taskops, taskop, to_next);
935
	sc->sc_to.to_ses = ses;
936
	mtx_unlock(&sc->sc_task_mtx);
976
	mtx_unlock(&sc->sc_task_mtx);
937
938
	taskqueue_enqueue(sc->sc_tq, &sc->sc_cryptotask);
977
	taskqueue_enqueue(sc->sc_tq, &sc->sc_cryptotask);
939
	return(0);
978
	return(0);
940
979
941
fail:
980
fail:
942
	crp->crp_etype = error;
981
	crp->crp_etype = error;

Return to bug 132622