public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: Laszlo Ersek <lersek@redhat.com>
To: Brijesh Singh <brijesh.singh@amd.com>, edk2-devel@lists.01.org
Cc: Jordan Justen <jordan.l.justen@intel.com>,
	Tom Lendacky <thomas.lendacky@amd.com>,
	Ard Biesheuvel <ard.biesheuvel@linaro.org>
Subject: Re: [PATCH v1 14/14] OvmfPkg/VirtioRngDxe: Use DeviceAddresses in vring descriptors
Date: Thu, 10 Aug 2017 02:46:29 +0200	[thread overview]
Message-ID: <d465c84a-19b9-6d2a-2e81-e796f35388d9@redhat.com> (raw)
In-Reply-To: <82b54f74-f1ec-732f-4757-f7061e536406@redhat.com>

On 08/10/17 02:25, Laszlo Ersek wrote:
> On 08/07/17 13:58, Brijesh Singh wrote:
>> The patch uses newly introduced VIRTIO_DEVICE_PROTOCOL.MapSharedBuffer()
>> to map system memory to device address and programs the vring descriptors
>> with device addresses.
>>
>> 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>
>> Contributed-under: TianoCore Contribution Agreement 1.1
>> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
>> ---
>>  OvmfPkg/VirtioRngDxe/VirtioRng.h |  1 +
>>  OvmfPkg/VirtioRngDxe/VirtioRng.c | 47 +++++++++++++++++---
>>  2 files changed, 43 insertions(+), 5 deletions(-)
> 
> I'm skipping all the other device driver conversion patches for now (v1
> 8-13), because I think that this is the simplest driver, and we already
> have enough changes queued from this review.
> 
> I suggest that for v2, you please update and test all of the drivers (so
> that we can be sure that my requests are feasible), but move this driver
> patch in front of the others.
> 
> I'll say a number of generalities:
> 
> * Please never roll-back earlier actions directly within an
>   error-catching "if" -- instead, insert a new error handling label at
>   the appropriate place, and jump to it with "goto". Sooner or later
>   we'll grow yet more actions, and then we'll have to convert those "if"
>   bodies to goto's anyway.
> 
> * NULL for RingMap is a valid value () -- see also point (8) in my v1
>   03/14 feedback -- and device driver logic should not depend on it.
>   Instead, use additional (precise) labels -- such as "UnmapQueue" and
>   "UnmapBuffer" -- and matching goto statements.
> 
>   If a VirtIo->MapSharedBuffer() implementation gives you RingMap=NULL
>   (on success), then VirtIo->UnmapSharedBuffer() will also take
>   RingMap=NULL -- you simply don't have to be aware of the value.
> 
> * In most cases, the fact that you have a live exit-boot-services
>   callback implies that your device is "live" as well. So no need for
>   additional checks before unmapping the queue. (There are exceptions of
>   course, such as virtio-net -- IIRC the SimpleNetworkProtocol has an
>   internal state flag that affects this question.)
> 
>   For example, in the virtio-rng case, the exit-boot-services
>   notification function is installed in VirtioRngDriverBindingStart()
>   *after* the call to VirtioRngInit(). In addition, it is uninstalled --
>   its associated event is closed -- in VirtioRngDriverBindingStop(),
>   *before* the call to VirtioRngUninit(). So whenever the notification
>   function can run, the device is guaranteed to be live.

Something else: please don't forget about the VIRTIO_F_IOMMU_PLATFORM
flag -- pls see point (5.3) in
<http://mid.mail-archive.com/841bec5f-6f6e-8b1f-25ba-0fd37a915b72@redhat.com>.

