OvmfPkg/Library/VirtioLib/VirtioLib.inf | 1 - OvmfPkg/Include/IndustryStandard/Virtio10.h | 4 +- OvmfPkg/Include/Library/VirtioLib.h | 132 +++++++++--- OvmfPkg/Include/Protocol/VirtioDevice.h | 162 +++++++++++++- OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.h | 39 +++- OvmfPkg/VirtioBlkDxe/VirtioBlk.h | 1 + OvmfPkg/VirtioNetDxe/VirtioNet.h | 25 ++- OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.h | 37 +++- OvmfPkg/VirtioRngDxe/VirtioRng.h | 1 + OvmfPkg/VirtioScsiDxe/VirtioScsi.h | 1 + OvmfPkg/Library/VirtioLib/VirtioLib.c | 204 +++++++++++++++--- OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.c | 8 +- OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceFunctions.c | 62 +++++- OvmfPkg/Virtio10Dxe/Virtio10.c | 128 ++++++++++- OvmfPkg/VirtioBlkDxe/VirtioBlk.c | 213 ++++++++++++++++--- OvmfPkg/VirtioGpuDxe/Commands.c | 13 +- OvmfPkg/VirtioNetDxe/Events.c | 19 ++ OvmfPkg/VirtioNetDxe/SnpGetStatus.c | 29 ++- OvmfPkg/VirtioNetDxe/SnpInitialize.c | 195 ++++++++++++++--- OvmfPkg/VirtioNetDxe/SnpSharedHelpers.c | 133 +++++++++++- OvmfPkg/VirtioNetDxe/SnpShutdown.c | 7 +- OvmfPkg/VirtioNetDxe/SnpTransmit.c | 30 ++- OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.c | 7 +- OvmfPkg/VirtioPciDeviceDxe/VirtioPciFunctions.c | 63 +++++- OvmfPkg/VirtioRngDxe/VirtioRng.c | 93 ++++++-- OvmfPkg/VirtioScsiDxe/VirtioScsi.c | 222 +++++++++++++++++--- 26 files changed, 1635 insertions(+), 194 deletions(-)
Currently, virtio drivers provides the system physical address to the device.
However, some systems may feature an IOMMU that requires the drivers to pass
the device addresses to the device - which are then translated by the IOMMU 
into physical addresses in memory. The patch series introduces new member
functions in VIRTIO_DEVICE_PROTOCOL which can be used for mapping a system
physical address to device address.
The approach that this patch series takes is to maps the system physical
address to device address for buffers (including rings, device specifc
request and response  pointed by vring descriptor, and any further memory 
reference by those request and response).
Patch 1 - 4:
 Defines and implements new member functions to map a system physical address
 to device address. The patch implements Laszlo's suggestion [1].
[1] http://mid.mail-archive.com/841bec5f-6f6e-8b1f-25ba-0fd37a915b72@redhat.com
Patch 5 - 12:
 Add some helper functions and allocate the vring using newly added member
 functions.
Patch 13:
 Update the virtio-rng driver to use newly added member functions to map the
 addresses.
 Verified using the following qemu cli
 # $QEMU \
    -device virtio-rng-pci
 # $QEMU \
    -device virtio-rng-pci,disable-legacy=on
 # $QEMU \
    -device virtio-rng-pci,disable-legacy=on,iommu_platform=true
 And succesfully ran RngTest.efi from SecurityPkg/Application and also
 verified that /dev/hwrng get created after Linux guest boot
Patch 14:
 Update the virtio-blk driver to use newly added member functions to map the
 addresses.
 Verified using the following qemu cli
 # $QEMU \
    -drive file=${IMAGE},if=none,id=disk0 \
    -device virtio-blk-pci,drive=disk0
 # $QEMU \
    -drive file=${IMAGE},if=none,id=disk0 \
    -device virtio-blk-pci,drive=disk0,disable-legacy=on
 # $QEMU \
    -drive file=${IMAGE},if=none,id=disk0 \
    -device virtio-blk-pci,drive=disk0,disable-legacy=on,iommu_platform=true
Patch 15:
 Update the virtio-scsi driver to use newly added member functions to map the
 addresses.
 Verified using the following qemu cli
 # $QEMU \
    -drive file=${IMAGE},if=none,id=disk0 \
    -device scsi-hd,drive=disk0 \
    -device virtio-scsi-pci,id=scsi 
 # $QEMU \
    -drive file=${IMAGE},if=none,id=disk0 \
    -device scsi-hd,drive=disk0 \
    -device virtio-scsi-pci,id=scsi,disable-legacy=on 
 # $QEMU \
    -drive file=${IMAGE},if=none,id=disk0 \
    -device scsi-hd,drive=disk0 \
    -device virtio-scsi-pci,id=scsi,disable-legacy=on,iommu_platform=true
Patch 16 - 19:
 Update the virtio-net driver to use newly added member functions to map the
 addresses.
 Verified using the following qemu cli
 # $QEMU \
    -netdev type=tap,id=net0 \
    -device virtio-net-pci,netdev=net0,romfile=
 # $QEMU \
    -netdev type=tap,id=net0 \
    -device virtio-net-pci,netdev=net0,disable-legacy=on,romfile=
 # $QEMU \
    -netdev type=tap,id=net0 \
    -device virtio-net-pci,netdev=net0,disable-legacy=on,iommu_platform=true,romfile=
Patch 20 - 23:
 Add support for VIRTIO_F_IOMMU_FEATURE bit
