From: Brijesh Singh <brijesh.singh@amd.com>
To: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: brijesh.singh@amd.com, Laszlo Ersek <lersek@redhat.com>,
"edk2-devel@lists.01.org" <edk2-devel@lists.01.org>,
Tom Lendacky <thomas.lendacky@amd.com>,
Jordan Justen <jordan.l.justen@intel.com>,
Jason Wang <jasowang@redhat.com>,
"Michael S . Tsirkin" <mst@redhat.com>,
Gerd Hoffmann <kraxel@redhat.com>
Subject: Re: [RFC v1 0/3] Add VIRTIO_F_IOMMU_PLATFORM support
Date: Thu, 27 Jul 2017 17:10:09 -0500 [thread overview]
Message-ID: <2bbe4119-ed19-d594-741b-cb92cd4f93f2@amd.com> (raw)
In-Reply-To: <9C4ABF62-4018-4014-A3C4-0A8B3B3CE1C2@linaro.org>
On 07/27/2017 04:31 PM, Ard Biesheuvel wrote:
>
>> On 27 Jul 2017, at 21:55, Brijesh Singh <brijesh.singh@amd.com> wrote:
>>
>>
>>
>> On 07/27/2017 02:00 PM, Brijesh Singh wrote:
>>
>>>>> This distribution of operations seems wrong. The key point is that
>>>>> AllocateBuffer() *need not* result in a buffer that is immediately
>>>>> usable, and that client code is required to call Map()
>>>>> *unconditionally*, even if BusMasterCommonBuffer is the desired
>>>>> operation. Therefore, the right distribution of operations is:
>>>>>
>>>>> - IoMmuAllocateBuffer() allocates pages and does not touch the
>>>>> encryption mask..
>>>>>
>>>>> - IoMmuFreeBuffer() deallocates pages and does not touch the encryption
>>>>> mask.
>>>>>
>>> Actually one of main reason why we cleared and restored the memory encryption mask
>>> during allocate/free is because we also consume the IOMMU protocol in QemuFwCfgLib
>>> as a method to allocate and free a DMA buffer. I am certainly open to suggestions.
>>> [1] https://github.com/tianocore/edk2/blob/master/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxe.c#L159
>>> [2] https://github.com/tianocore/edk2/blob/master/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgDxe.c#L197
>>>>> - IoMmuMap() does not allocate pages when BusMasterCommonBuffer is
>>>>> requested, and it allocates pages (bounce buffer) otherwise.
>>>>>
>>> I am trying to wrap my head around how we can support BusMasterCommonBuffer
>>> when buffer was not allocated by us. Changing the memory encryption mask in
>>> a page table will not update the contents. Also since the memory encryption
>>> mask works on PAGE_SIZE hence changing the encryption mask on not our allocated
>>> buffer could mess things up (e.g if NumberOfBytes is not PAGE_SIZE aligned).
>>
>> I may be missing something in my understanding. Here is a flow I have in my
>> mind, please correct me.
>>
>> OvmfPkg/VirtIoBlk.c:
>>
>> VirtioBlkInit()
>> ....
>> ....
>> VirtioRingInit
>> Virtio->AllocateSharedPages(RingSize, &Ring->Base)
>> PciIo->AllocatePages(RingSize, &RingAddress)
>> Virtio->MapSharedPages(...,BusMasterCommonBuffer, Ring->Base, RingSize, &RingDeviceAddress)
>> .....
>> .....
>>
>> This case is straight forward and we can easily maps. No need for bounce buffering.
>>
>> VirtioBlkReadBlocks(..., BufferSize, Buffer,)
>> ......
>> ......
>> SynchronousRequest(..., BufferSize, Buffer)
>> ....
>> Virtio->MapSharedPages(..., BusMasterCommonBuffer, Buffer, BufferSize, &DeviceAddress)
>> VirtioAppendDesc(DeviceAddress, BufferSize, ...)
>> VirtioFlush (...)
>>
>> In the above case, "Buffer" was not allocated by us hence we will not able to change the
>> memory encryption attributes. Am I missing something in the flow ?
>>
>
>
> Common buffer mappings may only be created from buffers that were allocated by AllocateBuffer(). In fact, that is its main purpose
Yes, that part is well understood. If the buffer was allocated by us (e.g vring, request/status
structure etc) then those should be mapped as "BusMasterCommonBuffer".
But I am trying to figure out, how to map a data buffers before issuing a virtio request. e.g when
VirtioBlkReadBlocks() is called, "Buffer" pointer is not a DMA address hence we need to map it.
I think it should be mapped using "BusMasterWrite" not "BusMasterCommonBuffer" before adding into vring.
>>
>>>>> *Regardless* of BusMaster operation, the following actions are carried
>>>>> out unconditionally:
>>>>>
>>>>> . the memory encryption mask is cleared in this function (and in this
>>>>> function only),
>>>>>
>>>>> . An attempt is made to grab a MAP_INFO structure from an internal
>>>>> free list (to be introduced!). The head of the list is a new static
>>>>> variable. If the free list is empty, then a MAP_INFO structure is
>>>>> allocated with AllocatePool(). The NO_MAPPING macro becomes unused
>>>>> and can be deleted from the source code.
>>>>>
>>>>> - IoMmuUnmap() clears the encryption mask unconditionally. (For this, it
>>>>> has to consult the MAP_INFO structure that is being passed in from the
>>>>> caller.) In addition:
>>>>>
>>>>> . If MapInfo->Operation is BusMasterCommonBuffer, then we know the
>>>>> allocation was done separately in AllocateBuffer, so we do not
>>>>> release the pages. Otherwise, we do release the pages.
>>>>>
>>>>> . MapInfo is linked back on the internal free list (see above). It is
>>>>> *never* released with FreePool().
>>>>>
>>>>> This approach guarantees that IoMmuUnmap() can de-program the IOMMU (=
>>>>> re-set the memory encryption mask) without changing the UEFI memory
>>>>> map. (I trust that MemEncryptSevSetPageEncMask() will not split page
>>>>> tables internally when it *re*sets the encryption mask -- is that
>>>>> correct?)
>>
>>
>>
next prev parent reply other threads:[~2017-07-27 22:08 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-07-19 22:09 [RFC v1 0/3] Add VIRTIO_F_IOMMU_PLATFORM support Brijesh Singh
2017-07-19 22:09 ` [RFC v1 1/3] OvmfPkg/Include/Virtio10: Define VIRTIO_F_IOMMU_PLATFORM feature bit Brijesh Singh
2017-07-19 22:09 ` [RFC v1 2/3] OvmfPkg/VirtioLib: Add IOMMU_PLATFORM support Brijesh Singh
2017-07-19 22:09 ` [RFC v1 3/3] OvmfPkg/VirtioBlkDxe: Add VIRITO_F_IOMMU_PLATFORM support Brijesh Singh
[not found] ` <62320c1a-0cec-947c-8c63-5eb0416e4e33@redhat.com>
2017-07-21 11:17 ` [RFC v1 0/3] Add VIRTIO_F_IOMMU_PLATFORM support Brijesh Singh
[not found] ` <20170722024318-mutt-send-email-mst@kernel.org>
2017-07-24 8:25 ` Gerd Hoffmann
2017-07-25 18:17 ` Laszlo Ersek
2017-07-25 23:42 ` Brijesh Singh
[not found] ` <904dae9f-e515-01ba-e16f-6561616c78af@redhat.com>
2017-07-26 15:30 ` Laszlo Ersek
2017-07-27 14:21 ` Brijesh Singh
2017-07-27 17:16 ` Laszlo Ersek
2017-07-27 17:56 ` Ard Biesheuvel
2017-07-27 19:00 ` Brijesh Singh
2017-07-27 20:55 ` Brijesh Singh
2017-07-27 21:31 ` Ard Biesheuvel
2017-07-27 21:38 ` Andrew Fish
2017-07-27 22:13 ` Brijesh Singh
2017-07-27 22:10 ` Brijesh Singh [this message]
2017-07-28 8:39 ` Ard Biesheuvel
2017-07-28 15:27 ` Laszlo Ersek
2017-07-28 13:38 ` Laszlo Ersek
2017-07-28 16:00 ` Brijesh Singh
2017-07-28 16:16 ` Laszlo Ersek
2017-07-28 19:21 ` Laszlo Ersek
2017-07-28 19:59 ` Laszlo Ersek
2017-07-29 0:52 ` Brijesh Singh
2017-07-29 1:37 ` Brijesh Singh
2017-07-31 18:20 ` 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=2bbe4119-ed19-d594-741b-cb92cd4f93f2@amd.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