Exemple #1
0
/*
 * Generate some output and apply a statistical RNG test to it.
 */
static void
cprng_strong_rngtest(struct cprng_strong *cprng)
{

	KASSERT(mutex_owned(&cprng->cs_lock));

	/* XXX Switch to a pool cache instead?  */
	rngtest_t *const rt = kmem_intr_alloc(sizeof(*rt), KM_NOSLEEP);
	if (rt == NULL)
		/* XXX Warn?  */
		return;

	(void)strlcpy(rt->rt_name, cprng->cs_name, sizeof(rt->rt_name));

	if (nist_ctr_drbg_generate(&cprng->cs_drbg, rt->rt_b, sizeof(rt->rt_b),
		NULL, 0))
		panic("cprng %s: NIST CTR_DRBG failed after reseed",
		    cprng->cs_name);

	if (rngtest(rt)) {
		printf("cprng %s: failed statistical RNG test\n",
		    cprng->cs_name);
		/* XXX Not clear that this does any good...  */
		cprng->cs_ready = false;
		rndsink_schedule(cprng->cs_rndsink);
	}

	explicit_memset(rt, 0, sizeof(*rt)); /* paranoia */
	kmem_intr_free(rt, sizeof(*rt));
}
Exemple #2
0
static void
feedrandom(size_t bytes, void *arg)
{
	uint8_t *rnddata;
	size_t dsize;

	rnddata = kmem_intr_alloc(MAXGET, KM_SLEEP);
	if (rumpuser_getrandom(rnddata, MIN(MAXGET, bytes),
	    RUMPUSER_RANDOM_HARD|RUMPUSER_RANDOM_NOWAIT, &dsize) == 0)
		rnd_add_data(&rndsrc, rnddata, dsize, NBBY*dsize);
	kmem_intr_free(rnddata, MAXGET);
}
Exemple #3
0
/*
 * Common function for DMA map creation.  May be called by bus-specific
 * DMA map creation functions.
 */
int
bus_dmamap_create(bus_dma_tag_t t, bus_size_t size, int nsegments,
	bus_size_t maxsegsz, bus_size_t boundary, int flags,
	bus_dmamap_t *dmamp)
{
	bus_dmamap_t map;
	void *mapstore;
	size_t mapsize;

	/*
	 * Allocate and initialize the DMA map.  The end of the map
	 * is a variable-sized array of segments, so we allocate enough
	 * room for them in one shot.
	 *
	 * Note we don't preserve the WAITOK or NOWAIT flags.  Preservation
	 * of ALLOCNOW notifies others that we've reserved these resources,
	 * and they are not to be freed.
	 *
	 * The bus_dmamap_t includes one bus_dma_segment_t, hence
	 * the (nsegments - 1).
	 */
	mapsize = sizeof(*map) + sizeof(bus_dma_segment_t [nsegments - 1]);
	if ((mapstore = kmem_intr_alloc(mapsize,
	    (flags & BUS_DMA_NOWAIT) ? KM_NOSLEEP : KM_SLEEP)) == NULL)
		return (ENOMEM);

	memset(mapstore, 0, mapsize);
	map = (void *)mapstore;
	map->_dm_size = size;
	map->_dm_segcnt = nsegments;
	map->_dm_maxmaxsegsz = maxsegsz;
	map->_dm_boundary = boundary;
	map->_dm_bounce_thresh = 0;
	map->_dm_flags = flags & ~(BUS_DMA_WAITOK|BUS_DMA_NOWAIT);
	map->dm_maxsegsz = maxsegsz;
	map->dm_mapsize = 0;		/* no valid mappings */
	map->dm_nsegs = 0;

	*dmamp = map;
	return (0);
}
Exemple #4
0
void *
intr_establish_xname(int hwirq, int type, int ipl, int (*ih_fun)(void *),
    void *ih_arg, const char *xname)
{
	struct intrhand **p, *q, *ih;
	struct pic_ops *pic;
	static struct intrhand fakehand;
	int maxipl = ipl;

	if (maxipl == IPL_NONE)
		maxipl = IPL_HIGH;

	if (hwirq >= max_base) {
		panic("%s: bogus IRQ %d, max is %d", __func__, hwirq,
		    max_base - 1);
	}

	pic = find_pic_by_hwirq(hwirq);
	if (pic == NULL) {
		panic("%s: cannot find a pic for IRQ %d", __func__, hwirq);
	}

	const int virq = mapirq(hwirq);

	/* no point in sleeping unless someone can free memory. */
	ih = kmem_intr_alloc(sizeof(*ih), cold ? KM_NOSLEEP : KM_SLEEP);
	if (ih == NULL)
		panic("intr_establish: can't allocate handler info");

	if (!PIC_VIRQ_LEGAL_P(virq) || type == IST_NONE)
		panic("intr_establish: bogus irq (%d) or type (%d)",
		    hwirq, type);

	struct intr_source * const is = &intrsources[virq];

	switch (is->is_type) {
	case IST_NONE:
		is->is_type = type;
		break;
	case IST_EDGE_FALLING:
	case IST_EDGE_RISING:
	case IST_LEVEL_LOW:
	case IST_LEVEL_HIGH:
		if (type == is->is_type)
			break;
		/* FALLTHROUGH */
	case IST_PULSE:
		if (type != IST_NONE)
			panic("intr_establish: can't share %s with %s",
			    intr_typename(is->is_type),
			    intr_typename(type));
		break;
	}
	if (is->is_hand == NULL) {
		snprintf(is->is_source, sizeof(is->is_source), "irq %d",
		    is->is_hwirq);
		evcnt_attach_dynamic(&is->is_ev, EVCNT_TYPE_INTR, NULL,
		    pic->pic_name, is->is_source);
	}

	/*
	 * Figure out where to put the handler.
	 * This is O(N^2), but we want to preserve the order, and N is
	 * generally small.
	 */
	for (p = &is->is_hand; (q = *p) != NULL; p = &q->ih_next) {
		maxipl = max(maxipl, q->ih_ipl);
	}

	/*
	 * Actually install a fake handler momentarily, since we might be doing
	 * this with interrupts enabled and don't want the real routine called
	 * until masking is set up.
	 */
	fakehand.ih_ipl = ipl;
	fakehand.ih_fun = fakeintr;
	*p = &fakehand;

	/*
	 * Poke the real handler in now.
	 */
	ih->ih_fun = ih_fun;
	ih->ih_arg = ih_arg;
	ih->ih_next = NULL;
	ih->ih_ipl = ipl;
	ih->ih_virq = virq;
	strlcpy(ih->ih_xname, xname != NULL ? xname : "unknown",
	    sizeof(ih->ih_xname));
	*p = ih;

	if (pic->pic_establish_irq != NULL)
		pic->pic_establish_irq(pic, hwirq - pic->pic_intrbase,
		    is->is_type, maxipl);

	/*
	 * Remember the highest IPL used by this handler.
	 */
	is->is_ipl = maxipl;

	/*
	 * now that the handler is established we're actually ready to
	 * calculate the masks
	 */
	intr_calculatemasks();

	return ih;
}