从DMA地址(dma_addr_t)获取PFN? [英] Get PFN from DMA address (dma_addr_t)?

查看:525
本文介绍了从DMA地址(dma_addr_t)获取PFN?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想获得与分配有dma_alloc_coherent的内存块关联的PFN,以便与PCIe设备一起使用,如下所示:

I would like to get the PFN associated with a memory block allocated with dma_alloc_coherent for use with a PCIe device as shown below:

unsigned long pfn;

buffer = dma_alloc_coherent(&pcie->dev, size, &bus_addr, GFP_KERNEL);

// Get PFN?
virt_to_phys(buffer) >> PAGE_SHIFT;

我知道这可能不是正确的方法,但是它似乎可行...我只是在寻找正确的解决方案来转换潜在的总线地址(因为我不知道是否有IOMMU )到PFN.预先感谢.

I'm aware that this is probably not the correct method, but it seems to work... I'm just looking for the right solution to translate the potential bus address (since I do not know if there is an IOMMU) to a PFN. Thanks in advance.

注意:内核中似乎有一个叫做dma_to_pfn的ARM函数,这似乎正是我所需要的,但是对于x86.

Note: There seems to be an ARM function in the kernel called dma_to_pfn, which seems to be exactly what I need, but for x86.

推荐答案

您所做的确实是错误的.在 virt_to_phys() :

What you're doing is indeed wrong. From the man page for virt_to_phys():

此功能不提供DMA传输的总线映射.在几乎所有可能的情况下,设备驱动程序都不应使用此功能.

This function does not give bus mappings for DMA transfers. In almost all conceivable cases a device driver should not be using this function.

DMA地址的等效功能为 dma_to_phys() ,在include/linux/dma-direct.h中定义如下:

The equivalent function for DMA addresses is dma_to_phys(), defined in include/linux/dma-direct.h as follows:

phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr);

因此,您可以这样做:

dma_to_phys(&pcie->dev, bus_addr) >> PAGE_SHIFT;

请注意,我使用的是dma_alloc_coherent()而不是buffer返回的bus_addr,因为您显然需要将DMA地址(dma_addr_t)传递给此函数,而不是虚拟地址.

Notice that I am using the bus_addr returned by dma_alloc_coherent(), not buffer, since you obviously need to pass a DMA address (dma_addr_t) to this function, not a virtual address.

似乎也有一个宏 include/linux/pfn.h中定义的> ,以获取给定物理地址的PFN(如果您更喜欢使用该地址):

There also seems to be a macro PHYS_PFN() defined in include/linux/pfn.h to get the PFN for a given physical address, if you prefer to use that:

PHYS_PFN(dma_to_phys(&pcie->dev, bus_addr));

这篇关于从DMA地址(dma_addr_t)获取PFN?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