Virtio: Difference between revisions

[unchecked revision][unchecked revision]
Content deleted Content added
m Formatting
m Bot: Replace deprecated source tag with syntaxhighlight
 
(13 intermediate revisions by 7 users not shown)
Line 3:
== Technical Details ==
 
VirtIO devices appear, to the guest VM, to be normal [[PCI]] devices with a specific VendorID and DeviceID. All VirtIO devices have a Vendor ID of 0x1AF4, and have a DeviceID between 0x1000 and 0x103F. The type of VirtIO device (Network Adapter, Block Device, etc.) can be determined by the Subsystem ID field in the [[PCI#Configuration_Space|PCI Configuration Space]] for the device. The currently defined types are:
 
{| {{wikitable}}
Line 60:
 
The Device Status field is used by the guest VM to communicate the current state of the guest VM driver. The flags in this register designate when the driver has found the device, when the driver has determined that the device is supported, and when the all of the necessary registers have been configured by the guest driver, and communication between the guest and host may begin.
 
{| {{wikitable}}
! Flags
! Description
|-
| 01 || Device Acknowledged
|-
| 02 || Driver Loaded
|-
| 04 || Driver Ready
|-
| 40 || Device Error
|-
| 80 || Driver Failed
|-
|}
 
== Device Specific Registers ==
Line 117 ⟶ 133:
=== Virtual Queue Descriptor ===
 
<sourcesyntaxhighlight lang="c">
 
struct VirtualQueue
Line 123 ⟶ 139:
struct Buffers[QueueSize]
{
longuint64_t Address; // 64-bit address of the buffer on the guest machine.
intuint32_t Length; // 32-bit length of the buffer.
shortuint16_t Flags; // 1: Next field contains linked buffer index.; 2: Buffer is write-only (clear for read-only). 4:Buffer contains additional buffer addresses.
// 4: Buffer contains additional buffer addresses.
shortuint16_t Next; // If flag is set, contains index of next buffer in chain.
}
struct Available
{
shortuint16_t Flags; // 1: Do not trigger interrupts.
shortuint16_t Index; // Index of the next ring index to be used. (Last available ring buffer index+1)
shortuint16_t [QueueSize] Ring; // List of available buffer indexes from the Buffers array above.
uint16_t EventIndex; // Only used if VIRTIO_F_EVENT_IDX was negotiated
short InterruptIndex; // If enabled, device will trigger interrupt after this ring index has been processed.
}
byteuint8_t[] Padding; // Reserved
// 4096 byte alignment
struct Used
{
shortuint16_t Flags; // 1: Do not notify device when buffers are added to available ring.
shortuint16_t Index; // Index of the next ring index to be used. (Last used ring buffer index+1)
struct Ring[QueueSize]
{
intuint32_t Index; // Index of the used buffer in the Buffers array above.
intuint32_t Length; // Total bytes written to buffer.
}
uint16_t AvailEvent; // Only used if VIRTIO_F_EVENT_IDX was negotiated
short InterruptIndex; // If enabled, device will trigger interrupt after this ring index has been used.
}
}
 
</syntaxhighlight>
</source>
 
== Communication ==
Line 164 ⟶ 183:
Each ethernet packet placed in a buffer must be immediately preceeded by a VirtIO Network Packet header.
 
<sourcesyntaxhighlight lang="c">
 
struct PacketHeader
{
byteuint8_t Flags; // 1Bit 0: Needs checksum; Bit 1: Received packet has valid data;
// Bit 2: If VIRTIO_NET_F_RSC_EXT was negotiated, the device processes
byte Segmentation; // 0:None 1:TCPv4 3:UDP 4:TCPv6 0x80:ECN
// duplicated ACK segments, reports number of coalesced TCP segments in ChecksumStart
short HeaderLength; // Size of header to be used during segmentation.
// field and number of duplicated ACK segments in ChecksumOffset field,
short SegmentLength; // Maximum segment size (not including header).
// and sets bit 2 in Flags(VIRTIO_NET_HDR_F_RSC_INFO)
short ChecksumStart; // The position to begin calculating the checksum.
byteuint8_t SegmentationSegmentationOffload; // 0:None 1:TCPv4 3:UDP 4:TCPv6 0x80:ECN
short ChecksumOffset; // The position after ChecksumStart to store the checksum.
shortuint16_t HeaderLength; // Size of header to be used during segmentation.
short BufferCount; // Used when merging buffers.
shortuint16_t SegmentLength; // Maximum segment size (not including header).
shortuint16_t ChecksumStart; // The position to begin calculating the checksum.
shortuint16_t ChecksumOffset; // The position after ChecksumStart to store the checksum.
shortuint16_t BufferCount; // Used when merging buffers.
}
 
</syntaxhighlight>
</source>
 
Note: Since the PacketHeader structure is Read-Only, and the incoming Network Packet is Write-Only (for incoming packets), you may need to separate these two areas into separate buffers, linked by the Next field.
Line 185 ⟶ 208:
Each block device request placed in a buffer must be filled with a VirtIO Block Request record.
 
<sourcesyntaxhighlight lang="c">
 
struct BlockRequest
{
intuint32_t Type; // 0: Read; 1: Write; 4: Flush; 11: Discard; 13: Write zeroes
uint32_t Reserved;
int Priority; // 0:Low
longuint64_t Sector;
uint8_t Data[]; // Data's size must be a multiple of 512
byte[255] Data;
byteuint8_t Status; // 0: OK; 1: Error; 2: Unsupported
}
 
</syntaxhighlight>
</source>
 
Note: Since the BlockRequest structure contains both read-only and write-only fields, it may be necessary to split this structure up into multiple buffers. The Type, Priority and Sector fields should be placed in a Read-Only buffer, and the Data and Status fields should be placed in a Write-Only buffer. The buffers will need to be linked together using the Next field. For Write requests, the buffer containing the Data field should be Read-Only, and the Status field buffer should be Write-Only, which would require 3 buffer entries.
 
== ReferencesSee Also ==
===External Links===
http* [https://docs.oasis-open.org/virtio/virtio/v1.01/virtio-v1.01.html - VirtIO specificationsspecification]
 
* [http://www.dumaisnet.ca/index.php?article=aca38a9a2b065b24dfa1dee728062a12 VirtIO Driver Example]
* [https://github.com/torokernel/torokernel/blob/7d6df4c40fa4cc85febd5fd5799404592ffdff53/rtl/drivers/VirtIONet.pas VirtIO Network Driver Example]
* [https://github.com/torokernel/torokernel/blob/7d6df4c40fa4cc85febd5fd5799404592ffdff53/rtl/drivers/VirtIOBlk.pas VirtIO Block Driver Example]
* [https://github.com/torokernel/torokernel/blob/master/rtl/drivers/VirtIOFS.pas VirtIO FS Driver Example]
* [https://github.com/torokernel/torokernel/blob/master/rtl/drivers/VirtIOVSocket.pas VirtIO VSocket Driver Example]
[[Category:Virtual]]
[[Category:Standards]]