On 12/10/13 20:28, Jordan Justen wrote:
> Laszlo,
>
> In comparing Olivier's v4 to your v5, I had some questions.
>
> Mainly, it seems like maybe some 'fixes' are sneaking into the commit
> where we convert to using the protocol.

Those fixes are not "sneaking". I requested them explicitly in my v4
review. My method for preparing version 5 was:
- take Olivier's v4
- go through my review comments (and some of yours that I could find) on
  the list that have been posted for v4
- those comments pointed out problems in v4
- therefore I fixed those problems where they were introduced.

Normally when a respin is done, if v(n) of a patch introduces a problem,
then v(n+1) simply avoids introducing the problem. Followup patches are
justified when:
- v(n) has been committed, or
- fixing problems in-place (ie. where v(n) introduces those problems)
  would be very hard / inconvenient (for example because it requires
  intrusive rebase in the rest of the series).

None of this held for these changes.

I seem to recall that we discussed before the possibility of fixing
stuff that had emerged in v4 review in future patches. But that was only
mentioned because it's easier to do, not because it's better.

> It seems like we should keep
> those fixes separate, unless they are specifically necessary because
> of the change to using the protocol.
>
> I think the fixes themselves could be grouped into a single commit.

In this case I would prefer if the patches did the right thing
immediately, as soon as they are committed. The fixes I added belong to
the conversion.

> I'm just worried if the fixes change something then a bisect would
> point at the conversion to use protocol commit.

I have not touched device driver operation.

