*参照元 [#h47764f0]
#backlinks

*説明 [#fd10e78d]
-パス: [[linux-4.4.1/mm/gup.c]]

-FIXME: これは何?
--説明


**引数 [#e02be924]
-struct mm_struct *mm
--
--[[linux-4.4.1/mm_struct]]
-unsigned long address
--
-unsigned int gup_flags
--
-struct vm_area_struct **vma
--
--[[linux-4.4.1/vm_area_struct]]
-struct page **page
--
--[[linux-4.4.1/page]]


**返り値 [#pe0d2321]
-
-int
--


**参考 [#k2a7fc95]


*実装 [#u6f6b48e]
 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;
 
-
--[[linux-4.4.1/pgd_t]]
--[[linux-4.4.1/pud_t]]
--[[linux-4.4.1/pmd_t]]
--[[linux-4.4.1/pte_t]]

         /* 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));
-仮想アドレスが TASK_SIZE より大きければ、カーネル空間の仮想アドレス。それ以外はユーザ空間の仮想アドレス。
--[[linux-4.4.1/TASK_SIZE]]
-カーネル空間のページテーブルを得る。
--[[linux-4.4.1/pgd_offset_k()]]
--[[linux-4.4.1/pgd_offset_gate()]]
-ページテーブルが取得できなければバグ。
--[[linux-4.4.1/BUG_ON()]]
--[[linux-4.4.1/pgd_none()]]

         pud = pud_offset(pgd, address);
         BUG_ON(pud_none(*pud));
-
--[[linux-4.4.1/pud_offset()]]
--[[linux-4.4.1/pud_none()]]

         pmd = pmd_offset(pud, address);
         if (pmd_none(*pmd))
                 return -EFAULT;
         VM_BUG_ON(pmd_trans_huge(*pmd));
-
--[[linux-4.4.1/pud_none()]]
--[[linux-4.4.1/pmd_offset()]]

         pte = pte_offset_map(pmd, address);
         if (pte_none(*pte))
                 goto unmap;
-
--[[linux-4.4.1/pte_offset_map()]]
--[[linux-4.4.1/pte_none()]]

         *vma = get_gate_vma(mm);
         if (!page)
                 goto out;
-
--[[linux-4.4.1/get_gate_vma()]]

         *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);
-
--[[linux-4.4.1/vm_normal_page()]]
--[[linux-4.4.1/is_zero_pfn()]]
--[[linux-4.4.1/pte_pfn()]]
--[[linux-4.4.1/pte_page()]]
--[[linux-4.4.1/get_page()]]

 out:
         ret = 0;
 unmap:
         pte_unmap(pte);
         return ret;
 }
-
--[[linux-4.4.1/pte_unmap()]]


*コメント [#o39a8714]

トップ   編集 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS