PCIe DMA aarch64 0x10 转换错误

PCIe DMA aarch64 0x10 Translation Fault

我正在尝试将 PCIe 驱动程序写入从主机内存到 FPGA 的 DMA 页面。我的主机设置是 Cavium ThunderX2,我的 FPGA 是 Xilinx Alveo U50。

DMA from/to 主机导致 ARM SMMU v3.4 引发 事件 0x10 转换错误。我正在使用 dma_map_single(..) 和 dma_alloc_coherent(..) Linux API 将页面的虚拟地址映射到支持 DMA 的地址。

进一步检查事件记录、上下文描述符和流 Table 条目,我有以下信息。

Type of Fault - F_TRANSLATION (Translation Fault)

S2 == 0 (Stage 1 Fault - Virtual Address -> Intermediate Physical Address stage)
Class of Fault = TT/TTD (Translation Table Descriptor Fetch)
PnU == Underprivileged Access
T0SZ == 5'b01000 (16); T1SZ == 5'b00000 (IGNORED because EPD1 == 1)
VAS == 49 bits (Virtual Address Size)
TG0 == 00 (4 kB page granule size)
EPD0 == 0 (Stage 1 page table walk enabled)
EPD1 == 1 (Stage 2 is bypassed)
TB0/1 == 0 (Top byte ignore disabled)
IPS == 44 bits (Input Address size)
SMMU Config = 3'b101 (Stage 1 translation enabled, Stage 2 bypassed)

获取页面的示例虚拟地址和 DMA 地址 -

Virtual Address - 0xFFFF--- (64-bit value)
DMA Address - 0x9F733CA000 (looks within the range defined by T0SZ and compliant with the IPS)

我无法理解为什么在一切看起来都很好的情况下我会遇到第 1 阶段的翻译错误。从技术上讲,我应该遇到第 2 阶段故障,因为它被绕过并且输入地址应该通过 TTB0 转换。

P.S。我是 ARM v8 的新手。如果您需要更多信息,请在评论中告诉我。

附上故障图片F_TRANSLATION。

我能够解决这个问题。 IOMMU 和 DMA 映射之间存在同步失效。在 SMMU 中找不到映射 DMA 地址的有效描述符。

我使用 dma_alloc_coherent(SZ_2M) 获取缓冲区并使用 IOMMU 域操作将 IOVA 映射到 SMMU。

int ret = iommu_domain->ops->map(domain, IOVA, size, phys_addr, PROT)

现在 SMMU 能够获取并翻译 IOVA。

出于某种原因,dma_map_single(..) 不适用于我当前的实现。我必须调查为什么流式 DMA API 不起作用。