Repo: https://github.com/codomania/edk2
Branch: virtio-support-v3
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Laszlo Ersek <lersek@redhat.com>
TODO:
 * add VirtioGpuDxe (i will take Laszlo's offer that he can help with this driver)
 * I did minimal test on aarch64 - I was running into some Linux
   bootup issues with Fedora aarch64 iso. The issue does not appear to
   be releated to virtio changes. If anyone can help doing additional
   test with their aarch images that will be great ! thanks
Changes since v2:
 * changes to address v2 feedbacks
 * split the iommu_platform support into multiple patches
Changes since v1:
 * changes to address v1 feedbacks
 * add VIRTIO_F_IOMMU_PLATFORM feature bit
Brijesh Singh (23):
  OvmfPkg: introduce IOMMU-like member functions to
    VIRTIO_DEVICE_PROTOCOL
  OvmfPkg/Virtio10Dxe: implement IOMMU-like member functions
  OvmfPkg/VirtioPciDeviceDxe: implement IOMMU-like member functions
  OvmfPkg/VirtioMmioDeviceLib: implement IOMMU-like member functions
  OvmfPkg/VirtioLib: add VirtioMapAllBytesInSharedBuffer() helper
    function
  OvmfPkg/VirtioLib: take VirtIo instance in
    VirtioRingInit/VirtioRingUninit
  OvmfPkg/Virtio: take RingBaseShift in SetQueueAddress()
  OvmfPkg/Virtio10Dxe: add the RingBaseShift offset
  OvmfPkg/VirtioLib: add function to map VRING
  OvmfPkg/VirtioLib: alloc VRING buffer with AllocateSharedPages()
  OvmfPkg/VirtioLib: change the parameter of VirtioAppendDesc() to
    UINT64
  OvmfPkg/VirtioRngDxe: map host address to device address
  OvmfPkg/VirtioBlkDxe: map host address to device address
  OvmfPkg/VirtioScsiDxe: map host address to device address
  OvmfPkg/VirtioNetDxe: alloc Tx and Rx rings using AllocateSharedPage()
  OvmfPkg/VirtioNetDxe: alloc RxBuf using AllocateSharedPages()
  OvmfPkg/VirtioNetDxe: dynamically alloc transmit header
  OvmfPkg/VirtioNetDxe: map transmit buffer host address to device
    address
  OvmfPkg/Virtio10: define VIRITO_F_IOMMU_PLATFORM feature bit
  OvmfPkg/VirtioRngDxe: negotiate VIRITO_F_IOMMU_PLATFORM
  OvmfPkg/VirtioBlkDxe: negotiate VIRITO_F_IOMMU_PLATFORM
  OvmfPkg/VirtioScsiDxe: negotiate VIRITO_F_IOMMU_PLATFORM
  OvmfPkg/VirtioNetDxe: negotiate VIRITO_F_IOMMU_PLATFORM
 OvmfPkg/Library/VirtioLib/VirtioLib.inf                         |   1 -
 OvmfPkg/Include/IndustryStandard/Virtio10.h                     |   4 +-
 OvmfPkg/Include/Library/VirtioLib.h                             | 132 +++++++++---
 OvmfPkg/Include/Protocol/VirtioDevice.h                         | 162 +++++++++++++-
 OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.h          |  39 +++-
 OvmfPkg/VirtioBlkDxe/VirtioBlk.h                                |   1 +
 OvmfPkg/VirtioNetDxe/VirtioNet.h                                |  25 ++-
 OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.h                    |  37 +++-
 OvmfPkg/VirtioRngDxe/VirtioRng.h                                |   1 +
 OvmfPkg/VirtioScsiDxe/VirtioScsi.h                              |   1 +
 OvmfPkg/Library/VirtioLib/VirtioLib.c                           | 204 +++++++++++++++---
 OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.c          |   8 +-
 OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceFunctions.c |  62 +++++-
 OvmfPkg/Virtio10Dxe/Virtio10.c                                  | 128 ++++++++++-
 OvmfPkg/VirtioBlkDxe/VirtioBlk.c                                | 213 ++++++++++++++++---
 OvmfPkg/VirtioGpuDxe/Commands.c                                 |  13 +-
 OvmfPkg/VirtioNetDxe/Events.c                                   |  19 ++
 OvmfPkg/VirtioNetDxe/SnpGetStatus.c                             |  29 ++-
 OvmfPkg/VirtioNetDxe/SnpInitialize.c                            | 195 ++++++++++++++---
 OvmfPkg/VirtioNetDxe/SnpSharedHelpers.c                         | 133 +++++++++++-
 OvmfPkg/VirtioNetDxe/SnpShutdown.c                              |   7 +-
 OvmfPkg/VirtioNetDxe/SnpTransmit.c                              |  30 ++-
 OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.c                    |   7 +-
 OvmfPkg/VirtioPciDeviceDxe/VirtioPciFunctions.c                 |  63 +++++-
 OvmfPkg/VirtioRngDxe/VirtioRng.c                                |  93 ++++++--
 OvmfPkg/VirtioScsiDxe/VirtioScsi.c                              | 222 +++++++++++++++++---
 26 files changed, 1635 insertions(+), 194 deletions(-)
-- 
2.7.4
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
                
            Hi Brijesh, so here's what I'd like to do with v3: On 08/23/17 14:22, Brijesh Singh wrote: > Brijesh Singh (23): > OvmfPkg: introduce IOMMU-like member functions to > VIRTIO_DEVICE_PROTOCOL > OvmfPkg/Virtio10Dxe: implement IOMMU-like member functions > OvmfPkg/VirtioPciDeviceDxe: implement IOMMU-like member functions > OvmfPkg/VirtioMmioDeviceLib: implement IOMMU-like member functions > OvmfPkg/VirtioLib: add VirtioMapAllBytesInSharedBuffer() helper > function > OvmfPkg/VirtioLib: take VirtIo instance in > VirtioRingInit/VirtioRingUninit > OvmfPkg/Virtio: take RingBaseShift in SetQueueAddress() > OvmfPkg/Virtio10Dxe: add the RingBaseShift offset > OvmfPkg/VirtioLib: add function to map VRING > OvmfPkg/VirtioLib: alloc VRING buffer with AllocateSharedPages() > OvmfPkg/VirtioLib: change the parameter of VirtioAppendDesc() to > UINT64 (1) I'll take the first 11 patches (which work on the transports and VirtioLib), fix up the trivial stuff I've found in the v3 review, and add my R-b tags. > OvmfPkg/VirtioRngDxe: map host address to device address (2) I'll do the same for the VirtioRngDxe driver. (3) I'll test this initial sequence in various scenarios. I think that the protocol / transport / VirtioLib changes are good at this point, and the simplest driver (VirtioRngDxe) demonstrates how to put those new features to use. It also enables regression testing. Importantly, I also plan to regression-test the remaining (not yet converted) drivers at this point. Those drivers are affected only by the "alloc VRING buffer with AllocateSharedPages" patch, as follows: - On legacy virtio-pci and virtio-mmio transports, the change is a no-op, because the AllocateSharedPages() and FreeSharedPages() VirtIo members are backed by MemoryAllocationLib's AllocatePages() / FreePages(). So the behavior of VirtioRingInit() / VirtioRingUninit() remains identical. - On the virtio-1.0 transport, the direct AllocatePages() call in VirtioRingInit() will be replaced with VirtIo.AllocateSharedPages -> PciIo.AllocateBuffer -> PciRootBridgeIo.AllocateBuffer. - The last function will either branch to gBS->AllocatePages -- if there's no IoMmu protocol, i.e. no SEV -- which is identical to current behavior, or branch to IoMmu.AllocateBuffer. - in IoMmuAllocateBuffer(), we'll allocate StashBuffer on the side (which is no problem), and the actual allocation (for HostAddress) will be done with gBS->AllocatePages(). The end result is that at this point, the unconverted drivers won't yet work on SEV, but they will continue working if SEV is absent. The only difference is (dependent on transport) longer call chains to memory allocation and freeing, and larger memory footprint. But, no regressions in functionality. If I'm satisfied with the above test results, I'll add my Regression-tested-by tags as well, and push the first 12 patches. This will provide a foundation for further driver work (incl. my VirtioGpuDxe work). > OvmfPkg/VirtioBlkDxe: map host address to device address > OvmfPkg/VirtioScsiDxe: map host address to device address (4) I've looked at these patches briefly. They are possibly fine now, but they've grown way too big. I struggled with the verification of the VirtioRngDxe driver patch, and each of these two is more than twice as big. So please, split *each* of these two patches in two parts (a logical build-up): - the first part should map and unmap the vring (all relevant contexts), - the second part should map the requests. (5) (I think this is my most important point), with the foundation in place, I suggest we switch to one series per driver. For each driver, I have to look at the virtio spec, and "page-in" how the requests are structured, what they do etc. It's not a mechanical process. All that virtio stuff is easier to re-digest if we proceed device by device. Should we need later tweaks for the foundation, then at this point I prefer small incremental patches for that. > OvmfPkg/VirtioNetDxe: alloc Tx and Rx rings using AllocateSharedPage() > OvmfPkg/VirtioNetDxe: alloc RxBuf using AllocateSharedPages() > OvmfPkg/VirtioNetDxe: dynamically alloc transmit header > OvmfPkg/VirtioNetDxe: map transmit buffer host address to device > address (6) This is obviously the most complex driver. I've only snuck a peek. I have one comment at this point: *if* we have to do random lookups, then lists aren't optimal. Please consider using the following library class: MdePkg/Include/Library/OrderedCollectionLib.h It is already resolved in the OVMF DSC files to the following instance: MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/ Examples for use: - various modules in OvmfPkg, - AppPkg/Applications/OrderedCollectionTest > OvmfPkg/Virtio10: define VIRITO_F_IOMMU_PLATFORM feature bit > OvmfPkg/VirtioRngDxe: negotiate VIRITO_F_IOMMU_PLATFORM (7) I would have liked to include these two patches in my "initial push", but minimally the second patch needs fixes from you. After I'm done with point (3), please repost these patches *only*. > OvmfPkg/VirtioBlkDxe: negotiate VIRITO_F_IOMMU_PLATFORM > OvmfPkg/VirtioScsiDxe: negotiate VIRITO_F_IOMMU_PLATFORM > OvmfPkg/VirtioNetDxe: negotiate VIRITO_F_IOMMU_PLATFORM (8) After these patches are fixed up, I suggest that you please post each one of them at the end of the matching driver series. > TODO: > * add VirtioGpuDxe (i will take Laszlo's offer that he can help with > this driver) OK, will do, thank you! In this work I'll also seek to follow the series layout proposed above. > * I did minimal test on aarch64 - I was running into some Linux > bootup issues with Fedora aarch64 iso. The issue does not appear to > be releated to virtio changes. If anyone can help doing additional > test with their aarch images that will be great ! thanks I'll test on aarch64 too. Thanks! Laszlo _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel
Hi Laszlo, On 8/23/17 7:26 PM, Laszlo Ersek wrote: > Hi Brijesh, > > so here's what I'd like to do with v3: > > On 08/23/17 14:22, Brijesh Singh wrote: >> Brijesh Singh (23): >> OvmfPkg: introduce IOMMU-like member functions to >> VIRTIO_DEVICE_PROTOCOL >> OvmfPkg/Virtio10Dxe: implement IOMMU-like member functions >> OvmfPkg/VirtioPciDeviceDxe: implement IOMMU-like member functions >> OvmfPkg/VirtioMmioDeviceLib: implement IOMMU-like member functions >> OvmfPkg/VirtioLib: add VirtioMapAllBytesInSharedBuffer() helper >> function >> OvmfPkg/VirtioLib: take VirtIo instance in >> VirtioRingInit/VirtioRingUninit >> OvmfPkg/Virtio: take RingBaseShift in SetQueueAddress() >> OvmfPkg/Virtio10Dxe: add the RingBaseShift offset >> OvmfPkg/VirtioLib: add function to map VRING >> OvmfPkg/VirtioLib: alloc VRING buffer with AllocateSharedPages() >> OvmfPkg/VirtioLib: change the parameter of VirtioAppendDesc() to >> UINT64 > (1) I'll take the first 11 patches (which work on the transports and > VirtioLib), fix up the trivial stuff I've found in the v3 review, and > add my R-b tags. Thanks > >> OvmfPkg/VirtioRngDxe: map host address to device address > (2) I'll do the same for the VirtioRngDxe driver. > Thanks > (3) I'll test this initial sequence in various scenarios. I think that > the protocol / transport / VirtioLib changes are good at this point, and > the simplest driver (VirtioRngDxe) demonstrates how to put those new > features to use. It also enables regression testing. > > Importantly, I also plan to regression-test the remaining (not yet > converted) drivers at this point. Those drivers are affected only by the > "alloc VRING buffer with AllocateSharedPages" patch, as follows: > > - On legacy virtio-pci and virtio-mmio transports, the change is a > no-op, because the AllocateSharedPages() and FreeSharedPages() VirtIo > members are backed by MemoryAllocationLib's AllocatePages() / > FreePages(). So the behavior of VirtioRingInit() / VirtioRingUninit() > remains identical. > > - On the virtio-1.0 transport, the direct AllocatePages() call in > VirtioRingInit() will be replaced with VirtIo.AllocateSharedPages -> > PciIo.AllocateBuffer -> PciRootBridgeIo.AllocateBuffer. > > - The last function will either branch to gBS->AllocatePages -- if > there's no IoMmu protocol, i.e. no SEV -- which is identical to current > behavior, or branch to IoMmu.AllocateBuffer. > > - in IoMmuAllocateBuffer(), we'll allocate StashBuffer on the side > (which is no problem), and the actual allocation (for HostAddress) will > be done with gBS->AllocatePages(). > > The end result is that at this point, the unconverted drivers won't yet > work on SEV, but they will continue working if SEV is absent. The only > difference is (dependent on transport) longer call chains to memory > allocation and freeing, and larger memory footprint. But, no regressions > in functionality. > > If I'm satisfied with the above test results, I'll add my > Regression-tested-by tags as well, and push the first 12 patches. > > This will provide a foundation for further driver work (incl. my > VirtioGpuDxe work). I agree with you. Sounds like a good plan. > >> OvmfPkg/VirtioBlkDxe: map host address to device address >> OvmfPkg/VirtioScsiDxe: map host address to device address > (4) I've looked at these patches briefly. They are possibly fine now, > but they've grown way too big. I struggled with the verification of the > VirtioRngDxe driver patch, and each of these two is more than twice as big. Great thanks, I agree the series is getting bigger. After v1 feedbacks, I was almost tempted to say that lets work to enable the base first then will do one driver at a time. I was repeating the same mistake in each patch and that was causing trouble to you and also I had to rework the all drivers. > So please, split *each* of these two patches in two parts (a logical > build-up): > - the first part should map and unmap the vring (all relevant contexts), > - the second part should map the requests. > > > (5) (I think this is my most important point), with the foundation in > place, I suggest we switch to one series per driver. For each driver, I > have to look at the virtio spec, and "page-in" how the requests are > structured, what they do etc. It's not a mechanical process. All that > virtio stuff is easier to re-digest if we proceed device by device. > > Should we need later tweaks for the foundation, then at this point I > prefer small incremental patches for that. > > >> OvmfPkg/VirtioNetDxe: alloc Tx and Rx rings using AllocateSharedPage() >> OvmfPkg/VirtioNetDxe: alloc RxBuf using AllocateSharedPages() >> OvmfPkg/VirtioNetDxe: dynamically alloc transmit header >> OvmfPkg/VirtioNetDxe: map transmit buffer host address to device >> address > (6) This is obviously the most complex driver. I've only snuck a peek. I > have one comment at this point: *if* we have to do random lookups, then > lists aren't optimal. > > Please consider using the following library class: > > MdePkg/Include/Library/OrderedCollectionLib.h > > It is already resolved in the OVMF DSC files to the following instance: > > MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/ > > Examples for use: > - various modules in OvmfPkg, > - AppPkg/Applications/OrderedCollectionTest Okay, I will look into it - thanks for the tip. I wanted to actually use the Simple array (because we know the maximum number of buffer we can queue) but was not sure about your preferences hence I went to with list. If you are okay then I can use array's too. > >> OvmfPkg/Virtio10: define VIRITO_F_IOMMU_PLATFORM feature bit >> OvmfPkg/VirtioRngDxe: negotiate VIRITO_F_IOMMU_PLATFORM > (7) I would have liked to include these two patches in my "initial > push", but minimally the second patch needs fixes from you. > > After I'm done with point (3), please repost these patches *only*. Sure will do. thanks > >> OvmfPkg/VirtioBlkDxe: negotiate VIRITO_F_IOMMU_PLATFORM >> OvmfPkg/VirtioScsiDxe: negotiate VIRITO_F_IOMMU_PLATFORM >> OvmfPkg/VirtioNetDxe: negotiate VIRITO_F_IOMMU_PLATFORM > (8) After these patches are fixed up, I suggest that you please post > each one of them at the end of the matching driver series. > Will do. >> TODO: >> * add VirtioGpuDxe (i will take Laszlo's offer that he can help with >> this driver) > OK, will do, thank you! > > In this work I'll also seek to follow the series layout proposed above. > >> * I did minimal test on aarch64 - I was running into some Linux >> bootup issues with Fedora aarch64 iso. The issue does not appear to >> be releated to virtio changes. If anyone can help doing additional >> test with their aarch images that will be great ! thanks > I'll test on aarch64 too. thank you. -Brijesh _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel
On 08/24/17 02:54, Brijesh Singh wrote: > On 8/23/17 7:26 PM, Laszlo Ersek wrote: >> On 08/23/17 14:22, Brijesh Singh wrote: >>> OvmfPkg/VirtioBlkDxe: map host address to device address >>> OvmfPkg/VirtioScsiDxe: map host address to device address >> (4) I've looked at these patches briefly. They are possibly fine now, >> but they've grown way too big. I struggled with the verification of the >> VirtioRngDxe driver patch, and each of these two is more than twice as big. > Great thanks, I agree the series is getting bigger. After v1 feedbacks, > I was almost tempted to say that lets work to enable the base first then > will do one driver at a time. I was repeating the same mistake in each > patch and that was causing trouble to you and also I had to rework the > all drivers. Unfortunately (for both of us! :) ), this churn is unavoidable in the first few versions of a large set -- the foundation is not dictated by some "divine design", it is dictated only by what the higher level drivers need. And we only find out what the higher level drivers need if you at least prototype the patches for them, and I at least skim-review those patches. It's regrettable that it requires so much wasted work, but I don't know how to do it better, save for knowing the future. :) I trust at this point the base has stabilized enough, and if we need further changes, we can solve that with small incremental patches. >> (6) This is obviously the most complex driver. I've only snuck a peek. I >> have one comment at this point: *if* we have to do random lookups, then >> lists aren't optimal. >> >> Please consider using the following library class: >> >> MdePkg/Include/Library/OrderedCollectionLib.h >> >> It is already resolved in the OVMF DSC files to the following instance: >> >> MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/ >> >> Examples for use: >> - various modules in OvmfPkg, >> - AppPkg/Applications/OrderedCollectionTest > > Okay, I will look into it - thanks for the tip. I wanted to actually use > the Simple array (because we know the maximum number of buffer we can > queue) but was not sure about your preferences hence I went to with > list. If you are okay then I can use array's too. My concern isn't about memory consumption (if our queue is full (64 elements, IIRC), we just reject the transmit request and let the caller deal with the error). Instead, I'd like to avoid an O(n) lookup time (where n is the number of pending requests), for whatever lookup is necessary now (I haven't checked the specifics yet). BaseOrderedCollectionRedBlackTreeLib would give you O(log n) lookup time. Without having looked at the details, I think an array would have O(n) lookup time as well (linear search, right?). (Let's not try to do O(1) with a hash function -- that's quite out of scope for now, and with a hash table, one has to think about collisions too, etc. When I contributed BaseOrderedCollectionRedBlackTreeLib, I wanted it to become *the* go-to associative data structure for edk2 -- at least in such DXE and UEFI driver contexts where frequent pool allocations and releases are not a problem. Plus, RB trees double as fast priority queues, can be used for one-off sorting, have worst-case (not just on-average) O(log n) time guarantees... I think they're versatile.) Cheers Laszlo _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel
On 8/23/17 8:22 PM, Laszlo Ersek wrote:Okay, I will look into it - thanks for the tip. I wanted to actually use >> the Simple array (because we know the maximum number of buffer we can >> queue) but was not sure about your preferences hence I went to with >> list. If you are okay then I can use array's too. > My concern isn't about memory consumption (if our queue is full (64 > elements, IIRC), we just reject the transmit request and let the caller > deal with the error). > > Instead, I'd like to avoid an O(n) lookup time (where n is the number of > pending requests), for whatever lookup is necessary now (I haven't > checked the specifics yet). BaseOrderedCollectionRedBlackTreeLib would > give you O(log n) lookup time. > > Without having looked at the details, I think an array would have O(n) > lookup time as well (linear search, right?). > > (Let's not try to do O(1) with a hash function -- that's quite out of > scope for now, and with a hash table, one has to think about collisions > too, etc. When I contributed BaseOrderedCollectionRedBlackTreeLib, I > wanted it to become *the* go-to associative data structure for edk2 -- > at least in such DXE and UEFI driver contexts where frequent pool > allocations and releases are not a problem. Plus, RB trees double as > fast priority queues, can be used for one-off sorting, have worst-case > (not just on-average) O(log n) time guarantees... I think they're > versatile.) To my understanding the network packet enqueued in the transmit ring will be completed in same order, hence I was thinking about the queue data structure and was not concern about the search time. I was mostly concerned about the memory consumption but if my understanding is wrong then I agree that we need to pick right data structure. Since the RedBlack tree is already implemented hence I have no issue using it. thanks -Brijesh _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel
On 08/24/17 04:06, Brijesh Singh wrote: > > > On 8/23/17 8:22 PM, Laszlo Ersek wrote:Okay, I will look into it - > thanks for the tip. I wanted to actually use >>> the Simple array (because we know the maximum number of buffer we can >>> queue) but was not sure about your preferences hence I went to with >>> list. If you are okay then I can use array's too. >> My concern isn't about memory consumption (if our queue is full (64 >> elements, IIRC), we just reject the transmit request and let the caller >> deal with the error). >> >> Instead, I'd like to avoid an O(n) lookup time (where n is the number of >> pending requests), for whatever lookup is necessary now (I haven't >> checked the specifics yet). BaseOrderedCollectionRedBlackTreeLib would >> give you O(log n) lookup time. >> >> Without having looked at the details, I think an array would have O(n) >> lookup time as well (linear search, right?). >> >> (Let's not try to do O(1) with a hash function -- that's quite out of >> scope for now, and with a hash table, one has to think about collisions >> too, etc. When I contributed BaseOrderedCollectionRedBlackTreeLib, I >> wanted it to become *the* go-to associative data structure for edk2 -- >> at least in such DXE and UEFI driver contexts where frequent pool >> allocations and releases are not a problem. Plus, RB trees double as >> fast priority queues, can be used for one-off sorting, have worst-case >> (not just on-average) O(log n) time guarantees... I think they're >> versatile.) > > To my understanding the network packet enqueued in the transmit ring > will be completed in same order, The current code does not make this assumption -- please see the very last paragraph in "OvmfPkg/VirtioNetDxe/TechNotes.txt" --, and it would be good to keep it that way. > hence I was thinking about the queue > data structure and was not concern about the search time. I was mostly > concerned about the memory consumption but if my understanding is wrong > then I agree that we need to pick right data structure. Since the > RedBlack tree is already implemented hence I have no issue using it. thanks OK, thanks! Laszlo _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel
On 08/24/17 02:26, Laszlo Ersek wrote:
> Hi Brijesh,
>
> so here's what I'd like to do with v3:
>
> On 08/23/17 14:22, Brijesh Singh wrote:
>> Brijesh Singh (23):
>>   OvmfPkg: introduce IOMMU-like member functions to
>>     VIRTIO_DEVICE_PROTOCOL
>>   OvmfPkg/Virtio10Dxe: implement IOMMU-like member functions
>>   OvmfPkg/VirtioPciDeviceDxe: implement IOMMU-like member functions
>>   OvmfPkg/VirtioMmioDeviceLib: implement IOMMU-like member functions
>>   OvmfPkg/VirtioLib: add VirtioMapAllBytesInSharedBuffer() helper
>>     function
>>   OvmfPkg/VirtioLib: take VirtIo instance in
>>     VirtioRingInit/VirtioRingUninit
>>   OvmfPkg/Virtio: take RingBaseShift in SetQueueAddress()
>>   OvmfPkg/Virtio10Dxe: add the RingBaseShift offset
>>   OvmfPkg/VirtioLib: add function to map VRING
>>   OvmfPkg/VirtioLib: alloc VRING buffer with AllocateSharedPages()
>>   OvmfPkg/VirtioLib: change the parameter of VirtioAppendDesc() to
>>     UINT64
>
> (1) I'll take the first 11 patches (which work on the transports and
> VirtioLib), fix up the trivial stuff I've found in the v3 review, and
> add my R-b tags.
>
>
>>   OvmfPkg/VirtioRngDxe: map host address to device address
>
> (2) I'll do the same for the VirtioRngDxe driver.
>
>
> (3) I'll test this initial sequence in various scenarios. I think that
> the protocol / transport / VirtioLib changes are good at this point,
> and the simplest driver (VirtioRngDxe) demonstrates how to put those
> new features to use. It also enables regression testing.
>
> Importantly, I also plan to regression-test the remaining (not yet
> converted) drivers at this point. Those drivers are affected only by
> the "alloc VRING buffer with AllocateSharedPages" patch, as follows:
>
> - On legacy virtio-pci and virtio-mmio transports, the change is a
> no-op, because the AllocateSharedPages() and FreeSharedPages() VirtIo
> members are backed by MemoryAllocationLib's AllocatePages() /
> FreePages(). So the behavior of VirtioRingInit() / VirtioRingUninit()
> remains identical.
>
> - On the virtio-1.0 transport, the direct AllocatePages() call in
> VirtioRingInit() will be replaced with VirtIo.AllocateSharedPages ->
> PciIo.AllocateBuffer -> PciRootBridgeIo.AllocateBuffer.
>
> - The last function will either branch to gBS->AllocatePages -- if
> there's no IoMmu protocol, i.e. no SEV -- which is identical to
> current behavior, or branch to IoMmu.AllocateBuffer.
>
> - in IoMmuAllocateBuffer(), we'll allocate StashBuffer on the side
> (which is no problem), and the actual allocation (for HostAddress)
> will be done with gBS->AllocatePages().
>
> The end result is that at this point, the unconverted drivers won't
> yet work on SEV, but they will continue working if SEV is absent. The
> only difference is (dependent on transport) longer call chains to
> memory allocation and freeing, and larger memory footprint. But, no
> regressions in functionality.
>
> If I'm satisfied with the above test results, I'll add my
> Regression-tested-by tags as well, and push the first 12 patches.
For patches v3 1-12:
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
I've pushed those patches now; commit range c69071bd7e21..0a568ccbcbd1.
The testing took incredibly long. For AARCH64 testing, I used my Mustang
(KVM). For IA32 and X64, I used my laptop (also KVM). This was all
without SEV (hence "regression testing".) Here's the matrix and some
remarks:
                            virtio-mmio  legacy PCI        modern PCI
                            -----------  ----------------- --------------------------
  device  test scenario     AARCH64      IA32     X64      IA32     X64      AARCH64
  ------  ----------------  -----------  -------- -------- -------- -------- --------
  rng     shell RECONNECT   PASS         PASS     PASS     PASS     PASS     PASS
  rng     RngTest.efi       PASS         PASS     PASS     PASS     PASS     PASS
  rng     ExitBootServices  PASS         PASS     PASS     PASS     PASS     PASS
  blk     shell RECONNECT   PASS         PASS     PASS     PASS     PASS     PASS
  blk     shell LS/TYPE     PASS         PASS     PASS     PASS     PASS     PASS
  blk     ExitBootServices  PASS         PASS     PASS     PASS     PASS     PASS
  scsi    shell RECONNECT   PASS         PASS     PASS     PASS     PASS     PASS
  scsi    OS boot           PASS         PASS     PASS     PASS     PASS     PASS
  scsi    ExitBootServices  PASS         PASS     PASS     PASS     PASS     PASS
  net     shell RECONNECT   PASS         PASS     PASS     PASS     PASS     PASS
          (parent, child)
  net     DHCP +            PASS[06]     SKIP[08] SKIP[10] SKIP[08] SKIP[10] PASS[03]
          DataSink.efi
  net     DHCP +            PASS[05]     SKIP[07] PASS[11] SKIP[07] PASS[09] PASS[04]
          DataSource.efi
  net     DHCP + PXE boot   PASS         PASS     PASS     PASS     PASS     PASS
  net     ExitBootServices  PASS         PASS     PASS     PASS     PASS     PASS
  gpu     shell RECONNECT   N/A[01]      N/A[01]  N/A[01]  N/A[02]  N/A[02]  PASS
          (parent, child)
  gpu     shell MODE        N/A[01]      N/A[01]  N/A[01]  N/A[02]  N/A[02]  PASS
  gpu     ExitBootServices  N/A[01]      N/A[01]  N/A[01]  N/A[02]  N/A[02]  PASS
