| @@ -1664,6 +1664,9 @@ out_unlock: · 1663 unmodified lines |
| 1664 | * vmf_insert_pfn_prot should only be used if using multiple VMAs is | 1664 | * vmf_insert_pfn_prot should only be used if using multiple VMAs is |
| 1665 | * impractical. | 1665 | * impractical. |
| 1666 | * | 1666 | * |
| | 1667 | * See vmf_insert_mixed_prot() for a discussion of the implication of using |
| | 1668 | * a value of @pgprot different from that of @vma->vm_page_prot. |
| | 1669 | * |
| 1667 | * Context: Process context. May allocate using %GFP_KERNEL. | 1670 | * Context: Process context. May allocate using %GFP_KERNEL. |
| 1668 | * Return: vm_fault_t value. | 1671 | * Return: vm_fault_t value. |
| 1669 | */ | 1672 | */ |
| @@ -1737,9 +1740,9 @@ static bool vm_mixed_ok(struct vm_area_struct *vma, pfn_t pfn) · 67 unmodified lines |
| 1737 | } | 1740 | } |
| 1738 | | 1741 | |
| 1739 | static vm_fault_t __vm_insert_mixed(struct vm_area_struct *vma, | 1742 | static vm_fault_t __vm_insert_mixed(struct vm_area_struct *vma, |
| 1740 | unsigned long addr, pfn_t pfn, bool mkwrite) | 1743 | unsigned long addr, pfn_t pfn, pgprot_t pgprot, |
| | 1744 | bool mkwrite) |
| 1741 | { | 1745 | { |
| 1742 | pgprot_t pgprot = vma->vm_page_prot; | | |
| 1743 | int err; | 1746 | int err; |
| 1744 | | 1747 | |
| 1745 | BUG_ON(!vm_mixed_ok(vma, pfn)); | 1748 | BUG_ON(!vm_mixed_ok(vma, pfn)); |
| @@ -1782,10 +1785,42 @@ static vm_fault_t __vm_insert_mixed(struct vm_area_struct *vma, · 36 unmodified lines |
| 1782 | return VM_FAULT_NOPAGE; | 1785 | return VM_FAULT_NOPAGE; |
| 1783 | } | 1786 | } |
| 1784 | | 1787 | |
| | 1788 | /** |
| | 1789 | * vmf_insert_mixed_prot - insert single pfn into user vma with specified pgprot |
| | 1790 | * @vma: user vma to map to |
| | 1791 | * @addr: target user address of this page |
| | 1792 | * @pfn: source kernel pfn |
| | 1793 | * @pgprot: pgprot flags for the inserted page |
| | 1794 | * |
| | 1795 | * This is exactly like vmf_insert_mixed(), except that it allows drivers to |
| | 1796 | * to override pgprot on a per-page basis. |
| | 1797 | * |
| | 1798 | * Typically this function should be used by drivers to set caching- and |
| | 1799 | * encryption bits different than those of @vma->vm_page_prot, because |
| | 1800 | * the caching- or encryption mode may not be known at mmap() time. |
| | 1801 | * This is ok as long as @vma->vm_page_prot is not used by the core vm |
| | 1802 | * to set caching and encryption bits for those vmas (except for COW pages). |
| | 1803 | * This is ensured by core vm only modifying these page table entries using |
| | 1804 | * functions that don't touch caching- or encryption bits, using pte_modify() |
| | 1805 | * if needed. (See for example mprotect()). |
| | 1806 | * Also when new page-table entries are created, this is only done using the |
| | 1807 | * fault() callback, and never using the value of vma->vm_page_prot, |
| | 1808 | * except for page-table entries that point to anonymous pages as the result |
| | 1809 | * of COW. |
| | 1810 | * |
| | 1811 | * Context: Process context. May allocate using %GFP_KERNEL. |
| | 1812 | * Return: vm_fault_t value. |
| | 1813 | */ |
| | 1814 | vm_fault_t vmf_insert_mixed_prot(struct vm_area_struct *vma, unsigned long addr, |
| | 1815 | pfn_t pfn, pgprot_t pgprot) |
| | 1816 | { |
| | 1817 | return __vm_insert_mixed(vma, addr, pfn, pgprot, false); |
| | 1818 | } |
| | 1819 | |
| 1785 | vm_fault_t vmf_insert_mixed(struct vm_area_struct *vma, unsigned long addr, | 1820 | vm_fault_t vmf_insert_mixed(struct vm_area_struct *vma, unsigned long addr, |
| 1786 | pfn_t pfn) | 1821 | pfn_t pfn) |
| 1787 | { | 1822 | { |
| 1788 | return __vm_insert_mixed(vma, addr, pfn, false); | 1823 | return __vm_insert_mixed(vma, addr, pfn, vma->vm_page_prot, false); |
| 1789 | } | 1824 | } |
| 1790 | EXPORT_SYMBOL(vmf_insert_mixed); | 1825 | EXPORT_SYMBOL(vmf_insert_mixed); |
| 1791 | | 1826 | |
| @@ -1797,7 +1832,7 @@ EXPORT_SYMBOL(vmf_insert_mixed); · 5 unmodified lines |
| 1797 | vm_fault_t vmf_insert_mixed_mkwrite(struct vm_area_struct *vma, | 1832 | vm_fault_t vmf_insert_mixed_mkwrite(struct vm_area_struct *vma, |
| 1798 | unsigned long addr, pfn_t pfn) | 1833 | unsigned long addr, pfn_t pfn) |
| 1799 | { | 1834 | { |
| 1800 | return __vm_insert_mixed(vma, addr, pfn, true); | 1835 | return __vm_insert_mixed(vma, addr, pfn, vma->vm_page_prot, true); |
| 1801 | } | 1836 | } |
| 1802 | EXPORT_SYMBOL(vmf_insert_mixed_mkwrite); | 1837 | EXPORT_SYMBOL(vmf_insert_mixed_mkwrite); |
| 1803 | | 1838 | |