History log of /device/linaro/bootloader/edk2/OvmfPkg/Library/VirtioLib/VirtioLib.c
Revision Date Author Comments (<<< Hide modified files) (Show modified files >>>)
ece77e4047c36ddd177949e81d548bda244ea8a7 11-Dec-2013 Olivier Martin <olivier.martin@arm.com> OvmfPkg/Virtio: Removed VirtioReadDevice() / VirtIoWriteDevice() functions

These functions did not provide much more than the new protocol functions
VIRTIO_DEVICE_PROTOCOL.ReadDevice() / VIRTIO_DEVICE_PROTOCOL.WriteDevice().

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Olivier Martin <olivier.martin@arm.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
Signed-off-by: Laszlo Ersek <lersek@redhat.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14968 6f19259b-4bc3-4df7-8a09-765794883524
/device/linaro/bootloader/edk2/OvmfPkg/Library/VirtioLib/VirtioLib.c
56f65ed838e8d73e91d54a8ed984d777c936843c 11-Dec-2013 Olivier Martin <olivier.martin@arm.com> OvmfPkg: Make the VirtIo devices use the new VIRTIO_DEVICE_PROTOCOL

This change replaces the accesses to the PCI bus from the Block, Scsi and Net drivers by
the use of the new VIRTIO_DEVICE_PROTOCOL protocol that abstracts the transport layer.
It means these drivers can be used on PCI and MMIO transport layer.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Olivier Martin <olivier.martin@arm.com>

v5:
- VirtioFlush(): update comment block in VirtioLib.[hc]; error code is
propagated from VirtIo->SetQueueNotify().
- VirtioBlkInit(): jump to Failed label if SetPageSize() fails
- VirtioBlkInit(): fixup comment, and add error handling, near
SetQueueNum() call
- VirtioBlkDriverBindingStart(): remove redundant (always false) check for
a subsystem device ID different from VIRTIO_SUBSYSTEM_BLOCK_DEVICE;
VirtioBlkDriverBindingSupported() handles it already
- VirtioNetGetFeatures(): update stale comment block
- VirtioNetGetFeatures(): retrieve MAC address byte for byte (open-coded
loop)
- VirtioNetDriverBindingStart(): remove redundant (always false) check for
a subsystem device ID different from VIRTIO_SUBSYSTEM_NETWORK_CARD;
VirtioNetDriverBindingSupported() handles it already
- VirtioNetInitRing(): call SetQueueNum() and SetQueueAlign() for proper
MMIO operation
- VirtioNetInitialize(): fix destination error label for when
SetPageSize() fails
- VirtioScsi.c: fix comment block of VIRTIO_CFG_WRITE()/VIRTIO_CFG_READ()
- VirtioScsiInit(): fix destination error label for when SetPageSize()
fails
- VirtioScsiInit(): call SetQueueNum() and SetQueueAlign() for proper MMIO
operation

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14966 6f19259b-4bc3-4df7-8a09-765794883524
/device/linaro/bootloader/edk2/OvmfPkg/Library/VirtioLib/VirtioLib.c
dc9447bd3777614529b711c9976979fe61822ba8 23-Aug-2013 Laszlo Ersek <lersek@redhat.com> OvmfPkg: Virtio: load used ring element strictly after loading used index

Enforce in-order execution of these steps even on not sequentially
consistent architectures, as discussed in [1]. These changes should be
unnecessary on x86 (the only architecture OVMF currently supports), but
they align the OVMF virtio code with the virtio specification and could be
necessary for future OVMF ports.

[1] http://lists.linuxfoundation.org/pipermail/virtualization/2013-June/024547.html

Suggested-by: Stefan Hajnoczi <stefanha@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14601 6f19259b-4bc3-4df7-8a09-765794883524
/device/linaro/bootloader/edk2/OvmfPkg/Library/VirtioLib/VirtioLib.c
a7615fa87528fad341a37880d36e95f16faca5d3 15-May-2013 jljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524> OvmfPkg: adapt VirtioFlush()'s leading comment to the coding style

Contributed-under: TianoCore Contribution Agreement 1.0

