/* * 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)); }
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); }
/* * 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); }
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; }