函数源码

Linux Kernel

v5.5.9

Brick Technologies Co., Ltd

Source File:mm\memory.c Create Date:2022-07-27 16:08:12
首页 Copyright©Brick

1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
static vm_fault_t __vm_insert_mixed(struct vm_area_struct *vma,
        unsigned long addr, pfn_t pfn, bool mkwrite)
{
    pgprot_t pgprot = vma->vm_page_prot;
    int err;
 
    BUG_ON(!vm_mixed_ok(vma, pfn));
 
    if (addr < vma->vm_start || addr >= vma->vm_end)
        return VM_FAULT_SIGBUS;
 
    track_pfn_insert(vma, &pgprot, pfn);
 
    if (!pfn_modify_allowed(pfn_t_to_pfn(pfn), pgprot))
        return VM_FAULT_SIGBUS;
 
    /*
     * If we don't have pte special, then we have to use the pfn_valid()
     * based VM_MIXEDMAP scheme (see vm_normal_page), and thus we *must*
     * refcount the page if pfn_valid is true (hence insert_page rather
     * than insert_pfn).  If a zero_pfn were inserted into a VM_MIXEDMAP
     * without pte special, it would there be refcounted as a normal page.
     */
    if (!IS_ENABLED(CONFIG_ARCH_HAS_PTE_SPECIAL) &&
        !pfn_t_devmap(pfn) && pfn_t_valid(pfn)) {
        struct page *page;
 
        /*
         * At this point we are committed to insert_page()
         * regardless of whether the caller specified flags that
         * result in pfn_t_has_page() == false.
         */
        page = pfn_to_page(pfn_t_to_pfn(pfn));
        err = insert_page(vma, addr, page, pgprot);
    } else {
        return insert_pfn(vma, addr, pfn, pgprot, mkwrite);
    }
 
    if (err == -ENOMEM)
        return VM_FAULT_OOM;
    if (err < 0 && err != -EBUSY)
        return VM_FAULT_SIGBUS;
 
    return VM_FAULT_NOPAGE;
}