Remarks:
[01] virtio-gpu is modern-only
[02] Libvirt maps the "virtio" video model to "virtio-vga" on IA32/X64,
     which is bound by QemuVideoDxe, and to "virtio-gpu-pci" on AARCH64,
     which is bound by VirtioGpuDxe.
[03] transferred 200 MB, average speed 1.3-1.6 MB/s
[04] transferred 20 MB, average speed 280 KB/s
[05] transferred 20 MB, average speed 96 KB/s
[06] transferred 80 MB, average speed 374 KB/s
[07] 295 KB were transferred, but when DataSource.efi wanted to print
     the first stats line, it crashed with a divide error:
     !!!! IA32 Exception Type - 00(#DE - Divide Error)  CPU Apic ID - 00000000 !!!!
     EIP  - 7CD2077A, CS  - 00000010, EFLAGS - 00010246
     EAX  - 00000000, ECX - 00000000, EDX - 00000000, EBX - 00000000
     ESP  - 7EEBE2EC, EBP - 7EEBE328, ESI - 000004D2, EDI - 00000000
     DS   - 00000008, ES  - 00000008, FS  - 00000008, GS  - 00000008, SS - 00000008
     CR0  - 00000033, CR2 - 00000000, CR3 - 00000000, CR4 - 00000640
     DR0  - 00000000, DR1 - 00000000, DR2 - 00000000, DR3 - 00000000
     DR6  - FFFF0FF0, DR7 - 00000400
     GDTR - 7EE07A90 00000047, IDTR - 7DDB7010 000007FF
     LDTR - 00000000, TR - 00000000
     FXSAVE_STATE - 7EEBE030
     !!!! Find image
     Build/AppPkg/NOOPT_GCC48/IA32/AppPkg/Applications/Sockets/DataSource/DataSource/DEBUG/DataSource.dll
     (ImageBase=000000007CCF3000, EntryPoint=000000007CCF3220) !!!!
     0002d770 <InternalMathDivRemU64x32>:
        2d770:       8b 4c 24 0c             mov    0xc(%esp),%ecx
        2d774:       8b 44 24 08             mov    0x8(%esp),%eax
        2d778:       31 d2                   xor    %edx,%edx
     -> 2d77a:       f7 f1                   div    %ecx
        2d77c:       50                      push   %eax
        2d77d:       8b 44 24 08             mov    0x8(%esp),%eax
        2d781:       f7 f1                   div    %ecx
        2d783:       8b 4c 24 14             mov    0x14(%esp),%ecx
        2d787:       e3 02                   jecxz  2d78b <InternalMathDivRemU64x32.0>
        2d789:       89 11                   mov    %edx,(%ecx)
     The same symptom reproduces without applying Brijesh's patches.
[08] after the connection is established, DataSink.efi crashes
     !!!! IA32 Exception Type - 00(#DE - Divide Error)  CPU Apic ID - 00000000 !!!!
     EIP  - 7CD211CA, CS  - 00000010, EFLAGS - 00010246
     EAX  - 00000000, ECX - 00000000, EDX - 00000000, EBX - 00000000
     ESP  - 7EEBE23C, EBP - 7EEBE278, ESI - 00000002, EDI - 00000000
     DS   - 00000008, ES  - 00000008, FS  - 00000008, GS  - 00000008, SS - 00000008
     CR0  - 00000033, CR2 - 00000000, CR3 - 00000000, CR4 - 00000640
     DR0  - 00000000, DR1 - 00000000, DR2 - 00000000, DR3 - 00000000
     DR6  - FFFF0FF0, DR7 - 00000400
     GDTR - 7EE07A90 00000047, IDTR - 7DDB7010 000007FF
     LDTR - 00000000, TR - 00000000
     FXSAVE_STATE - 7EEBDF80
     !!!! Find image
     Build/AppPkg/NOOPT_GCC48/IA32/AppPkg/Applications/Sockets/DataSink/DataSink/DEBUG/DataSink.dll
     (ImageBase=000000007CCFA000, EntryPoint=000000007CCFA220) !!!!
     000271c0 <InternalMathDivRemU64x32>:
        271c0:       8b 4c 24 0c             mov    0xc(%esp),%ecx
        271c4:       8b 44 24 08             mov    0x8(%esp),%eax
        271c8:       31 d2                   xor    %edx,%edx
     -> 271ca:       f7 f1                   div    %ecx
        271cc:       50                      push   %eax
        271cd:       8b 44 24 08             mov    0x8(%esp),%eax
        271d1:       f7 f1                   div    %ecx
        271d3:       8b 4c 24 14             mov    0x14(%esp),%ecx
        271d7:       e3 02                   jecxz  271db <InternalMathDivRemU64x32.0>
        271d9:       89 11                   mov    %edx,(%ecx)
     The same symptom reproduces without applying Brijesh's patches.
[09] transferred 30MB, average speed 282 KB/s
[10] DataSink.efi hangs. The connection is established (according to
     "netstat"), but no data is transferred. The OVMF log contains
     repeated messages
     TcpInput: sequence acceptance test failed for segment of TCB 7CF52998
     Tcp4Input: Discard a packet
     The same symptom reproduces without applying Brijesh's patches.
[11] transferred 10.2MB, average speed 282 KB/s
The DataSource.efi and DataSink.efi applications seem quite brittle to
me, so I think in the future I might switch to different tools for
testing virtio-net with TCP. HTTP boot looks like a good candidate
<https://github.com/tianocore/tianocore.github.io/wiki/HTTP-Boot>;
perhaps I'll try it out.
Brijesh, can you please proceed with step (7) below?
Thank you,
Laszlo
>
> This will provide a foundation for further driver work (incl. my
> VirtioGpuDxe work).
>
>
>>   OvmfPkg/VirtioBlkDxe: map host address to device address
>>   OvmfPkg/VirtioScsiDxe: map host address to device address
>
> (4) I've looked at these patches briefly. They are possibly fine now,
> but they've grown way too big. I struggled with the verification of
> the VirtioRngDxe driver patch, and each of these two is more than
> twice as big.
>
> So please, split *each* of these two patches in two parts (a logical
> build-up):
> - the first part should map and unmap the vring (all relevant
>   contexts),
> - the second part should map the requests.
>
>
> (5) (I think this is my most important point), with the foundation in
> place, I suggest we switch to one series per driver. For each driver,
> I have to look at the virtio spec, and "page-in" how the requests are
> structured, what they do etc. It's not a mechanical process. All that
> virtio stuff is easier to re-digest if we proceed device by device.
>
> Should we need later tweaks for the foundation, then at this point I
> prefer small incremental patches for that.
>
>
>>   OvmfPkg/VirtioNetDxe: alloc Tx and Rx rings using AllocateSharedPage()
>>   OvmfPkg/VirtioNetDxe: alloc RxBuf using AllocateSharedPages()
>>   OvmfPkg/VirtioNetDxe: dynamically alloc transmit header
>>   OvmfPkg/VirtioNetDxe: map transmit buffer host address to device
>>     address
>
> (6) This is obviously the most complex driver. I've only snuck a peek.
> I have one comment at this point: *if* we have to do random lookups,
> then lists aren't optimal.
>
> Please consider using the following library class:
>
>   MdePkg/Include/Library/OrderedCollectionLib.h
>
> It is already resolved in the OVMF DSC files to the following
> instance:
>
>   MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/
>
> Examples for use:
> - various modules in OvmfPkg,
> - AppPkg/Applications/OrderedCollectionTest
>
>
>>   OvmfPkg/Virtio10: define VIRITO_F_IOMMU_PLATFORM feature bit
>>   OvmfPkg/VirtioRngDxe: negotiate VIRITO_F_IOMMU_PLATFORM
>
> (7) I would have liked to include these two patches in my "initial
> push", but minimally the second patch needs fixes from you.
>
> After I'm done with point (3), please repost these patches *only*.
>
>
>>   OvmfPkg/VirtioBlkDxe: negotiate VIRITO_F_IOMMU_PLATFORM
>>   OvmfPkg/VirtioScsiDxe: negotiate VIRITO_F_IOMMU_PLATFORM
>>   OvmfPkg/VirtioNetDxe: negotiate VIRITO_F_IOMMU_PLATFORM
>
> (8) After these patches are fixed up, I suggest that you please post
> each one of them at the end of the matching driver series.
>
>
>> TODO:
>>  * add VirtioGpuDxe (i will take Laszlo's offer that he can help with
>>    this driver)
>
> OK, will do, thank you!
>
> In this work I'll also seek to follow the series layout proposed
> above.
>
>>  * I did minimal test on aarch64 - I was running into some Linux
>>    bootup issues with Fedora aarch64 iso. The issue does not appear
>>    to be releated to virtio changes. If anyone can help doing
>>    additional test with their aarch images that will be great !
>>    thanks
>
> I'll test on aarch64 too.
>
> Thanks!
> Laszlo
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel
>
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
                
            © 2016 - 2025 Red Hat, Inc.