参照元

説明

引数

返り値

参考

実装

static int get_gate_page(struct mm_struct *mm, unsigned long address,
                unsigned int gup_flags, struct vm_area_struct **vma,
                struct page **page)
{
        pgd_t *pgd;
        pud_t *pud;
        pmd_t *pmd;
        pte_t *pte;
        int ret = -EFAULT;
        /* user gate pages are read-only */
        if (gup_flags & FOLL_WRITE)
                return -EFAULT;
        if (address > TASK_SIZE)
                pgd = pgd_offset_k(address);
        else
                pgd = pgd_offset_gate(mm, address);
        BUG_ON(pgd_none(*pgd));
        pud = pud_offset(pgd, address);
        BUG_ON(pud_none(*pud));
        pmd = pmd_offset(pud, address);
        if (pmd_none(*pmd))
                return -EFAULT;
        VM_BUG_ON(pmd_trans_huge(*pmd));
        pte = pte_offset_map(pmd, address);
        if (pte_none(*pte))
                goto unmap;
        *vma = get_gate_vma(mm);
        if (!page)
                goto out;
        *page = vm_normal_page(*vma, address, *pte);
        if (!*page) {
                if ((gup_flags & FOLL_DUMP) || !is_zero_pfn(pte_pfn(*pte)))
                        goto unmap;
                *page = pte_page(*pte);
        }
        get_page(*page);
out:
        ret = 0;
unmap:
        pte_unmap(pte);
        return ret;
}

コメント


トップ   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS