static inline offset_t __npg_bk_op(offset_t start, offset_t end, offset_t upper, uint64_t attr, npg_op_t *op, uint8_t act) { offset_t addr; if(op->nxt) { offset_t start_up = __align_next(start, op->sz); bool_t diff_tbl = (pg_abs_idx(start, op->shf) != pg_abs_idx(end, op->shf)); if(__aligned(start, op->sz) && diff_tbl) { op->fnc[act](start, attr); addr = start_up; } else addr = __npg_bk_op(start, end, start_up, attr, op->nxt, act); } else addr = __align(start, op->sz); while(addr < min(__align(end, op->sz), upper)) { op->fnc[act](addr, attr); addr += op->sz; } return addr; }
int __vm_access_mem(vm_access_t *access) { offset_t vaddr, nxt; size_t psz, len; if(!access->len) return 1; if(!__paging()) return access->operator(access); vaddr = access->addr; len = access->len; while(len) { if(!__pg_walk(access->cr3, vaddr, &access->addr, &psz, 1)) { debug(VM_ACCESS, "#PF on vm access 0x%X sz 0x%X\n", vaddr, len); return 0; } nxt = __align_next(vaddr, psz); access->len = min(len, (nxt - vaddr)); if(!access->operator(access)) return 0; len -= access->len; vaddr = nxt; } return 1; }