From ddb1d4be594baf555c3beb4f93f61591e7401c78 Mon Sep 17 00:00:00 2001 From: Hugh Dickins Date: Mon, 21 Nov 2005 21:32:19 -0800 Subject: [PATCH] --- yaml --- r: 14611 b: refs/heads/master c: f57e88a8d83de8d844b57e16b84d2f762fe9f092 h: refs/heads/master i: 14609: b967d6e854b1d59a85221b5ee8c99f32f7de1036 14607: c0a3932a59ac0c406e30594dea88e95981fd89e5 v: v3 --- [refs] | 2 +- trunk/drivers/char/mem.c | 2 +- trunk/mm/memory.c | 14 ++++++++++++-- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/[refs] b/[refs] index ea7f476a004a..2d97e0d90952 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: ee498ed730283e9cdfc8913f12b90a2246f1a8cc +refs/heads/master: f57e88a8d83de8d844b57e16b84d2f762fe9f092 diff --git a/trunk/drivers/char/mem.c b/trunk/drivers/char/mem.c index 91dd669273e0..29c3b631445a 100644 --- a/trunk/drivers/char/mem.c +++ b/trunk/drivers/char/mem.c @@ -591,7 +591,7 @@ static inline size_t read_zero_pagealigned(char __user * buf, size_t size) if (vma->vm_start > addr || (vma->vm_flags & VM_WRITE) == 0) goto out_up; - if (vma->vm_flags & (VM_SHARED | VM_HUGETLB)) + if (vma->vm_flags & (VM_SHARED | VM_HUGETLB | VM_UNPAGED)) break; count = vma->vm_end - addr; if (count > size) diff --git a/trunk/mm/memory.c b/trunk/mm/memory.c index 3666a4c6dd22..d1f46f4e4c8a 100644 --- a/trunk/mm/memory.c +++ b/trunk/mm/memory.c @@ -1812,7 +1812,16 @@ static int do_anonymous_page(struct mm_struct *mm, struct vm_area_struct *vma, spinlock_t *ptl; pte_t entry; - if (write_access) { + /* + * A VM_UNPAGED vma will normally be filled with present ptes + * by remap_pfn_range, and never arrive here; but it might have + * holes, or if !VM_DONTEXPAND, mremap might have expanded it. + * It's weird enough handling anon pages in unpaged vmas, we do + * not want to worry about ZERO_PAGEs too (it may or may not + * matter if their counts wrap): just give them anon pages. + */ + + if (write_access || (vma->vm_flags & VM_UNPAGED)) { /* Allocate our own private page. */ pte_unmap(page_table); @@ -1887,6 +1896,7 @@ static int do_no_page(struct mm_struct *mm, struct vm_area_struct *vma, int anon = 0; pte_unmap(page_table); + BUG_ON(vma->vm_flags & VM_UNPAGED); if (vma->vm_file) { mapping = vma->vm_file->f_mapping; @@ -1962,7 +1972,7 @@ static int do_no_page(struct mm_struct *mm, struct vm_area_struct *vma, inc_mm_counter(mm, anon_rss); lru_cache_add_active(new_page); page_add_anon_rmap(new_page, vma, address); - } else if (!(vma->vm_flags & VM_UNPAGED)) { + } else { inc_mm_counter(mm, file_rss); page_add_file_rmap(new_page); }