smmu 学习笔记之iova_domain中的一个变量granule

在iova_domain中有一个变量granule
struct iova_domain {
    spinlock_t    iova_rbtree_lock; /* Lock to protect update of rbtree */
    struct rb_root    rbroot;        /* iova domain rbtree root */
    struct rb_node    *cached32_node; /* Save last alloced node */
    unsigned long    granule;    /* pfn granularity for this domain */
    unsigned long    start_pfn;    /* Lower limit for this domain */
    unsigned long    dma_32bit_pfn;
    struct iova_rcache rcaches[IOVA_RANGE_CACHE_MAX_SIZE];    /* IOVA range caches */
};
这个变量会在iommu_dma_init_domain 中通过init_iova_domain来赋值
首先在iommu_dma_init_domain 中得到order,__ffs 这个函数之前分析过,就
order = __ffs(domain->pgsize_bitmap);
是得到domain->pgsize_bitmap 的最低为1的为,我们以4096 为里的话,就是12.然后又1UL << order就等于4096,最后调用init_iova_domain来给granule 赋值.
init_iova_domain(iovad, 1UL << order, base_pfn, end_pfn);

init_iova_domain(struct iova_domain *iovad, unsigned long granule,
    unsigned long start_pfn, unsigned long pfn_32bit)
{
    /*
     * IOVA granularity will normally be equal to the smallest
     * supported IOMMU page size; both *must* be capable of
     * representing individual CPU pages exactly.
     */
    BUG_ON((granule > PAGE_SIZE) || !is_power_of_2(granule));

    spin_lock_init(&iovad->iova_rbtree_lock);
    iovad->rbroot = RB_ROOT;
    iovad->cached32_node = NULL;
    iovad->granule = granule;
    iovad->start_pfn = start_pfn;
    iovad->dma_32bit_pfn = pfn_32bit;
    init_iova_rcaches(iovad);
}
所以这里的granule 就等于4096,也就说这个domain 最低是一个4096 对齐的.
这样我们在iommu_dma_map_page 中调用
size_t iova_off = iova_offset(iovad, phys);来计算iova_off的时候起始就是让phys以granule 对齐
static inline size_t iova_offset(struct iova_domain *iovad, dma_addr_t iova)
{
    return iova & iova_mask(iovad);
}
static inline unsigned long iova_mask(struct iova_domain *iovad)
{
    return iovad->granule - 1;
}
这样在调用(iommu_map(domain, dma_addr, phys - iova_off, len, prot))的时候,第三个参数paddr就表示需要映射的物理地址和这个domain 最小支持的page size的差值,一般情况下这个差值为0.因为我们通过iommu映射的时候一般都是pagesize对齐的。
如果不为0的话会在iommu_map->iommu_pgsize 中尝试合并.
最后在计算pte的时候会加上这个paddr
pte |= pfn_to_iopte(paddr >> data->pg_shift, data);



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值