Documentation
¶
Overview ¶
go-virtio/rng — driver core: feature negotiation + init sequence + entropy-read path for the modern virtio-entropy device (virtio-rng, Virtio 1.1 §5.4).
virtio-rng is the simplest device class in the spec: a single virtqueue (the "requestq"), no device-specific feature bits, and no device-config region. The driver places a device-writable buffer on the queue; the device fills it with random bytes and reports, via the used ring, how many bytes it wrote.
Index ¶
Constants ¶
const AcceptedFeatures uint64 = common.FeatureVersion1
AcceptedFeatures is the feature mask the driver negotiates ON. virtio-rng defines no device-specific feature bits (Virtio 1.1 §5.4.3), so the only bit we ever accept is the non-negotiable VIRTIO_F_VERSION_1 (modern transport).
const DefaultPollIterations = 200000
DefaultPollIterations is the busy-poll budget a plain Read spends waiting for the device to return a filled buffer. The entropy round-trip is sub-millisecond on every backend measured; this is a generous upper bound for the busy-poll model the driver uses.
const RequestQueueIdx uint16 = 0
RequestQueueIdx is the index of the single virtio-rng virtqueue (Virtio 1.1 §5.4.2 — "requestq", virtqueue 0).
const RequestQueueSize uint16 = 8
RequestQueueSize is the desired ring size for the request queue. A small ring is plenty: the driver keeps at most one buffer outstanding per Read call. Clamped down to the device's advertised maximum (and rounded to a power of two) during setup.
Variables ¶
var ( ErrNotModernDevice = commonRngError("go-virtio/rng: device doesn't offer VIRTIO_F_VERSION_1 (legacy-only)") ErrFeaturesNotOK = commonRngError("go-virtio/rng: FEATURES_OK status bit didn't stick after DriverFeature write") ErrInitWrongDeviceID = commonRngError("go-virtio/rng: PCI device ID is not 0x1044 (modern entropy device)") ErrQueueNotAvailable = commonRngError("go-virtio/rng: device reports QueueSize=0 for the request queue") ErrReadTimeout = commonRngError("go-virtio/rng: read poll timeout (device returned no entropy within budget)") )
Sentinel errors for the virtio-rng path. All exported so callers can branch + format them.
Functions ¶
func AcceptFeatures ¶
AcceptFeatures returns the negotiated feature mask: the intersection of what the device offers and what we accept. The caller writes this back via DriverFeature.
We require VIRTIO_F_VERSION_1 — if the device doesn't offer it, the device is legacy-only and we return ErrNotModernDevice.
Types ¶
type VirtioRng ¶
type VirtioRng struct {
// Cfg is the modern-transport handle (BARs + offsets + the
// BARMemoryAccessor used for every register access).
Cfg *common.ModernConfig
// NegotiatedFeatures records what the driver-feature handshake
// settled on. Exposed for diagnostic prints.
NegotiatedFeatures uint64
// contains filtered or unexported fields
}
VirtioRng wraps one initialised virtio-rng device. The caller holds this for the lifetime of the entropy source; the underlying virtqueue pages live as long as the supplied PageAllocator's lifetime contract.
func OpenVirtioRng ¶
OpenVirtioRng drives the full bring-up of one virtio-rng device:
- Verify the PCI device ID is 0x1044 (modern entropy).
- InitModernConfig walks PCI caps + populates the BAR locators.
- Reset → ACK → DRIVER status progression.
- Read DeviceFeature, mask to VERSION_1, write DriverFeature.
- Set FEATURES_OK, verify it stuck.
- Allocate + publish the request queue (queue 0).
- DRIVER_OK status.
On success the device is in DRIVER_OK state with an empty, ready request queue. Unlike virtio-net there is no device-config region to read and no buffers to pre-post — the driver posts a buffer on demand in Read.
func (*VirtioRng) Read ¶
Read fills p with entropy from the device, blocking (busy-poll) up to DefaultPollIterations per device round-trip. It always fills the whole of p on success (io.ReadFull-style semantics, matching crypto/rand's Reader contract) and returns len(p). A partial result is returned alongside an error if the device stalls or returns no bytes.
func (*VirtioRng) ReadPoll ¶
ReadPoll is the parameterised variant of Read that takes an explicit busy-poll budget (iterations spent waiting for each device round-trip). Useful for callers that want a tighter timeout than DefaultPollIterations.
func (*VirtioRng) RequestQueue ¶
RequestQueue exposes the request *common.Virtqueue handle. Read-only accessor so callers can inspect ring state for diagnostic dumps; the field itself stays unexported.