Documentation
¶
Overview ¶
Package vsock is a pure-Go virtio-vsock (socket device) driver. It drives a modern (Virtio 1.0+) PCI virtio-vsock device through the transport interfaces defined in github.com/go-virtio/common; the same code drives a UEFI-backed device, a bare-metal device, or a virtio-mmio device depending on which common.Transport implementation the caller supplies.
Scope — this package sits at the same altitude as go-virtio/net: it owns the device bring-up, the three virtqueues, and the on-the-wire struct virtio_vsock_hdr marshalling, and exposes a packet-level Send/Receive API. It deliberately does NOT implement the connection state machine or the credit-based flow control (buf_alloc / fwd_cnt accounting) — those belong a layer up, just as net drives frames, not TCP. The header's addressing and credit fields are surfaced on Packet so that upper layer can implement them.
- Modern transport (VIRTIO_F_VERSION_1 mandatory). Legacy devices are rejected by the common init sequence.
- Split-virtqueue layout; the packed ring is negotiated OUT.
- Three virtqueues: rx (0), tx (1), event (2) per Virtio 1.1 §5.10.2.
References:
- Virtio 1.1 §5.10 "Socket Device" — device-type 19 binding.
- Virtio 1.1 §5.10.2 "Virtqueues" — rx / tx / event.
- Virtio 1.1 §5.10.4 "Device configuration layout" — le64 guest_cid.
- Virtio 1.1 §5.10.6 "Device Operation" — struct virtio_vsock_hdr.
- Virtio 1.1 §3.1.1 "Device Initialization" — the status-bit choreography in OpenVirtioVsock.
Index ¶
Constants ¶
const ( RxQueueIdx uint16 = 0 TxQueueIdx uint16 = 1 EventQueueIdx uint16 = 2 )
Virtqueue indices (Virtio 1.1 §5.10.2).
const ( RxRingSize uint16 = 32 TxRingSize uint16 = 32 EventRingSize uint16 = 4 )
Desired ring sizes (clamped down to the device maximum, rounded to a power of two, during setup). The event queue is tiny — events are rare (only transport resets in this scope).
const ( TypeStream uint16 = 1 TypeSeqpacket uint16 = 2 )
Packet type values (Virtio 1.1 §5.10.6 — virtio_vsock_hdr.type).
const ( OpInvalid uint16 = 0 OpRequest uint16 = 1 OpResponse uint16 = 2 OpRst uint16 = 3 OpShutdown uint16 = 4 OpRW uint16 = 5 OpCreditUpdate uint16 = 6 OpCreditRequest uint16 = 7 )
Operation codes (Virtio 1.1 §5.10.6 — virtio_vsock_hdr.op).
const ( CIDHypervisor uint64 = 0 CIDHost uint64 = 2 CIDAny uint64 = 0xFFFFFFFF )
Well-known context IDs (Virtio 1.1 §5.10.4). VMADDR_CID_HOST = 2 is the peer CID a guest uses to reach the host.
const AcceptedFeatures uint64 = common.FeatureVersion1
AcceptedFeatures is the feature mask the driver negotiates ON. The packet-level driver needs no vsock-specific feature bit (stream is the baseline); the only bit we accept is the non-negotiable VIRTIO_F_VERSION_1.
const TxPollIterations = 200000
TxPollIterations is the default busy-poll budget for SendPacket while waiting for the device to return the transmitted descriptor.
const VsockHdrSize = 44
VsockHdrSize is the on-the-wire byte length of struct virtio_vsock_hdr (Virtio 1.1 §5.10.6.1), all fields little-endian:
0 le64 src_cid 8 le64 dst_cid 16 le32 src_port 20 le32 dst_port 24 le32 len (payload byte count following the header) 28 le16 type 30 le16 op 32 le32 flags 36 le32 buf_alloc 40 le32 fwd_cnt
Variables ¶
var ( ErrNotModernDevice = commonVsockError("go-virtio/vsock: device doesn't offer VIRTIO_F_VERSION_1 (legacy-only)") ErrFeaturesNotOK = commonVsockError("go-virtio/vsock: FEATURES_OK status bit didn't stick after DriverFeature write") ErrInitWrongDeviceID = commonVsockError("go-virtio/vsock: PCI device ID is not 0x1053 (modern vsock device)") ErrQueueNotAvailable = commonVsockError("go-virtio/vsock: device reports QueueSize=0 for a required queue") ErrTransmitTimeout = commonVsockError("go-virtio/vsock: TX poll timeout (device did not return descriptor)") ErrReceiveTimeout = commonVsockError("go-virtio/vsock: RX poll timeout (no packet received within budget)") ErrPacketTooLarge = commonVsockError("go-virtio/vsock: header + payload exceeds one page") ErrShortPacket = commonVsockError("go-virtio/vsock: received buffer shorter than virtio_vsock_hdr (44 bytes)") )
Sentinel errors for the virtio-vsock path.
Functions ¶
func AcceptFeatures ¶
AcceptFeatures returns the negotiated feature mask: the intersection of what the device offers and what we accept. Requires VIRTIO_F_VERSION_1 (else the device is legacy-only).
Types ¶
type Packet ¶
type Packet struct {
SrcCID, DstCID uint64
SrcPort, DstPort uint32
Type uint16
Op uint16
Flags uint32
BufAlloc uint32
FwdCnt uint32
Data []byte
}
Packet is one virtio-vsock packet: the header fields plus the payload. On SendPacket the `len` header field is derived from len(Data); on ReceivePacket Data is the payload the device delivered.
type VirtioVsock ¶
type VirtioVsock struct {
// Cfg is the modern-transport handle.
Cfg *common.ModernConfig
// GuestCID is the context ID the device assigned to this guest
// (Virtio 1.1 §5.10.4), read from DeviceCfg at OpenVirtioVsock.
GuestCID uint64
// NegotiatedFeatures records the driver-feature handshake result.
NegotiatedFeatures uint64
// contains filtered or unexported fields
}
VirtioVsock wraps one initialised virtio-vsock device.
func OpenVirtioVsock ¶
func OpenVirtioVsock(t common.Transport) (*VirtioVsock, error)
OpenVirtioVsock drives the full bring-up of one virtio-vsock device:
- Verify the PCI device ID is 0x1053 (modern vsock).
- 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 rx (0), tx (1), event (2) queues.
- DRIVER_OK status.
- Read guest_cid from DeviceCfg.
- Pre-post receive + event buffers and notify the device.
func (*VirtioVsock) EventQueue ¶
func (v *VirtioVsock) EventQueue() *common.Virtqueue
func (*VirtioVsock) ReceivePacket ¶
func (v *VirtioVsock) ReceivePacket(pollIterations int) (Packet, error)
ReceivePacket polls the rx queue for one packet, busy-spinning up to pollIterations cycles. On success it copies the payload out, reclaims and re-posts the descriptor (best-effort), and returns the parsed Packet. Returns ErrReceiveTimeout if no packet arrives in budget.
func (*VirtioVsock) RxQueue ¶
func (v *VirtioVsock) RxQueue() *common.Virtqueue
RxQueue / TxQueue / EventQueue expose the per-direction virtqueue handles for diagnostic inspection.
func (*VirtioVsock) SendPacket ¶
func (v *VirtioVsock) SendPacket(p Packet) error
SendPacket marshals p (header + payload) into a fresh DMA buffer, enqueues it on the tx queue, notifies the device, and busy-polls the used ring for completion. Returns ErrPacketTooLarge if the payload plus header exceeds one page, or ErrTransmitTimeout if the device does not return the descriptor within TxPollIterations.
func (*VirtioVsock) TxQueue ¶
func (v *VirtioVsock) TxQueue() *common.Virtqueue