diff options
Diffstat (limited to 'mm/memory.c')
| -rw-r--r-- | mm/memory.c | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/mm/memory.c b/mm/memory.c index d14b251a25a6..2302d228fe04 100644 --- a/mm/memory.c +++ b/mm/memory.c | |||
| @@ -1151,7 +1151,7 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, | |||
| 1151 | * be processed until returning to user space. | 1151 | * be processed until returning to user space. |
| 1152 | */ | 1152 | */ |
| 1153 | if (unlikely(test_tsk_thread_flag(tsk, TIF_MEMDIE))) | 1153 | if (unlikely(test_tsk_thread_flag(tsk, TIF_MEMDIE))) |
| 1154 | return -ENOMEM; | 1154 | return i ? i : -ENOMEM; |
| 1155 | 1155 | ||
| 1156 | if (write) | 1156 | if (write) |
| 1157 | foll_flags |= FOLL_WRITE; | 1157 | foll_flags |= FOLL_WRITE; |
| @@ -1697,8 +1697,19 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma, | |||
| 1697 | struct page *dirty_page = NULL; | 1697 | struct page *dirty_page = NULL; |
| 1698 | 1698 | ||
| 1699 | old_page = vm_normal_page(vma, address, orig_pte); | 1699 | old_page = vm_normal_page(vma, address, orig_pte); |
| 1700 | if (!old_page) | 1700 | if (!old_page) { |
| 1701 | /* | ||
| 1702 | * VM_MIXEDMAP !pfn_valid() case | ||
| 1703 | * | ||
| 1704 | * We should not cow pages in a shared writeable mapping. | ||
| 1705 | * Just mark the pages writable as we can't do any dirty | ||
| 1706 | * accounting on raw pfn maps. | ||
| 1707 | */ | ||
| 1708 | if ((vma->vm_flags & (VM_WRITE|VM_SHARED)) == | ||
| 1709 | (VM_WRITE|VM_SHARED)) | ||
| 1710 | goto reuse; | ||
| 1701 | goto gotten; | 1711 | goto gotten; |
| 1712 | } | ||
| 1702 | 1713 | ||
| 1703 | /* | 1714 | /* |
| 1704 | * Take out anonymous pages first, anonymous shared vmas are | 1715 | * Take out anonymous pages first, anonymous shared vmas are |
| @@ -1751,6 +1762,7 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma, | |||
| 1751 | } | 1762 | } |
| 1752 | 1763 | ||
| 1753 | if (reuse) { | 1764 | if (reuse) { |
| 1765 | reuse: | ||
| 1754 | flush_cache_page(vma, address, pte_pfn(orig_pte)); | 1766 | flush_cache_page(vma, address, pte_pfn(orig_pte)); |
| 1755 | entry = pte_mkyoung(orig_pte); | 1767 | entry = pte_mkyoung(orig_pte); |
| 1756 | entry = maybe_mkwrite(pte_mkdirty(entry), vma); | 1768 | entry = maybe_mkwrite(pte_mkdirty(entry), vma); |