>
> Comparing v4 to v5:
>> diff --git a/ArmPlatformPkg/ArmVExpressPkg/ArmFvpDxe/ArmFvpDxe.c 
>> b/ArmPlatformPkg/ArmVExpressPkg/ArmFvpDxe/ArmFvpDxe.c
>> index 0cf5b7b..1885b69 100644
>> --- a/ArmPlatformPkg/ArmVExpressPkg/ArmFvpDxe/ArmFvpDxe.c
>> +++ b/ArmPlatformPkg/ArmVExpressPkg/ArmFvpDxe/ArmFvpDxe.c
>> @@ -19,10 +19,12 @@
>>
>>  #define ARM_FVP_BASE_VIRTIO_BLOCK_BASE    0x1c130000
>>
>> +#pragma pack(1)
>>  typedef struct {
>>    VENDOR_DEVICE_PATH                  Vendor;
>>    EFI_DEVICE_PATH_PROTOCOL            End;
>>  } VIRTIO_BLK_DEVICE_PATH;
>> +#pragma pack()
>>
>>  VIRTIO_BLK_DEVICE_PATH mVirtioBlockDevicePath =
>>  {
>> @@ -40,7 +42,7 @@ VIRTIO_BLK_DEVICE_PATH mVirtioBlockDevicePath =
>>    {
>>      END_DEVICE_PATH_TYPE,
>>      END_ENTIRE_DEVICE_PATH_SUBTYPE,
>> -        {
>> +    {
>>        sizeof (EFI_DEVICE_PATH_PROTOCOL),
>>        0
>>      }
>> diff --git a/OvmfPkg/Include/Library/VirtioLib.h 
>> b/OvmfPkg/Include/Library/VirtioLib.h
>> index df4fc62..36527a5 100644
>> --- a/OvmfPkg/Include/Library/VirtioLib.h
>> +++ b/OvmfPkg/Include/Library/VirtioLib.h
>> @@ -168,7 +168,7 @@ VirtioAppendDesc (
>>                            of the descriptor chain.
>>
>>
>> -  @return              Error code from VirtioWriteDevice() if it fails.
>> +  @return              Error code from VirtIo->SetQueueNotify() if it fails.
>>
>>    @retval EFI_SUCCESS  Otherwise, the host processed all descriptors.
>>
>> diff --git a/OvmfPkg/Include/Library/VirtioMmioDeviceLib.h 
>> b/OvmfPkg/Include/Library/VirtioMmioDeviceLib.h
>> index ac71014..3f63a65 100644
>> --- a/OvmfPkg/Include/Library/VirtioMmioDeviceLib.h
>> +++ b/OvmfPkg/Include/Library/VirtioMmioDeviceLib.h
>> @@ -23,12 +23,13 @@
>>
>>    @param[in] BaseAddress  Base Address of the VirtIo MMIO Device
>>
>> -  @param[in] Handle       Handle of the device the driver should be 
>> attached to.
>> +  @param[in] Handle       Handle of the device the driver should be attached
>> +                          to.
>>
>>    @retval EFI_SUCCESS           The VirtIo Device has been installed
>>                                  successfully.
>>
>> -  @retval EFI_OUT_OF_RESOURCES  The function failed too allocate memory 
>> require
>> +  @retval EFI_OUT_OF_RESOURCES  The function failed to allocate memory 
>> required
>>                                  by the Virtio MMIO device initialization.
>>
>>    @retval EFI_UNSUPPORTED       BaseAddress does not point to a VirtIo MMIO
>> diff --git a/OvmfPkg/Include/Protocol/VirtioDevice.h 
>> b/OvmfPkg/Include/Protocol/VirtioDevice.h
>> index 71541f8..48fca2e 100644
>> --- a/OvmfPkg/Include/Protocol/VirtioDevice.h
>> +++ b/OvmfPkg/Include/Protocol/VirtioDevice.h
>> @@ -1,6 +1,9 @@
>>  /** @file
>>    Virtio Device
>>
>> +  DISCLAIMER: the VIRTIO_DEVICE_PROTOCOL introduced here is a work in 
>> progress,
>> +  and should not be used outside of the EDK II tree.
>
> Note: I moved this above the copyright.

OK. I wasn't sure which one should have been more prominent, the
disclaimer or the copyright.


>
>>    Copyright (c) 2013, ARM Ltd. All rights reserved.<BR>
>>
>>    This program and the accompanying materials are licensed and made 
>> available
>> @@ -341,6 +344,9 @@ EFI_STATUS
>>  ///
>>  ///  This protocol provides an abstraction over the VirtIo transport layer
>>  ///
>> +///  DISCLAIMER: this protocol is a work in progress, and should not be used
>> +///  outside of the EDK II tree.
>> +///
>>  struct _VIRTIO_DEVICE_PROTOCOL {
>>    /// VirtIo Specification Revision encoded with VIRTIO_SPEC_REVISION()
>>    UINT32                      Revision;
>> diff --git a/OvmfPkg/Library/VirtioLib/VirtioLib.c 
>> b/OvmfPkg/Library/VirtioLib/VirtioLib.c
>> index 9bbd141..54cf225 100644
>> --- a/OvmfPkg/Library/VirtioLib/VirtioLib.c
>> +++ b/OvmfPkg/Library/VirtioLib/VirtioLib.c
>> @@ -250,7 +250,7 @@ VirtioAppendDesc (
>>                            of the descriptor chain.
>>
>>
>> -  @return              Error code from VirtioWriteDevice() if it fails.
>> +  @return              Error code from VirtIo->SetQueueNotify() if it fails.
>>
>>    @retval EFI_SUCCESS  Otherwise, the host processed all descriptors.
>>
>> diff --git a/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.c 
>> b/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.c
>> index 4d8578e..7543e15 100644
>> --- a/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.c
>> +++ b/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDevice.c
>> @@ -199,6 +199,7 @@ VirtioMmioUninstallDevice (
>>
>>    // Uninitialize the VirtIo Device
>>    VirtioMmioUninit (MmioDevice);
>> +  FreePool (MmioDevice);
>
> I think this is part of the conversion to having the new protocol, so
> it seems okay. (Ie, not a fix that should be separated out into it's
> own patch, right?)

Correct.

(But, again, that's the case for all the other fixes.)

>
>>    return EFI_SUCCESS;
>>  }
>> diff --git a/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceFunctions.c 
>> b/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceFunctions.c
>> index bcba062..068e1ed 100644
>> --- a/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceFunctions.c
>> +++ b/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceFunctions.c
>> @@ -48,7 +48,7 @@ VirtioMmioGetQueueAddress (
>>    VIRTIO_MMIO_DEVICE *Device;
>>
>>    if (QueueAddress == NULL) {
>> -
>> +    return EFI_INVALID_PARAMETER;
>>    }
>>
>>    Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);
>> @@ -109,7 +109,9 @@ VirtioMmioSetQueueSize (
>>
>>    Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);
>>
>> -  return VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_QUEUE_NUM, QueueSize);
>> +  VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_QUEUE_NUM, QueueSize);
>> +
>> +  return EFI_SUCCESS;
>>  }
>>
>>  EFI_STATUS
>> @@ -169,7 +171,9 @@ VirtioMmioSetPageSize (
>>  {
>>    VIRTIO_MMIO_DEVICE *Device;
>>
>> -  ASSERT (PageSize == EFI_PAGE_SIZE);
>> +  if (PageSize != EFI_PAGE_SIZE) {
>> +    return EFI_UNSUPPORTED;
>> +  }
>
> Maybe a separate change?

I don't think so. The MMIO implementation of the protocol is new; the
change you're quoting is between v4 and v5 (ie. it affects the
original-to-be commit). The protocol member is being introduced in:

  [edk2] [PATCH v5 3/8] OvmfPkg/VirtioMmioDeviceLib: Implement
                        VIRTIO_DEVICE_PROTOCOL for VirtIo Devices over
                        MMIO

and I listed the change in the v5 section there:

- VirtioMmioSetPageSize(): check against EFI_PAGE_SIZE with "if" plus
  EFI_UNSUPPORTED, rather than ASSERT()

I had pointed this out in my v4 review:
http://thread.gmane.org/gmane.comp.bios.tianocore.devel/4557/focus=4711

On 10/29/13 13:43, Laszlo Ersek wrote:
> On 10/16/13 19:29, Olivier Martin wrote:
>> +EFI_STATUS
>> +EFIAPI
>> +VirtioMmioSetPageSize (
>> +  VIRTIO_DEVICE_PROTOCOL *This,
>> +  UINT32                  PageSize
>> +  )
>> +{
>> +  VIRTIO_MMIO_DEVICE *Device;
>> +
>> +  ASSERT (PageSize == EFI_PAGE_SIZE);
>
> I would have preferred EFI_UNSUPPORTED in place of the assert, but I
> don't mind.

Going forward,

>
>>    Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);
>>
>> @@ -240,10 +244,6 @@ VirtioMmioDeviceWrite (
>>    Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This);
>>
>>    // Double-check fieldsize
>> -  if (FieldSize > 8) {
>> -    return EFI_INVALID_PARAMETER;
>> -  }
>
> Separate change?

Same status. I listed the change broken-out in the v5 3/8 posting:

- VirtioMmioDeviceWrite(), VirtioMmioDeviceRead(): remove redundant
  (FieldSize > 8) checks

And I had noticed it originally in the same v4 06/11 review as linked
above:

"This inequality is now redundant, given the below [...]".

>
>>    if ((FieldSize != 1) && (FieldSize != 2) &&
>>        (FieldSize != 4) && (FieldSize != 8)) {
>>      return EFI_INVALID_PARAMETER;
>> @@ -281,10 +281,6 @@ VirtioMmioDeviceRead (
>>    ASSERT (FieldSize == BufferSize);
>>
>>    // Double-check fieldsize
>> -  if (FieldSize > 8) {
>> -    return EFI_INVALID_PARAMETER;
>> -  }
>
> Separate change?

Same status (noticed in v4 06/11 review, fixed for v5), please see
above.

>
>>    if ((FieldSize != 1) && (FieldSize != 2) &&
>>        (FieldSize != 4) && (FieldSize != 8)) {
>>      return EFI_INVALID_PARAMETER;
>> diff --git a/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceLib.inf 
>> b/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceLib.inf
>> index 126afec..2e266a9 100644
>> --- a/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceLib.inf
>> +++ b/OvmfPkg/Library/VirtioMmioDeviceLib/VirtioMmioDeviceLib.inf
>> @@ -36,7 +36,6 @@
>>    IoLib
>>    MemoryAllocationLib
>>    UefiBootServicesTableLib
>> -  UefiDriverEntryPoint
>>    UefiLib
>>
>>  [Protocols]
>> diff --git a/OvmfPkg/VirtioBlkDxe/VirtioBlk.c 
>> b/OvmfPkg/VirtioBlkDxe/VirtioBlk.c
>> index 0dcb05c..e0be7b0 100644
>> --- a/OvmfPkg/VirtioBlkDxe/VirtioBlk.c
>> +++ b/OvmfPkg/VirtioBlkDxe/VirtioBlk.c
>> @@ -622,7 +622,7 @@ VirtioBlkInit (
>>    //
>>    Status = Dev->VirtIo->SetPageSize (Dev->VirtIo, EFI_PAGE_SIZE);
>>    if (EFI_ERROR (Status)) {
>> -    goto ReleaseQueue;
>> +    goto Failed;
>>    }
>>
>>    //
>> @@ -683,16 +683,21 @@ VirtioBlkInit (
>>    }
>>
>>    //
>> -  // Additional steps for MMIO: align the queue appropriately, and set the 
>> size
>> -  Dev->VirtIo->SetQueueNum (Dev->VirtIo, QueueSize);
>> +  // Additional steps for MMIO: align the queue appropriately, and set the
>> +  // size. If anything fails from here on, we must release the ring 
>> resources.
>> +  //
>> +  Status = Dev->VirtIo->SetQueueNum (Dev->VirtIo, QueueSize);
>> +  if (EFI_ERROR (Status)) {
>> +    goto ReleaseQueue;
>> +  }
>
> Separate change, or does the protocol alter the code flow making this
> necessary?

The v4 conversion of the virtio-blk driver to the new protocol had added
the necessary SetQueueNum() call, but it lacked correct error handling.
I pointed this out in my v4 review:

http://thread.gmane.org/gmane.comp.bios.tianocore.devel/4557/focus=4714

On 10/29/13 17:28, Laszlo Ersek wrote:
> On 10/16/13 19:29, Olivier Martin wrote:
>> @@ -700,22 +683,31 @@ VirtioBlkInit (
>>    }
>>
>>    //
>> +  // Additional steps for MMIO: align the queue appropriately, and set the 
>> size
>> +  Dev->VirtIo->SetQueueNum (Dev->VirtIo, QueueSize);
>
> (2) Please don't shirk from the error checking here! :)

Again, the change you're seeing is between v4 and v5. This is a new
function call that becomes necessary with the conversion, and v4 was
incomplete in this regard because it only added the call but not the
error checking.

>
>>    Status = Dev->VirtIo->SetQueueAlign (Dev->VirtIo, EFI_PAGE_SIZE);
>>    if (EFI_ERROR (Status)) {
>>      goto ReleaseQueue;
>>    }
>>
>>    //
>> -  // step 4c -- Report GPFN (guest-physical frame number) of queue. If 
>> anything
>> -  // fails from here on, we must release the ring resources.
>> +  // step 4c -- Report GPFN (guest-physical frame number) of queue.
>>    //
>>    Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo,
>>        (UINTN) Dev->Ring.Base >> EFI_PAGE_SHIFT);
>> @@ -841,10 +846,6 @@ VirtioBlkDriverBindingStart (
>>      goto FreeVirtioBlk;
>>    }
>>
>> -  if (Dev->VirtIo->SubSystemDeviceId != VIRTIO_SUBSYSTEM_BLOCK_DEVICE) {
>> -    return EFI_UNSUPPORTED;
>> -  }
>> -
>>    //
>>    // VirtIo access granted, configure virtio-blk device.
>>    //
>> diff --git a/OvmfPkg/VirtioNetDxe/DriverBinding.c 
>> b/OvmfPkg/VirtioNetDxe/DriverBinding.c
>> index 330f1f3..93995c6 100644
>> --- a/OvmfPkg/VirtioNetDxe/DriverBinding.c
>> +++ b/OvmfPkg/VirtioNetDxe/DriverBinding.c
>> @@ -49,8 +49,7 @@
>>                                      unused.
>>
>>    @retval EFI_UNSUPPORTED           The host doesn't supply a MAC address.
>> -  @return                           Status codes from 
>> Dev->VirtIo->Io.Read(),
>> -                                    VIRTIO_CFG_READ() and 
>> VIRTIO_CFG_WRITE().
>> +  @return                           Status codes from VirtIo protocol 
>> members.
>>    @retval EFI_SUCCESS               Configuration values retrieved.
>>  */
>>  STATIC
>> @@ -66,6 +65,7 @@ VirtioNetGetFeatures (
>>    EFI_STATUS Status;
>>    UINT8      NextDevStat;
>>    UINT32     Features;
>> +  UINTN      MacIdx;
>>    UINT16     LinkStatus;
>>
>>    //
>> @@ -105,15 +105,16 @@ VirtioNetGetFeatures (
>>      Status = EFI_UNSUPPORTED;
>>      goto YieldDevice;
>>    }
>> -  Status = Dev->VirtIo->ReadDevice (Dev->VirtIo,
>> -                                    OFFSET_OF_VNET (Mac), // Offset
>> -                                    sizeof(UINT8),        // FieldSize
>> -                                    SIZE_OF_VNET (Mac),   // BufferSize
>> -                                    MacAddress            // Buffer
>> -                                    );
>> -
>> -  if (EFI_ERROR (Status)) {
>> -    goto YieldDevice;
>> +  for (MacIdx = 0; MacIdx < SIZE_OF_VNET (Mac); ++MacIdx) {
>> +    Status = Dev->VirtIo->ReadDevice (Dev->VirtIo,
>> +                            OFFSET_OF_VNET (Mac) + MacIdx, // Offset
>> +                            1,                             // FieldSize
>> +                            1,                             // BufferSize
>> +                            &MacAddress->Addr[MacIdx]      // Buffer
>> +                            );
>> +    if (EFI_ERROR (Status)) {
>> +      goto YieldDevice;
>> +    }
>
> Separate change? Is this related to moving to using the protocol?

This is not a separate change either.

I reviewed v4 07/11 in two rounds. In the second round I commented:

http://thread.gmane.org/gmane.comp.bios.tianocore.devel/4557/focus=4721

On 10/30/13 14:21, Laszlo Ersek wrote:
> On 10/16/13 19:29, Olivier Martin wrote:

>> @@ -106,13 +105,12 @@ VirtioNetGetFeatures (
>>      Status = EFI_UNSUPPORTED;
>>      goto YieldDevice;
>>    }
>> -  Status = Dev->PciIo->Io.Read (Dev->PciIo,           // PciIo
>> -                            EfiPciIoWidthUint8,       // Width
>> -                            PCI_BAR_IDX0,             // BarIndex
>> -                            OFFSET_OF_VNET (VhdrMac), // Offset
>> -                            SIZE_OF_VNET (VhdrMac),   // Count
>> -                            MacAddress                // Buffer
>> -                            );
>> +  Status = Dev->VirtIo->ReadDevice (Dev->VirtIo,
>> +                                    OFFSET_OF_VNET (Mac), // Offset
>> +                                    sizeof(UINT8),        // FieldSize
>> +                                    SIZE_OF_VNET (Mac),   // BufferSize
>> +                                    MacAddress            // Buffer
>> +                                    );
>
> (4) OK, so I guess this is the incentive for the "looping" (new in v4)
> in VirtioPciIoRead(). However, this call will trigger the ASSERT() in
> VirtioMmioDeviceRead().
>
> I think I would like an open-coded loop here :), but we seem to disagree
> on that. I don't insist though; the PCI variant will work and the
> failure on MMIO will be prominent.

The v4 patchset converted the reading of the MAC address from PciIo to
VirtIo. However, the conversion is invalid for the virtio-mmio backend,
because it tries to read 6 bytes at once.

The virtio-pci backend had satisfied this request in v4, due to a
looping kludge added there to the virtio-pci backend. But, since I fixed
this call site in v5 in order to work with the virtio-mmio backend,
there was no longer any need for the kludge in the PCI backend. So I
removed the looping from the PCI backend as well.

>
>>    }
>>
>>    //
>> @@ -459,10 +460,6 @@ VirtioNetDriverBindingStart (
>>      goto FreeVirtioNet;
>>    }
>>
>> -  if (Dev->VirtIo->SubSystemDeviceId != VIRTIO_SUBSYSTEM_NETWORK_CARD) {
>> -    return EFI_UNSUPPORTED;
>> -  }
>> -
>>    //
>>    // now we can run a basic one-shot virtio-net initialization required to
>>    // retrieve the MAC address
>> diff --git a/OvmfPkg/VirtioNetDxe/SnpInitialize.c 
>> b/OvmfPkg/VirtioNetDxe/SnpInitialize.c
>> index 56a55db..8dcf9da 100644
>> --- a/OvmfPkg/VirtioNetDxe/SnpInitialize.c
>> +++ b/OvmfPkg/VirtioNetDxe/SnpInitialize.c
>> @@ -79,13 +79,33 @@ VirtioNetInitRing (
>>    }
>>
>>    //
>> +  // Additional steps for MMIO: align the queue appropriately, and set the
>> +  // size. If anything fails from here on, we must release the ring 
>> resources.
>> +  //
>> +  Status = Dev->VirtIo->SetQueueNum (Dev->VirtIo, QueueSize);
>> +  if (EFI_ERROR (Status)) {
>> +    goto ReleaseQueue;
>> +  }
>> +
>> +  Status = Dev->VirtIo->SetQueueAlign (Dev->VirtIo, EFI_PAGE_SIZE);
>> +  if (EFI_ERROR (Status)) {
>> +    goto ReleaseQueue;
>> +  }
>
> Separate change, or does the protocol alter the code flow making this 
> necessary?

The latter.

The conversion of VirtioNetDxe to the new protocol had been incomplete
in v4. I observed this too in the second round of my v4 07/11 review:

http://thread.gmane.org/gmane.comp.bios.tianocore.devel/4557/focus=4721

On 10/30/13 14:21, Laszlo Ersek wrote:
> On 10/16/13 19:29, Olivier Martin wrote:

>> @@ -80,8 +81,8 @@ VirtioNetInitRing (
>>    //
>>    // step 4c -- report GPFN (guest-physical frame number) of queue
>>    //
>> -  Status = VIRTIO_CFG_WRITE (Dev, Generic.VhdrQueueAddress,
>> -             (UINTN) Ring->Base >> EFI_PAGE_SHIFT);
>> +  Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo,
>> +      (UINTN) Ring->Base >> EFI_PAGE_SHIFT);
>>    if (EFI_ERROR (Status)) {
>>      VirtioRingUninit (Ring);
>>    }
>
> (6) The conversion of this function is incomplete (for MMIO).
>
> The "Additional steps for MMIO", that is, the SetQueueNum() and
> SetQueueAlign() calls -- including my notes under (2), ie. error
> checking -- are necessary here, between VirtioRingInit() and
> SetQueueAddress().
>
> You'll have to extract the VirtioRingUninit() "rollback" call under an
> error handling label, and jump to it if any of SetQueueNum(),
> SetQueueAlign(), SetQueueAddress() fail.

I just added in v5 what had been missing from v4. My v5 4/8 posting
says:

- VirtioNetInitRing(): call SetQueueNum() and SetQueueAlign() for proper
  MMIO operation

>
>> +  //
>>    // step 4c -- report GPFN (guest-physical frame number) of queue
>>    //
>>    Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo,
>>        (UINTN) Ring->Base >> EFI_PAGE_SHIFT);
>>    if (EFI_ERROR (Status)) {
>> -    VirtioRingUninit (Ring);
>> +    goto ReleaseQueue;
>>    }
>> +
>> +  return EFI_SUCCESS;
>> +
>> +ReleaseQueue:
>> +  VirtioRingUninit (Ring);
>> +
>>    return Status;
>>  }
>>
>> @@ -382,7 +402,7 @@ VirtioNetInitialize (
>>    //
>>    Status = Dev->VirtIo->SetPageSize (Dev->VirtIo, EFI_PAGE_SIZE);
>>    if (EFI_ERROR (Status)) {
>> -    goto ReleaseTxRing;
>> +    goto DeviceFailed;
>>    }
>>
>>    //
>> diff --git a/OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.c 
>> b/OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.c
>> index c513622..c03a273 100644
>> --- a/OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.c
>> +++ b/OvmfPkg/VirtioPciDeviceDxe/VirtioPciDevice.c
>> @@ -80,11 +80,10 @@ VirtioPciIoRead (
>>    EFI_PCI_IO_PROTOCOL_WIDTH Width;
>>    EFI_PCI_IO_PROTOCOL       *PciIo;
>>
>> -  // The BufferSize must be a multiple of FieldSize
>> -  ASSERT ((BufferSize % FieldSize) == 0);
>> +  ASSERT (FieldSize == BufferSize);
>>
>>    PciIo = Dev->PciIo;
>> -  Count = BufferSize / FieldSize;
>> +  Count = 1;
>
> Separate change, or does the protocol alter the code flow making this
> necessary?

The latter. (I've touched on this above.)

This looping behavior (that didn't match the leading comment block) had
been introduced in v4, solely in order to accommodat the one-call
reading of the virtio-net MAC address. Since that reading had been
invalid for MMIO, and I fixed it for v5 anyway, I removed the looping
here as well. In any case, I remarked this in my v4 review explicitly
for the hunk in question:

http://thread.gmane.org/gmane.comp.bios.tianocore.devel/4557/focus=4687

On 10/28/13 16:45, Laszlo Ersek wrote:
> On 10/16/13 19:29, Olivier Martin wrote:
>> +/**
>> +
>> +  Read a word from Region 0 of the device specified by PciIo.
>> +
>> +  Region 0 must be an iomem region. This is an internal function for the PCI
>> +  implementation of the protocol.
>> +
>> +  @param[in] Dev          Virtio PCI device.
>> +
>> +  @param[in] FieldOffset  Source offset.
>> +
>> +  @param[in] FieldSize    Source field size, must be in { 1, 2, 4, 8 }.
>> +
>> +  @param[in] BufferSize   Number of bytes available in the target buffer. 
>> Must
>> +                          equal FieldSize.
>> +
>> +  @param[out] Buffer      Target buffer.
>> +
>> +
>> +  @return  Status code returned by PciIo->Io.Read().
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +VirtioPciIoRead (
>> +  IN  VIRTIO_PCI_DEVICE         *Dev,
>> +  IN  UINTN                     FieldOffset,
>> +  IN  UINTN                     FieldSize,
>> +  IN  UINTN                     BufferSize,
>> +  OUT VOID                      *Buffer
>> +  )
>> +{
>> +  UINTN                     Count;
>> +  EFI_PCI_IO_PROTOCOL_WIDTH Width;
>> +  EFI_PCI_IO_PROTOCOL       *PciIo;
>> +
>> +  // The BufferSize must be a multiple of FieldSize
>> +  ASSERT ((BufferSize % FieldSize) == 0);
>
> Not sure what motivated this change (and the corresponding Count
> doubling below). It doesn't match the comment on BufferSize.
>
> But, I don't mind.

As I described above, later on I did figure out why this was necessary
(for the VirtioNetDxe MAC-reading). Since the latter was wrong anyway
and I fixed it, this change in v4 lost its raison d'etre as well. My v5
2/8 posting says:

- VirtioPciIoRead(): restore the original requirement that FieldSize equal
  BufferSize exactly (not only divide it). The looping added in v4 did not
  match the comment block, and the only place that used it in v4 (ie.
  VirtioNetGetFeatures()) needs an open-coded loop anyway (will be done in
  a later part of v5).

(And it was.)

>
>>    switch (FieldSize) {
>>      case 1:
>> @@ -96,6 +95,7 @@ VirtioPciIoRead (
>>        break;
>>
>>      case 8:
>> +      //
>>        // The 64bit PCI I/O is broken down into two 32bit reads to prevent
>>        // any alignment or width issues.
>>        // The UEFI spec says under EFI_PCI_IO_PROTOCOL.Io.Write():
>> @@ -103,8 +103,9 @@ VirtioPciIoRead (
>>        // The I/O operations are carried out exactly as requested. The caller
>>        // is responsible for any alignment and I/O width issues which the
>>        // bus, device, platform, or type of I/O might require. For example on
>> -      // some platforms, width requests of EfiPciIoWidthUint64 do not work
>> -      Count = Count * 2;
>> +      // some platforms, width requests of EfiPciIoWidthUint64 do not work.
>> +      //
>> +      Count = 2;
>>        // fall through
>>
>>      case 4:
>> diff --git a/OvmfPkg/VirtioPciDeviceDxe/VirtioPciFunctions.c 
>> b/OvmfPkg/VirtioPciDeviceDxe/VirtioPciFunctions.c
>> index 586bec6..9c40fd9 100644
>> --- a/OvmfPkg/VirtioPciDeviceDxe/VirtioPciFunctions.c
>> +++ b/OvmfPkg/VirtioPciDeviceDxe/VirtioPciFunctions.c
>> @@ -24,12 +24,12 @@
>>
>>  /**
>>
>> -  Read a word from Region 0 of the device specified by PciIo.
>> +  Read a word from Region 0 of the device specified by VirtIo Device 
>> protocol.
>>
>>    The function implements the ReadDevice protocol member of
>>    VIRTIO_DEVICE_PROTOCOL.
>>
>> -  @param[in] PciIo        Source PCI device.
>> +  @param[in] This         VirtIo Device protocol.
>>
>>    @param[in] FieldOffset  Source offset.
>>
>> @@ -235,9 +235,7 @@ VirtioPciSetPageSize (
>>    UINT32                  PageSize
>>    )
>>  {
>> -  ASSERT (PageSize == EFI_PAGE_SIZE);
>> -
>> -  return EFI_SUCCESS;
>> +  return (PageSize == EFI_PAGE_SIZE) ? EFI_SUCCESS : EFI_UNSUPPORTED;
>
> Separate change?

No, it isn't.

This even dates back to my v3 review. I mentioned it again in my v4
review:

http://thread.gmane.org/gmane.comp.bios.tianocore.devel/4557/focus=4687

On 10/28/13 16:45, Laszlo Ersek wrote:
> On 10/16/13 19:29, Olivier Martin wrote:
>> +EFI_STATUS
>> +EFIAPI
>> +VirtioPciSetPageSize (
>> +  VIRTIO_DEVICE_PROTOCOL *This,
>> +  UINT32                  PageSize
>> +  )
>> +{
>> +  ASSERT (PageSize == EFI_PAGE_SIZE);
>> +
>> +  return EFI_SUCCESS;
>> +}
>
> In
> <http://thread.gmane.org/gmane.comp.bios.tianocore.devel/4373/focus=4409> I
> suggested
>
>     backend      take page size  return EFI_UNSUPPORTED  configure
>                  parameter       if the value is not     host side
>                                  EFI_PAGE_SIZE
>     -----------  --------------  ----------------------  ---------
>     virtio-pci   yes             yes                     no
>     virtio-mmio  yes             yes                     yes
>
> but I don't mind the ASSERT() in place of EFI_UNSUPPORTED.

And my v5 2/8 changelog says:

- return EFI_UNSUPPORTED instead of failed ASSERT() in
  VirtioPciSetPageSize()

>
>>  }
>>
>>  EFI_STATUS
>> diff --git a/OvmfPkg/VirtioScsiDxe/VirtioScsi.c 
>> b/OvmfPkg/VirtioScsiDxe/VirtioScsi.c
>> index 9702985..267f5f9 100644
>> --- a/OvmfPkg/VirtioScsiDxe/VirtioScsi.c
>> +++ b/OvmfPkg/VirtioScsiDxe/VirtioScsi.c
>> @@ -50,14 +50,14 @@
>>
>>  /**
>>
>> -  Convenience macros to read and write region 0 IO space elements of the
>> -  virtio-scsi VirtIo device, for configuration purposes.
>> +  Convenience macros to read and write configuration elements of the
>> +  virtio-scsi VirtIo device.
>>
>>    The following macros make it possible to specify only the "core 
>> parameters"
>>    for such accesses and to derive the rest. By the time VIRTIO_CFG_WRITE()
>>    returns, the transaction will have been completed.
>>
>> -  @param[in] Dev       Pointer to the VirtIo Device Protocol
>> +  @param[in] Dev       Pointer to the VSCSI_DEV structure.
>>
>>    @param[in] Field     A field name from VSCSI_HDR, identifying the 
>> virtio-scsi
>>                         configuration item to access.
>> @@ -738,7 +738,7 @@ VirtioScsiInit (
>>    //
>>    Status = Dev->VirtIo->SetPageSize (Dev->VirtIo, EFI_PAGE_SIZE);
>>    if (EFI_ERROR (Status)) {
>> -    goto ReleaseQueue;
>> +    goto Failed;
>>    }
>>
>>    //
>> @@ -825,8 +825,21 @@ VirtioScsiInit (
>>    }
>>
>>    //
>> -  // step 4c -- Report GPFN (guest-physical frame number) of queue. If 
>> anything
>> -  // fails from here on, we must release the ring resources.
>> +  // Additional steps for MMIO: align the queue appropriately, and set the
>> +  // size. If anything fails from here on, we must release the ring 
>> resources.
>> +  //
>> +  Status = Dev->VirtIo->SetQueueNum (Dev->VirtIo, QueueSize);
>> +  if (EFI_ERROR (Status)) {
>> +    goto ReleaseQueue;
>> +  }
>> +
>> +  Status = Dev->VirtIo->SetQueueAlign (Dev->VirtIo, EFI_PAGE_SIZE);
>> +  if (EFI_ERROR (Status)) {
>> +    goto ReleaseQueue;
>> +  }
>> +
>> +  //
>> +  // step 4c -- Report GPFN (guest-physical frame number) of queue.
>
> Separate change?

No; please see my v4 07/11 review (round #2):

http://thread.gmane.org/gmane.comp.bios.tianocore.devel/4557/focus=4721

On 10/30/13 14:21, Laszlo Ersek wrote:
> On 10/16/13 19:29, Olivier Martin wrote:

>> @@ -823,8 +828,8 @@ VirtioScsiInit (
>>    // step 4c -- Report GPFN (guest-physical frame number) of queue. If 
>> anything
>>    // fails from here on, we must release the ring resources.
>>    //
>> -  Status = VIRTIO_CFG_WRITE (Dev, Generic.VhdrQueueAddress,
>> -             (UINTN) Dev->Ring.Base >> EFI_PAGE_SHIFT);
>> +  Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo,
>> +      (UINTN) Dev->Ring.Base >> EFI_PAGE_SHIFT);
>>    if (EFI_ERROR (Status)) {
>>      goto ReleaseQueue;
>>    }
>
> (9) The conversion is incomplete for MMIO; note (6) applies.
>
> When fixing this, please move the "If anything fails from here..."
> sentence as well (pls. refer to (2)).
>
> The error label to use with the new SetQueueNum() and SetQueueAlign()
> calls is "ReleaseQueue" of course (they take place after VirtioRingInit()).

This is the same (for VirtioScsiInit) as it is for VirtioNetInitRing
above (hence you can even find note (6) above).

The v4 conversion of virtio-blk to the new protocol was mostly complete.
The v4 conversion of both virtio-net and virtio-scsi was incomplete,
they both lacked two MMIO-specific steps each (for which the PCI backend
provides no-ops). I pointed out the virtio-net problem in note (6), and
the virtio-scsi problem in note (9). I addressed these (and completed
the conversion) for both virtio-net and virtio-scsi in v5 4/8, and the
changelog says there

- VirtioScsiInit(): call SetQueueNum() and SetQueueAlign() for proper MMIO
  operation

> -Jordan

Again, each one of my changes in v5 has been made in response to an
explicit remark made in the v4 (or an earlier) review.

Thanks,
Laszlo

------------------------------------------------------------------------------
Rapidly troubleshoot problems before they affect your business. Most IT 
organizations don't have a clear picture of how application performance 
affects their revenue. With AppDynamics, you get 100% visibility into your 
Java,.NET, & PHP application. Start your 15-day FREE TRIAL of AppDynamics Pro!
http://pubads.g.doubleclick.net/gampad/clk?id=84349831&iu=/4140/ostg.clktrk
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel

Reply via email to