Signed-off-by: Laszlo Ersek <lersek@redhat.com>

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@14362 6f19259b-4bc3-4df7-8a09-765794883524
/device/linaro/bootloader/edk2/OvmfPkg/Library/VirtioLib/VirtioLib.c
11a5fdf43773b2418412f0800ab9770053bcef05 15-May-2013 jljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524> OvmfPkg: adapt VirtioAppendDesc()'s leading comment to the coding style

Contributed-under: TianoCore Contribution Agreement 1.0

Signed-off-by: Laszlo Ersek <lersek@redhat.com>

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@14361 6f19259b-4bc3-4df7-8a09-765794883524
/device/linaro/bootloader/edk2/OvmfPkg/Library/VirtioLib/VirtioLib.c
f2965f4e263274d27e2d9a1291a60785543f3e0c 15-May-2013 jljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524> OvmfPkg: adapt VirtioPrepare()'s leading comment to the coding style

Contributed-under: TianoCore Contribution Agreement 1.0

Signed-off-by: Laszlo Ersek <lersek@redhat.com>

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@14360 6f19259b-4bc3-4df7-8a09-765794883524
/device/linaro/bootloader/edk2/OvmfPkg/Library/VirtioLib/VirtioLib.c
635a3ca2a10b39cce7f067dfc16f909d9387612a 14-May-2013 jljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524> OvmfPkg: VirtioLib: populate the Available Ring correctly

The descriptor table (also known as "queue") consists of descriptors. (The
corresponding type in the code is VRING_DESC.)

An individual descriptor describes a contiguous buffer, to be transferred
uni-directionally between host and guest.

Several descriptors in the descriptor table can be linked into a
descriptor chain, specifying a bi-directional scatter-gather transfer
between host and guest. Such a descriptor chain is also known as "virtio
request".

(The descriptor table can host sereval descriptor chains (in-flight virtio
requests) in parallel, but the OVMF driver supports at most one chain, at
any point in time.)

The first descriptor in any descriptor chain is called "head descriptor".
In order to submit a number of parallel requests (= a set of independent
descriptor chains) from the guest to the host, the guest must put *only*
the head descriptor of each separate chain onto the Available Ring.

VirtioLib currently places the head of its one descriptor chain onto the
Available Ring repeatedly, once for each single (head *or* dependent)
descriptor in said descriptor chain. If the descriptor chain comprises N
descriptors, this error amounts to submitting the same entire chain N
times in parallel.

Available Ring Descriptor table
Ptr to head ----> Desc#0 (head of chain)
Ptr to head --/ Desc#1 (next in same chain)
... / ...
Ptr to head / Desc#(N-1) (last in same chain)

Anatomy of a single virtio-blk READ request (a descriptor chain with three
descriptors):

virtio-blk request header, prepared by guest:
VirtioAppendDesc PhysAddr=3FBC6050 Size=16 Flags=1 Head=1232 Next=1232

payload to be filled in by host:
VirtioAppendDesc PhysAddr=3B934C00 Size=32768 Flags=3 Head=1232 Next=1233

host status, to be filled in by host:
VirtioAppendDesc PhysAddr=3FBC604F Size=1 Flags=2 Head=1232 Next=1234

Processing on the host side -- the descriptor chain is processed three
times in parallel (its head is available to virtqueue_pop() thrice); the
same chain is submitted/collected separately to/from AIO three times:

virtio_queue_notify vdev VDEV vq VQ#0

virtqueue_pop vq VQ#0 elem EL#0 in_num 2 out_num 1
bdrv_aio_readv bs BDRV sector_num 585792 nb_sectors 64 opaque REQ#0

virtqueue_pop vq VQ#0 elem EL#1 in_num 2 out_num 1
bdrv_aio_readv bs BDRV sector_num 585792 nb_sectors 64 opaque REQ#1

virtqueue_pop vq VQ#0 elem EL#2 in_num 2 out_num 1
bdrv_aio_readv bs BDRV sector_num 585792 nb_sectors 64 opaque REQ#2

virtio_blk_rw_complete req REQ#0 ret 0
virtio_blk_req_complete req REQ#0 status 0

virtio_blk_rw_complete req REQ#1 ret 0
virtio_blk_req_complete req REQ#1 status 0

