diff options
| author | 2014-11-19 21:32:12 +1100 | |
|---|---|---|
| committer | 2014-11-19 21:32:12 +1100 | |
| commit | b10778a00d40b3d9fdaaf5891e802794781ff71c (patch) | |
| tree | 6ba4cbac86eecedc3f30650e7f764ecf00c83898 /fs/proc/task_mmu.c | |
| parent | integrity: do zero padding of the key id (diff) | |
| parent | Linux 3.17 (diff) | |
| download | wireguard-linux-b10778a00d40b3d9fdaaf5891e802794781ff71c.tar.xz wireguard-linux-b10778a00d40b3d9fdaaf5891e802794781ff71c.zip | |
Merge commit 'v3.17' into next
Diffstat (limited to '')
| -rw-r--r-- | fs/proc/task_mmu.c | 34 | 
1 files changed, 29 insertions, 5 deletions
| diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index cfa63ee92c96..c34156888d70 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -925,15 +925,39 @@ static int pagemap_pte_hole(unsigned long start, unsigned long end,  				struct mm_walk *walk)  {  	struct pagemapread *pm = walk->private; -	unsigned long addr; +	unsigned long addr = start;  	int err = 0; -	pagemap_entry_t pme = make_pme(PM_NOT_PRESENT(pm->v2)); -	for (addr = start; addr < end; addr += PAGE_SIZE) { -		err = add_to_pagemap(addr, &pme, pm); -		if (err) +	while (addr < end) { +		struct vm_area_struct *vma = find_vma(walk->mm, addr); +		pagemap_entry_t pme = make_pme(PM_NOT_PRESENT(pm->v2)); +		/* End of address space hole, which we mark as non-present. */ +		unsigned long hole_end; + +		if (vma) +			hole_end = min(end, vma->vm_start); +		else +			hole_end = end; + +		for (; addr < hole_end; addr += PAGE_SIZE) { +			err = add_to_pagemap(addr, &pme, pm); +			if (err) +				goto out; +		} + +		if (!vma)  			break; + +		/* Addresses in the VMA. */ +		if (vma->vm_flags & VM_SOFTDIRTY) +			pme.pme |= PM_STATUS2(pm->v2, __PM_SOFT_DIRTY); +		for (; addr < min(end, vma->vm_end); addr += PAGE_SIZE) { +			err = add_to_pagemap(addr, &pme, pm); +			if (err) +				goto out; +		}  	} +out:  	return err;  } | 
