add remove_process_memory_range()
This commit is contained in:
@@ -98,6 +98,8 @@ void free_process_memory(struct process *proc);
|
||||
int add_process_memory_range(struct process *process,
|
||||
unsigned long start, unsigned long end,
|
||||
unsigned long phys, unsigned long flag);
|
||||
int remove_process_memory_range(
|
||||
struct process *process, unsigned long start, unsigned long end);
|
||||
int remove_process_region(struct process *proc,
|
||||
unsigned long start, unsigned long end);
|
||||
struct program_load_desc;
|
||||
|
||||
@@ -171,6 +171,96 @@ err:
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
int remove_process_memory_range(struct process *process, unsigned long start, unsigned long end)
|
||||
{
|
||||
struct process_vm * const vm = process->vm;
|
||||
struct vm_range *range;
|
||||
struct vm_range *next;
|
||||
int error;
|
||||
unsigned long freestart;
|
||||
unsigned long freephys;
|
||||
unsigned long freesize;
|
||||
struct vm_range *freerange;
|
||||
struct vm_range *newrange;
|
||||
|
||||
list_for_each_entry_safe(range, next, &vm->vm_range_list, list) {
|
||||
if ((range->end <= start) || (end <= range->start)) {
|
||||
/* no overlap */
|
||||
continue;
|
||||
}
|
||||
|
||||
error = 0;
|
||||
freerange = NULL;
|
||||
freesize = 0;
|
||||
|
||||
if (start <= range->start) {
|
||||
/* partial or whole delete from range->start */
|
||||
freestart = range->start;
|
||||
freephys = range->phys;
|
||||
freesize = end - range->start;
|
||||
|
||||
if (freesize >= (range->end - range->start)) {
|
||||
freesize = range->end - range->start;
|
||||
list_del(&range->list);
|
||||
freerange = range;
|
||||
}
|
||||
else {
|
||||
range->start += freesize;
|
||||
range->phys += freesize;
|
||||
}
|
||||
}
|
||||
else if (range->end <= end) {
|
||||
/* partial delete up to range->end */
|
||||
freestart = start;
|
||||
freephys = range->phys + (start - range->start);
|
||||
freesize = range->end - start;
|
||||
|
||||
range->end = start;
|
||||
}
|
||||
else {
|
||||
/* delete the middle part of the 'range' */
|
||||
freestart = start;
|
||||
freephys = range->phys + (start - range->start);
|
||||
freesize = end - start;
|
||||
|
||||
newrange = kmalloc(sizeof(struct vm_range), IHK_MC_AP_NOWAIT);
|
||||
if (!newrange) {
|
||||
kprintf("remove_process_memory_range:kmalloc failed\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
INIT_LIST_HEAD(&range->list);
|
||||
newrange->start = end;
|
||||
newrange->end = range->end;
|
||||
newrange->phys = range->phys + (end - range->start);
|
||||
newrange->flag = range->flag;
|
||||
list_add_tail(&newrange->list, &vm->vm_range_list);
|
||||
|
||||
range->end = start;
|
||||
}
|
||||
|
||||
if (freesize > 0) {
|
||||
error = remove_process_region(process, freestart, (freestart + freesize));
|
||||
if (error) {
|
||||
kprintf("remove_process_memory_range:remove_process_region failed: %d\n", error);
|
||||
/* through */
|
||||
}
|
||||
|
||||
if (!(range->flag & (VR_REMOTE | VR_IO_NOCACHE | VR_RESERVED))) {
|
||||
// XXX: need TLB shootdown?
|
||||
ihk_mc_free_pages(phys_to_virt(freephys), freesize>>PAGE_SHIFT);
|
||||
}
|
||||
}
|
||||
if (freerange != NULL) {
|
||||
ihk_mc_free(freerange);
|
||||
}
|
||||
if (error) {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int add_process_memory_range(struct process *process,
|
||||
unsigned long start, unsigned long end,
|
||||
unsigned long phys, unsigned long flag)
|
||||
|
||||
@@ -506,12 +506,16 @@ SYSCALL_DECLARE(mmap)
|
||||
SYSCALL_DECLARE(munmap)
|
||||
{
|
||||
unsigned long address, len;
|
||||
int error;
|
||||
|
||||
address = ihk_mc_syscall_arg0(ctx);
|
||||
len = ihk_mc_syscall_arg1(ctx);
|
||||
|
||||
return remove_process_region(cpu_local_var(current), address,
|
||||
address + len);
|
||||
ihk_mc_spinlock_lock_noirq(&cpu_local_var(current)->vm->memory_range_lock);
|
||||
error = remove_process_memory_range(cpu_local_var(current), address, address+len);
|
||||
ihk_mc_spinlock_unlock_noirq(&cpu_local_var(current)->vm->memory_range_lock);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
SYSCALL_DECLARE(mprotect)
|
||||
|
||||
Reference in New Issue
Block a user