mremap: Fix to work correctly when old_page is large_page

Change-Id: I5a589383644a8098d910e49cd7ade6df325e0366
Refs: #1383
This commit is contained in:
Ken Sato
2020-01-30 14:11:22 +09:00
committed by Masamichi Takagi
parent 4bbdee395e
commit 41ea9d16c4
8 changed files with 344 additions and 1 deletions

View File

@ -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:"

View File

@ -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);