asmlinkage unsigned long ia64_mremap (unsigned long addr, unsigned long old_len, unsigned long new_len, unsigned long flags, unsigned long new_addr) { addr = sys_mremap(addr, old_len, new_len, flags, new_addr); if (!IS_ERR((void *) addr)) force_successful_syscall_return(); return addr; }
static int vdso_remap(char *who, unsigned long from, unsigned long to, size_t size) { unsigned long addr; pr_debug("Remap %s %lx -> %lx\n", who, from, to); addr = sys_mremap(from, size, size, MREMAP_MAYMOVE | MREMAP_FIXED, to); if (addr != to) { pr_err("Unable to remap %lx -> %lx %lx\n", from, to, addr); return -1; } return 0; }
static int vma_remap(unsigned long src, unsigned long dst, unsigned long len) { unsigned long guard = 0, tmp; pr_info("Remap %lx->%lx len %lx\n", src, dst, len); if (src - dst < len) guard = dst; else if (dst - src < len) guard = dst + len - PAGE_SIZE; if (src == dst) return 0; if (guard != 0) { /* * mremap() returns an error if a target and source vma-s are * overlapped. In this case the source vma are remapped in * a temporary place and then remapped to the target address. * Here is one hack to find non-ovelapped temporary place. * * 1. initial placement. We need to move src -> tgt. * | |+++++src+++++| * |-----tgt-----| | * * 2. map a guard page at the non-ovelapped border of a target vma. * | |+++++src+++++| * |G|----tgt----| | * * 3. remap src to any other place. * G prevents src from being remaped on tgt again * | |-------------| -> |+++++src+++++| * |G|---tgt-----| | * * 4. remap src to tgt, no overlapping any longer * |+++++src+++++| <---- |-------------| * |G|---tgt-----| | */ unsigned long addr; /* Map guard page (step 2) */ tmp = sys_mmap((void *) guard, PAGE_SIZE, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); if (tmp != guard) { pr_err("Unable to map a guard page %lx (%lx)\n", guard, tmp); return -1; } /* Move src to non-overlapping place (step 3) */ addr = sys_mmap(NULL, len, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); if (addr == (unsigned long) MAP_FAILED) { pr_err("Unable to reserve memory (%lx)\n", addr); return -1; } tmp = sys_mremap(src, len, len, MREMAP_MAYMOVE | MREMAP_FIXED, addr); if (tmp != addr) { pr_err("Unable to remap %lx -> %lx (%lx)\n", src, addr, tmp); return -1; } src = addr; } tmp = sys_mremap(src, len, len, MREMAP_MAYMOVE | MREMAP_FIXED, dst); if (tmp != dst) { pr_err("Unable to remap %lx -> %lx\n", src, dst); return -1; } return 0; }