linux va 2 pa walk through

linux-3.0.35

drivers/staging/comedi/drivers.c

x86

static inline unsigned long uvirt_to_kva(pgd_t *pgd, unsigned long adr)
{
        unsigned long ret = 0UL;
        pmd_t *pmd;
        pte_t *ptep, pte;
        pud_t *pud;

        if (!pgd_none(*pgd)) {
                pud = pud_offset(pgd, adr);
                pmd = pmd_offset(pud, adr);
                if (!pmd_none(*pmd)) {
                        ptep = pte_offset_kernel(pmd, adr);
                        pte = *ptep;
                        if (pte_present(pte)) {
                                ret = (unsigned long)
                                    page_address(pte_page(pte));
                                ret |= (adr & (PAGE_SIZE - 1));
                        }
                }
        }
        return ret;
}

static inline unsigned long kvirt_to_kva(unsigned long adr)
{
        unsigned long va, kva;

        va = adr;
        kva = uvirt_to_kva(pgd_offset_k(va), va);

        return kva;
}

drivers/staging/tidspbriage/core/tiomap3430.c

arm


/*
 *  ======== user_va2_pa ========
 *  Purpose:
 *      This function walks through the page tables to convert a userland
 *      virtual address to physical address
 */
static u32 user_va2_pa(struct mm_struct *mm, u32 address)
{
        pgd_t *pgd;
        pmd_t *pmd;
        pte_t *ptep, pte;

        pgd = pgd_offset(mm, address);
        if (!(pgd_none(*pgd) || pgd_bad(*pgd))) {
                pmd = pmd_offset(pgd, address);
                if (!(pmd_none(*pmd) || pmd_bad(*pmd))) {
                        ptep = pte_offset_map(pmd, address);
                        if (ptep) {
                                pte = *ptep;
                                if (pte_present(pte))
                                        return pte & PAGE_MASK;
                        }
                }
        }

        return 0;
}


pandaboard AOSP kernel 3.0.31

drivers/video/omap2/dsscomp/device.c

arm

static u32 hwc_virt_to_phys(u32 arg)
{
        pmd_t *pmd;
        pte_t *ptep;

        pgd_t *pgd = pgd_offset(current->mm, arg);
        if (pgd_none(*pgd) || pgd_bad(*pgd))
                return 0;

        pmd = pmd_offset(pgd, arg);
        if (pmd_none(*pmd) || pmd_bad(*pmd))
                return 0;

        ptep = pte_offset_map(pmd, arg);
        if (ptep && pte_present(*ptep))
                return (PAGE_MASK & *ptep) | (~PAGE_MASK & arg);

        return 0;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值