virtio_blk_rw_complete req REQ#2 ret 0
virtio_blk_req_complete req REQ#2 status 0

On my Thinkpad T510 laptop with RHEL-6 as host, this probably leads to
simultaneous DMA transfers targeting the same RAM area. Even though the
source of each transfer is identical, the data is corrupted in the
destination buffer -- the CRC32 calculated over the buffer varies, even
though the origin of the transfers is the same, never rewritten LBA.

SynchronousRequest Lba=585792 BufSiz=32768 ReqIsWrite=0 Crc32=BF68A44D

The problem is invisible on my HP Z400 workstation.

Fix the request submission by:
- building the only one descriptor chain supported by VirtioLib always at
the beginning of the descriptor table,
- ensuring the head descriptor of this chain is put on the Available Ring
only once,
- requesting the virtio spec's language to be cleaned up
<http://lists.linuxfoundation.org/pipermail/virtualization/2013-April/024032.html>.

Available Ring Descriptor table
Ptr to head ----> Desc#0 (head of chain)
Desc#1 (next in same chain)
...
Desc#(N-1) (last in same chain)

VirtioAppendDesc PhysAddr=3FBC6040 Size=16 Flags=1 Head=0 Next=0
VirtioAppendDesc PhysAddr=3B934C00 Size=32768 Flags=3 Head=0 Next=1
VirtioAppendDesc PhysAddr=3FBC603F Size=1 Flags=2 Head=0 Next=2

virtio_queue_notify vdev VDEV vq VQ#0

virtqueue_pop vq VQ#0 elem EL#0 in_num 2 out_num 1
bdrv_aio_readv bs BDRV sector_num 585792 nb_sectors 64 opaque REQ#0

virtio_blk_rw_complete req REQ#0 ret 0
virtio_blk_req_complete req REQ#0 status 0

SynchronousRequest Lba=585792 BufSiz=32768 ReqIsWrite=0 Crc32=1EEB2B07

(The Crc32 was double-checked with edk2's and Linux's guest IDE driver.)

Contributed-under: TianoCore Contribution Agreement 1.0

Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@14356 6f19259b-4bc3-4df7-8a09-765794883524
/device/linaro/bootloader/edk2/OvmfPkg/Library/VirtioLib/VirtioLib.c
9de0355b1ad7c8afaaf1dc0545438c9a6659d869 12-Oct-2012 jljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524> OvmfPkg: MSVC build fixes for VirtioLib and VirtioBlkDxe

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Mike Lee <leemiketw@gmail.com>
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13845 6f19259b-4bc3-4df7-8a09-765794883524
/device/linaro/bootloader/edk2/OvmfPkg/Library/VirtioLib/VirtioLib.c
e371e7e545b266ce4ae8ff76da6c98616214599f 12-Oct-2012 jljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524> OvmfPkg: librarize reusable bits from VirtioBlkDxe's SynchronousRequest()

new VirtioLib functions:
- VirtioPrepare(): prepare for appending descriptors
- VirtioFlush(): submit descriptor chain and await host answer

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13844 6f19259b-4bc3-4df7-8a09-765794883524
/device/linaro/bootloader/edk2/OvmfPkg/Library/VirtioLib/VirtioLib.c
7fcacd6c92616fd993a5befd93bcc9cad2610c90 12-Oct-2012 jljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524> OvmfPkg: rename AppendDesc to VirtioAppendDesc

AppendDesc() should have a prefix implying its containing library,
VirtioLib. Update its sole client VirtioBlkDxe.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13843 6f19259b-4bc3-4df7-8a09-765794883524
/device/linaro/bootloader/edk2/OvmfPkg/Library/VirtioLib/VirtioLib.c
263559b87232826552c9e42c1652d9f9488c9870 12-Oct-2012 jljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524> OvmfPkg: extract VirtioLib from VirtioBlkDxe

Introduce a new library called VirtioLib, for now only collecting the
following reusable functions with as little changes as possible:

- VirtioWrite()
- VirtioRead()
- VirtioRingInit()
- VirtioRingUninit()
- AppendDesc()

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13842 6f19259b-4bc3-4df7-8a09-765794883524
/device/linaro/bootloader/edk2/OvmfPkg/Library/VirtioLib/VirtioLib.c