mremap: Fix to work correctly when old_page is large_page
Change-Id: I5a589383644a8098d910e49cd7ade6df325e0366 Refs: #1383
This commit is contained in:
committed by
Masamichi Takagi
parent
4bbdee395e
commit
41ea9d16c4
@ -908,10 +908,19 @@ int split_process_memory_range(struct process_vm *vm, struct vm_range *range,
|
||||
{
|
||||
int error;
|
||||
struct vm_range *newrange = NULL;
|
||||
unsigned long page_mask;
|
||||
|
||||
dkprintf("split_process_memory_range(%p,%lx-%lx,%lx,%p)\n",
|
||||
vm, range->start, range->end, addr, splitp);
|
||||
|
||||
if (range->pgshift != 0) {
|
||||
page_mask = (1 << range->pgshift) - 1;
|
||||
if (addr & page_mask) {
|
||||
/* split addr is not aligned */
|
||||
range->pgshift = 0;
|
||||
}
|
||||
}
|
||||
|
||||
error = ihk_mc_pt_split(vm->address_space->page_table, vm, (void *)addr);
|
||||
if (error) {
|
||||
ekprintf("split_process_memory_range:"
|
||||
|
||||
@ -8498,7 +8498,7 @@ SYSCALL_DECLARE(mremap)
|
||||
error = add_process_memory_range(thread->vm, newstart, newend, -1,
|
||||
range->flag, range->memobj,
|
||||
range->objoff + (oldstart - range->start),
|
||||
range->pgshift, NULL, NULL);
|
||||
0, NULL, NULL);
|
||||
if (error) {
|
||||
ekprintf("sys_mremap(%#lx,%#lx,%#lx,%#x,%#lx):"
|
||||
"add failed. %d\n",
|
||||
@ -8518,6 +8518,29 @@ SYSCALL_DECLARE(mremap)
|
||||
if (oldsize > 0) {
|
||||
size = (oldsize < newsize)? oldsize: newsize;
|
||||
ihk_mc_spinlock_lock_noirq(&vm->page_table_lock);
|
||||
if (range->start != oldstart) {
|
||||
error = split_process_memory_range(vm,
|
||||
range, oldstart, &range);
|
||||
if (error) {
|
||||
ekprintf("sys_mremap(%#lx,%#lx,%#lx,%#x,%#lx):"
|
||||
"split range failed. %d\n",
|
||||
oldaddr, oldsize0, newsize0,
|
||||
flags, newaddr, error);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
if (range->end != oldstart + size) {
|
||||
error = split_process_memory_range(vm,
|
||||
range, oldstart + size, NULL);
|
||||
if (error) {
|
||||
ekprintf("sys_mremap(%#lx,%#lx,%#lx,%#x,%#lx):"
|
||||
"split range failed. %d\n",
|
||||
oldaddr, oldsize0, newsize0,
|
||||
flags, newaddr, error);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
error = move_pte_range(vm->address_space->page_table, vm,
|
||||
(void *)oldstart, (void *)newstart,
|
||||
size, range);
|
||||
|
||||
Reference in New Issue
Block a user