summaryrefslogtreecommitdiffstats
path: root/OvmfPkg/IoMmuDxe/IoMmuBuffer.c
Commit message (Collapse)AuthorAgeFilesLines
* OvmfPkg/IoMmuDxe: don't rely on TPLs to manage concurrencyArd Biesheuvel2023-09-021-41/+59
| | | | | | | | | | | | | | | | | Instead of relying on raising the TPL to protect the critical sections that manipulate the global bitmask that keeps track of bounce buffer allocations, use compare-and-exchange to manage the global variable, and tweak the logic to line up with that. Given that IoMmuDxe implements a singleton protocol that is shared between multiple drivers, and considering the elaborate and confusing requirements in the UEFP spec regarding TPL levels at which protocol methods may be invoked, not relying on TPL levels at all is a more robust approach in this case. Link: https://bugzilla.redhat.com/show_bug.cgi?id=2211060 Signed-off-by: Ard Biesheuvel <ardb@kernel.org> Acked-by: Pedro Falcato <pedro.falcato@gmail.com>
* OvmfPkg/IoMmuDxe: add locking to IoMmuAllocateBounceBufferGerd Hoffmann2023-07-191-0/+7
| | | | | | | | | | | | | | | | | | | Searching for an unused bounce buffer in mReservedMemBitmap and reserving the buffer by flipping the bit is a critical section which must not be interrupted. Raise the TPL level to ensure that. Without this fix it can happen that IoMmuDxe hands out the same bounce buffer twice, causing trouble down the road. Seen happening in practice with VirtioNetDxe setting up the network interface (and calling into IoMmuDxe from a polling timer callback) in parallel with Boot Manager doing some disk I/O. An ASSERT() in VirtioNet caught the buffer inconsistency. Full story with lots of details and discussions is available here: https://bugzilla.redhat.com/show_bug.cgi?id=2211060 Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
* OvmfPkg: Update code to be more C11 compliant by using __func__Rebecca Cran2023-04-101-4/+4
| | | | | | | | | | | | | __FUNCTION__ is a pre-standard extension that gcc and Visual C++ among others support, while __func__ was standardized in C99. Since it's more standard, replace __FUNCTION__ with __func__ throughout OvmfPkg. Signed-off-by: Rebecca Cran <rebecca@bsdio.com> Reviewed-by: Michael D Kinney <michael.d.kinney@intel.com> Reviewed-by: Ard Biesheuvel <ardb@kernel.org> Reviewed-by: Sunil V L <sunilvl@ventanamicro.com>
* OvmfPkg/IoMmuDxe: Add SEV support for reserved shared memoryTom Lendacky2022-12-181-12/+42
| | | | | | | | | | | | | | Add support to use the reserved shared memory within the IoMmu library. This improves boot times for all SEV guests, with SEV-SNP benefiting the most as it avoids the page state change call to the hypervisor. Cc: Erdem Aktas <erdemaktas@google.com> Cc: James Bottomley <jejb@linux.ibm.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Min Xu <min.m.xu@intel.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Acked-by: Jiewen Yao <Jiewen.yao@intel.com> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
* OvmfPkg/IoMmuDxe: Reserve shared memory region for DMA operationMin M Xu2022-12-181-0/+465
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4171 A typical QEMU fw_cfg read bytes with IOMMU for td guest is that: (QemuFwCfgReadBytes@QemuFwCfgLib.c is the example) 1) Allocate DMA Access buffer 2) Map actual data buffer 3) start the transfer and wait for the transfer to complete 4) Free DMA Access buffer 5) Un-map actual data buffer In step 1/2, Private memories are allocated, converted to shared memories. In Step 4/5 the shared memories are converted to private memories and accepted again. The final step is to free the pages. This is time-consuming and impacts td guest's boot perf (both direct boot and grub boot) badly. In a typical grub boot, there are about 5000 calls of page allocation and private/share conversion. Most of page size is less than 32KB. This patch allocates a memory region and initializes it into pieces of memory with different sizes. A piece of such memory consists of 2 parts: the first page is of private memory, and the other pages are shared memory. This is to meet the layout of common buffer. When allocating bounce buffer in IoMmuMap(), IoMmuAllocateBounceBuffer() is called to allocate the buffer. Accordingly when freeing bounce buffer in IoMmuUnmapWorker(), IoMmuFreeBounceBuffer() is called to free the bounce buffer. CommonBuffer is allocated by IoMmuAllocateCommonBuffer and accordingly freed by IoMmuFreeCommonBuffer. This feature is tested in Intel TDX pre-production platform. It saves up to hundreds of ms in a grub boot. Cc: Erdem Aktas <erdemaktas@google.com> Cc: James Bottomley <jejb@linux.ibm.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Tom Lendacky <thomas.lendacky@amd.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Reviewed-by: Jiewen Yao <Jiewen.yao@intel.com> Signed-off-by: Min Xu <min.m.xu@intel.com> Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>