After this conversion is complete, we can claim that our virtio device
drivers are "IOMMU aware", whenever we negotiate VIRTIO_F_VERSION_1.
(It's a different question what IOMMU drivers we have.)

Thanks,
Laszlo


>> diff --git a/OvmfPkg/VirtioRngDxe/VirtioRng.h b/OvmfPkg/VirtioRngDxe/VirtioRng.h
>> index 998f9fae48c2..b372d84c1ebc 100644
>> --- a/OvmfPkg/VirtioRngDxe/VirtioRng.h
>> +++ b/OvmfPkg/VirtioRngDxe/VirtioRng.h
>> @@ -38,6 +38,7 @@ typedef struct {
>>    EFI_EVENT                 ExitBoot;       // DriverBindingStart   0
>>    VRING                     Ring;           // VirtioRingInit       2
>>    EFI_RNG_PROTOCOL          Rng;            // VirtioRngInit        1
>> +  VOID                      *RingMap;       // VirtioRngInit        1
>>  } VIRTIO_RNG_DEV;
>>  
>>  #define VIRTIO_ENTROPY_SOURCE_FROM_RNG(RngPointer) \
>> diff --git a/OvmfPkg/VirtioRngDxe/VirtioRng.c b/OvmfPkg/VirtioRngDxe/VirtioRng.c
>> index e20602ac7225..5ff54867616a 100644
>> --- a/OvmfPkg/VirtioRngDxe/VirtioRng.c
>> +++ b/OvmfPkg/VirtioRngDxe/VirtioRng.c
>> @@ -140,11 +140,15 @@ VirtioRngGetRNG (
>>    UINT32                    Len;
>>    UINT32                    BufferSize;
>>    EFI_STATUS                Status;
>> +  UINTN                     NumPages;
>> +  EFI_PHYSICAL_ADDRESS      DeviceAddress;
>> +  VOID                      *Mapping;
>>  
>>    if (This == NULL || RNGValueLength == 0 || RNGValue == NULL) {
>>      return EFI_INVALID_PARAMETER;
>>    }
>>  
>> +  Dev = VIRTIO_ENTROPY_SOURCE_FROM_RNG (This);
>>    //
>>    // We only support the raw algorithm, so reject requests for anything else
>>    //
>> @@ -153,12 +157,18 @@ VirtioRngGetRNG (
>>      return EFI_UNSUPPORTED;
>>    }
>>  
>> -  Buffer = (volatile UINT8 *)AllocatePool (RNGValueLength);
>> -  if (Buffer == NULL) {
>> +  NumPages = EFI_SIZE_TO_PAGES (RNGValueLength);
>> +  Status = VirtioAllocateSharedPages (Dev->VirtIo, NumPages, (VOID *)&Buffer);
>> +  if (EFI_ERROR (Status)) {
>>      return EFI_DEVICE_ERROR;
>>    }
>>  
>> -  Dev = VIRTIO_ENTROPY_SOURCE_FROM_RNG (This);
>> +  Status = VirtioMapSharedBufferWrite (Dev->VirtIo, (VOID *)Buffer,
>> +             RNGValueLength, &DeviceAddress, &Mapping);
>> +  if (EFI_ERROR (Status)) {
>> +    VirtioFreeSharedPages (Dev->VirtIo, NumPages, (VOID *)Buffer);
>> +    return EFI_DEVICE_ERROR;
>> +  }
>>  
>>    //
>>    // The Virtio RNG device may return less data than we asked it to, and can
>> @@ -170,7 +180,7 @@ VirtioRngGetRNG (
>>  
>>      VirtioPrepare (&Dev->Ring, &Indices);
>>      VirtioAppendDesc (&Dev->Ring,
>> -      (UINTN)Buffer + Index,
>> +      (UINTN)DeviceAddress + Index,
>>        BufferSize,
>>        VRING_DESC_F_WRITE,
>>        &Indices);
>> @@ -178,19 +188,22 @@ VirtioRngGetRNG (
>>      if (VirtioFlush (Dev->VirtIo, 0, &Dev->Ring, &Indices, &Len) !=
>>          EFI_SUCCESS) {
>>        Status = EFI_DEVICE_ERROR;
>> +      VirtioUnmapSharedBuffer (Dev->VirtIo, Mapping);
>>        goto FreeBuffer;
>>      }
>>      ASSERT (Len > 0);
>>      ASSERT (Len <= BufferSize);
>>    }
>>  
>> +  VirtioUnmapSharedBuffer (Dev->VirtIo, Mapping);
>> +
>>    for (Index = 0; Index < RNGValueLength; Index++) {
>>      RNGValue[Index] = Buffer[Index];
>>    }
>>    Status = EFI_SUCCESS;
>>  
>>  FreeBuffer:
>> -  FreePool ((VOID *)Buffer);
>> +  VirtioFreeSharedPages (Dev->VirtIo, NumPages, (VOID *)Buffer);
>>    return Status;
>>  }
>>  
>> @@ -281,6 +294,11 @@ VirtioRngInit (
>>      goto Failed;
>>    }
>>  
>> +  Status = VirtioRingMap (Dev->VirtIo, &Dev->Ring, &Dev->RingMap);
>> +  if (EFI_ERROR (Status)) {
>> +    goto ReleaseQueue;
>> +  }
>> +
>>    //
>>    // Additional steps for MMIO: align the queue appropriately, and set the
>>    // size. If anything fails from here on, we must release the ring resources.
>> @@ -332,6 +350,11 @@ VirtioRngInit (
>>    return EFI_SUCCESS;
>>  
>>  ReleaseQueue:
>> +  if (Dev->RingMap != NULL) {
>> +    VirtioRingUnmap (Dev->VirtIo, &Dev->Ring, Dev->RingMap);
>> +    Dev->RingMap = NULL;
>> +  }
>> +
>>    VirtioRingUninit (Dev->VirtIo, &Dev->Ring);
>>  
>>  Failed:
>> @@ -359,6 +382,11 @@ VirtioRngUninit (
>>    // the old comms area.
>>    //
>>    Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0);
>> +
>> +  if (Dev->RingMap != NULL) {
>> +    VirtioRingUnmap (Dev->VirtIo, &Dev->Ring, Dev->RingMap);
>> +  }
>> +
>>    VirtioRingUninit (Dev->VirtIo, &Dev->Ring);
>>  }
>>  
>> @@ -385,6 +413,15 @@ VirtioRngExitBoot (
>>    //
>>    Dev = Context;
>>    Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0);
>> +
>> +  //
>> +  // If Ring mapping exist then umap it so that hypervisor will not able to
>> +  // get readable data after device reset.
>> +  //
>> +  if (Dev->RingMap != NULL) {
>> +    VirtioRingUnmap (Dev->VirtIo, &Dev->Ring, Dev->RingMap);
>> +    Dev->RingMap = NULL;
>> +  }
>>  }
>>  
>>  
>>
> 



  reply	other threads:[~2017-08-10  0:44 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-08-07 11:58 [PATCH v1 00/14] OvmfPkg/Virtio: Add APIs to map system physical to device address Brijesh Singh
2017-08-07 11:58 ` [PATCH v1 01/14] OvmfPkg/Virtio: Introduce new member functions in VIRTIO_DEVICE_PROTOCOL Brijesh Singh
2017-08-09 14:27   ` Laszlo Ersek
2017-08-09 18:23     ` Brijesh Singh
2017-08-07 11:58 ` [PATCH v1 02/14] OvmfPkg/Virtio10Dxe: Implement new member functions Brijesh Singh
2017-08-09 16:50   ` Laszlo Ersek
2017-08-07 11:58 ` [PATCH v1 03/14] OvmfPkg/VirtioPciDeviceDxe: " Brijesh Singh
2017-08-09 17:09   ` Laszlo Ersek
2017-08-10 18:41     ` Brijesh Singh
2017-08-10 19:47       ` Laszlo Ersek
2017-08-07 11:58 ` [PATCH v1 04/14] OvmfPkg/VirtioLib: Add SharedBuffer helper functions Brijesh Singh
2017-08-09 20:30   ` Laszlo Ersek
2017-08-07 11:58 ` [PATCH v1 05/14] OvmfPkg/VirtioLib: Pass VirtIo instance in VringInit/Uinit() Brijesh Singh
2017-08-09 21:13   ` Laszlo Ersek
2017-08-07 11:58 ` [PATCH v1 06/14] OvmfPkg/VirtioLib: Add functions to map/unmap VRING Brijesh Singh
2017-08-09 23:51   ` Laszlo Ersek
2017-08-07 11:58 ` [PATCH v1 07/14] OvmfPkg/VirtioLib: Use AllocateShared() to allocate vring buffer Brijesh Singh
2017-08-10  0:02   ` Laszlo Ersek
2017-08-07 11:58 ` [PATCH v1 08/14] OvmfPkg/VirtioBlkDxe: Use DeviceAddresses in vring descriptors Brijesh Singh
2017-08-07 11:58 ` [PATCH v1 09/14] OvmfPkg/VirtioScsiDxe: " Brijesh Singh
2017-08-07 11:58 ` [PATCH v1 10/14] OvmfPkg/VirtioNetDxe: Allocate Tx and Rx ring using AllocateSharedPage() Brijesh Singh
2017-08-07 11:58 ` [PATCH v1 11/14] OvmfPkg/VirtioNetDxe: Allocate RxBuf using AllocateSharedPages() Brijesh Singh
2017-08-07 11:58 ` [PATCH v1 12/14] OvmfPkg/VirtioNetDxe: Dynamically allocate transmit header Brijesh Singh
2017-08-07 11:58 ` [PATCH v1 13/14] OvmfPkg/VirtioNetDxe: Use DeviceAddress in transmit vring descriptors Brijesh Singh
2017-08-07 11:58 ` [PATCH v1 14/14] OvmfPkg/VirtioRngDxe: Use DeviceAddresses in " Brijesh Singh
2017-08-10  0:25   ` Laszlo Ersek
2017-08-10  0:46     ` Laszlo Ersek [this message]
2017-08-09 14:39 ` [PATCH v1 00/14] OvmfPkg/Virtio: Add APIs to map system physical to device address Laszlo Ersek
2017-08-09 17:35   ` Brijesh Singh
2017-08-09 17:56     ` Laszlo Ersek
2017-08-09 19:29       ` Laszlo Ersek
2017-08-11 22:22       ` Brijesh Singh
2017-08-15 10:42         ` Laszlo Ersek
2017-08-15 19:32           ` Brijesh Singh
2017-08-15 19:48             ` Laszlo Ersek
2017-08-15 20:26               ` Brijesh Singh
2017-08-15 20:39                 ` Laszlo Ersek
2017-08-15 20:44                   ` Brijesh Singh
2017-08-15 21:57                     ` Laszlo Ersek
2017-08-09 22:38 ` Laszlo Ersek
2017-08-09 22:44   ` Brijesh Singh
2017-08-10  9:53     ` Laszlo Ersek

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=d465c84a-19b9-6d2a-2e81-e796f35388d9@redhat.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox