unsigned long end, struct mm_walk *walk)
{
const struct mm_walk_ops *ops = walk->ops;
- int err = 0;
for (;;) {
- err = ops->pte_entry(pte, addr, addr + PAGE_SIZE, walk);
+ int err = ops->pte_entry(pte, addr, addr + PAGE_SIZE, walk);
if (err)
- break;
+ return err;
if (addr >= end - PAGE_SIZE)
break;
addr += PAGE_SIZE;
pte++;
}
- return err;
+ return 0;
}
static int walk_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
struct mm_walk *walk)
{
pte_t *pte;
- int err = 0;
+ int err;
spinlock_t *ptl;
if (walk->no_vma) {
static int walk_hugepd_range(hugepd_t *phpd, unsigned long addr,
unsigned long end, struct mm_walk *walk, int pdshift)
{
- int err = 0;
const struct mm_walk_ops *ops = walk->ops;
int shift = hugepd_shift(*phpd);
int page_size = 1 << shift;
for (;;) {
pte_t *pte;
+ int err;
spin_lock(&walk->mm->page_table_lock);
pte = hugepte_offset(*phpd, addr, pdshift);
spin_unlock(&walk->mm->page_table_lock);
if (err)
- break;
+ return err;
if (addr >= end - page_size)
break;
addr += page_size;
}
- return err;
+ return 0;
}
#else
static int walk_hugepd_range(hugepd_t *phpd, unsigned long addr,
pmd_t *pmd;
unsigned long next;
const struct mm_walk_ops *ops = walk->ops;
- int err = 0;
int depth = real_depth(3);
pmd = pmd_offset(pud, addr);
do {
-again:
+ int err;
+
+ again:
next = pmd_addr_end(addr, end);
if (pmd_none(*pmd) || (!walk->vma && !walk->no_vma)) {
- if (ops->pte_hole)
+ if (ops->pte_hole) {
err = ops->pte_hole(addr, next, depth, walk);
- if (err)
- break;
+ if (err)
+ return err;
+ }
continue;
}
* This implies that each ->pmd_entry() handler
* needs to know about pmd_trans_huge() pmds
*/
- if (ops->pmd_entry)
+ if (ops->pmd_entry) {
err = ops->pmd_entry(pmd, addr, next, walk);
- if (err)
- break;
+ if (err)
+ return err;
+ }
if (walk->action == ACTION_AGAIN)
goto again;
else
err = walk_pte_range(pmd, addr, next, walk);
if (err)
- break;
+ return err;
} while (pmd++, addr = next, addr != end);
- return err;
+ return 0;
}
static int walk_pud_range(p4d_t *p4d, unsigned long addr, unsigned long end,
pud_t *pud;
unsigned long next;
const struct mm_walk_ops *ops = walk->ops;
- int err = 0;
int depth = real_depth(2);
pud = pud_offset(p4d, addr);
do {
+ int err;
+
again:
next = pud_addr_end(addr, end);
if (pud_none(*pud) || (!walk->vma && !walk->no_vma)) {
- if (ops->pte_hole)
+ if (ops->pte_hole) {
err = ops->pte_hole(addr, next, depth, walk);
- if (err)
- break;
+ if (err)
+ return err;
+ }
continue;
}
walk->action = ACTION_SUBTREE;
- if (ops->pud_entry)
+ if (ops->pud_entry) {
err = ops->pud_entry(pud, addr, next, walk);
- if (err)
- break;
+ if (err)
+ return err;
+ }
if (walk->action == ACTION_AGAIN)
goto again;
else
err = walk_pmd_range(pud, addr, next, walk);
if (err)
- break;
+ return err;
} while (pud++, addr = next, addr != end);
- return err;
+ return 0;
}
static int walk_p4d_range(pgd_t *pgd, unsigned long addr, unsigned long end,
p4d_t *p4d;
unsigned long next;
const struct mm_walk_ops *ops = walk->ops;
- int err = 0;
int depth = real_depth(1);
p4d = p4d_offset(pgd, addr);
do {
+ int err;
+
next = p4d_addr_end(addr, end);
if (p4d_none_or_clear_bad(p4d)) {
- if (ops->pte_hole)
+ if (ops->pte_hole) {
err = ops->pte_hole(addr, next, depth, walk);
- if (err)
- break;
+ if (err)
+ return err;
+ }
continue;
}
if (ops->p4d_entry) {
err = ops->p4d_entry(p4d, addr, next, walk);
if (err)
- break;
+ return err;
}
if (is_hugepd(__hugepd(p4d_val(*p4d))))
err = walk_hugepd_range((hugepd_t *)p4d, addr, next, walk, P4D_SHIFT);
else if (ops->pud_entry || ops->pmd_entry || ops->pte_entry)
err = walk_pud_range(p4d, addr, next, walk);
if (err)
- break;
+ return err;
} while (p4d++, addr = next, addr != end);
- return err;
+ return 0;
}
static int walk_pgd_range(unsigned long addr, unsigned long end,
pgd_t *pgd;
unsigned long next;
const struct mm_walk_ops *ops = walk->ops;
- int err = 0;
if (walk->pgd)
pgd = walk->pgd + pgd_index(addr);
else
pgd = pgd_offset(walk->mm, addr);
do {
+ int err;
+
next = pgd_addr_end(addr, end);
if (pgd_none_or_clear_bad(pgd)) {
- if (ops->pte_hole)
+ if (ops->pte_hole) {
err = ops->pte_hole(addr, next, 0, walk);
- if (err)
- break;
+ if (err)
+ return err;
+ }
continue;
}
if (ops->pgd_entry) {
err = ops->pgd_entry(pgd, addr, next, walk);
if (err)
- break;
+ return err;
}
if (is_hugepd(__hugepd(pgd_val(*pgd))))
err = walk_hugepd_range((hugepd_t *)pgd, addr, next, walk, PGDIR_SHIFT);
else if (ops->p4d_entry || ops->pud_entry || ops->pmd_entry || ops->pte_entry)
err = walk_p4d_range(pgd, addr, next, walk);
if (err)
- break;
+ return err;
} while (pgd++, addr = next, addr != end);
- return err;
+ return 0;
}
#ifdef CONFIG_HUGETLB_PAGE
unsigned long sz = huge_page_size(h);
pte_t *pte;
const struct mm_walk_ops *ops = walk->ops;
- int err = 0;
do {
+ int err;
+
next = hugetlb_entry_end(h, addr, end);
pte = huge_pte_offset(walk->mm, addr & hmask, sz);
err = ops->pte_hole(addr, next, -1, walk);
if (err)
- break;
+ return err;
} while (addr = next, addr != end);
- return err;
+ return 0;
}
#else /* CONFIG_HUGETLB_PAGE */
* vma(VM_PFNMAP).
*/
if (vma->vm_flags & VM_PFNMAP) {
- int err = 1;
- if (ops->pte_hole)
- err = ops->pte_hole(start, end, -1, walk);
- return err ? err : 1;
+ if (ops->pte_hole) {
+ int err = ops->pte_hole(start, end, -1, walk);
+
+ return err ? err : 1;
+ }
+
+ return 1;
}
return 0;
}
unsigned long end, const struct mm_walk_ops *ops,
void *private)
{
- int err = 0;
unsigned long next;
struct vm_area_struct *vma;
struct mm_walk walk = {
vma = find_vma(walk.mm, start);
do {
+ int err;
+
if (!vma) { /* after the last vma */
walk.vma = NULL;
next = end;
* controlling the pagewalk, so should never
* be passed to the callers.
*/
- err = 0;
continue;
}
if (err < 0)
- break;
+ return err;
}
- if (walk.vma || walk.ops->pte_hole)
+ if (walk.vma || walk.ops->pte_hole) {
err = __walk_page_range(start, next, &walk);
- if (err)
- break;
+ if (err)
+ return err;
+ }
} while (start = next, start < end);
- return err;
+ return 0;
}
/*
struct vm_area_struct *vma;
pgoff_t vba, vea, cba, cea;
unsigned long start_addr, end_addr;
- int err = 0;
lockdep_assert_held(&mapping->i_mmap_rwsem);
vma_interval_tree_foreach(vma, &mapping->i_mmap, first_index,
first_index + nr - 1) {
+ int err;
+
/* Clip to the vma */
vba = vma->vm_pgoff;
vea = vba + vma_pages(vma);
walk.mm = vma->vm_mm;
err = walk_page_test(vma->vm_start, vma->vm_end, &walk);
- if (err > 0) {
- err = 0;
- break;
- } else if (err < 0)
- break;
+ if (err > 0)
+ return 0;
+ else if (err < 0)
+ return err;
err = __walk_page_range(start_addr, end_addr, &walk);
if (err)
- break;
+ return err;
}
- return err;
+ return 0;
}