Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 43941
b: refs/heads/master
c: 5fcf7bb
h: refs/heads/master
i:
  43939: 18492c2
v: v3
  • Loading branch information
Hugh Dickins authored and Linus Torvalds committed Dec 10, 2006
1 parent abdac7c commit 75448e7
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 16 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 347a00fb4ad2200f8f8331f8b366b1d84eff577d
refs/heads/master: 5fcf7bb73f66cc1c4ad90788b0f367c4d6852b75
12 changes: 8 additions & 4 deletions trunk/drivers/char/mem.c
Original file line number Diff line number Diff line change
Expand Up @@ -646,7 +646,8 @@ static inline size_t read_zero_pagealigned(char __user * buf, size_t size)
count = size;

zap_page_range(vma, addr, count, NULL);
zeromap_page_range(vma, addr, count, PAGE_COPY);
if (zeromap_page_range(vma, addr, count, PAGE_COPY))
break;

size -= count;
buf += count;
Expand Down Expand Up @@ -713,11 +714,14 @@ static ssize_t read_zero(struct file * file, char __user * buf,

static int mmap_zero(struct file * file, struct vm_area_struct * vma)
{
int err;

if (vma->vm_flags & VM_SHARED)
return shmem_zero_setup(vma);
if (zeromap_page_range(vma, vma->vm_start, vma->vm_end - vma->vm_start, vma->vm_page_prot))
return -EAGAIN;
return 0;
err = zeromap_page_range(vma, vma->vm_start,
vma->vm_end - vma->vm_start, vma->vm_page_prot);
BUG_ON(err == -EEXIST);
return err;
}
#else /* CONFIG_MMU */
static ssize_t read_zero(struct file * file, char * buf,
Expand Down
32 changes: 21 additions & 11 deletions trunk/mm/memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -1110,57 +1110,67 @@ static int zeromap_pte_range(struct mm_struct *mm, pmd_t *pmd,
{
pte_t *pte;
spinlock_t *ptl;
int err = 0;

pte = pte_alloc_map_lock(mm, pmd, addr, &ptl);
if (!pte)
return -ENOMEM;
return -EAGAIN;
arch_enter_lazy_mmu_mode();
do {
struct page *page = ZERO_PAGE(addr);
pte_t zero_pte = pte_wrprotect(mk_pte(page, prot));

if (unlikely(!pte_none(*pte))) {
err = -EEXIST;
pte++;
break;
}
page_cache_get(page);
page_add_file_rmap(page);
inc_mm_counter(mm, file_rss);
BUG_ON(!pte_none(*pte));
set_pte_at(mm, addr, pte, zero_pte);
} while (pte++, addr += PAGE_SIZE, addr != end);
arch_leave_lazy_mmu_mode();
pte_unmap_unlock(pte - 1, ptl);
return 0;
return err;
}

static inline int zeromap_pmd_range(struct mm_struct *mm, pud_t *pud,
unsigned long addr, unsigned long end, pgprot_t prot)
{
pmd_t *pmd;
unsigned long next;
int err;

pmd = pmd_alloc(mm, pud, addr);
if (!pmd)
return -ENOMEM;
return -EAGAIN;
do {
next = pmd_addr_end(addr, end);
if (zeromap_pte_range(mm, pmd, addr, next, prot))
return -ENOMEM;
err = zeromap_pte_range(mm, pmd, addr, next, prot);
if (err)
break;
} while (pmd++, addr = next, addr != end);
return 0;
return err;
}

static inline int zeromap_pud_range(struct mm_struct *mm, pgd_t *pgd,
unsigned long addr, unsigned long end, pgprot_t prot)
{
pud_t *pud;
unsigned long next;
int err;

pud = pud_alloc(mm, pgd, addr);
if (!pud)
return -ENOMEM;
return -EAGAIN;
do {
next = pud_addr_end(addr, end);
if (zeromap_pmd_range(mm, pud, addr, next, prot))
return -ENOMEM;
err = zeromap_pmd_range(mm, pud, addr, next, prot);
if (err)
break;
} while (pud++, addr = next, addr != end);
return 0;
return err;
}

int zeromap_page_range(struct vm_area_struct *vma,
Expand Down

0 comments on commit 75448e7

Please sign in to comment.