fixed vma_add() when area is already in use
This commit is contained in:
parent
96e7a99b38
commit
2f903deebd
1 changed files with 14 additions and 11 deletions
25
mm/vma.c
25
mm/vma.c
|
@ -190,8 +190,6 @@ int vma_add(size_t start, size_t end, uint32_t flags)
|
||||||
spinlock_t* lock;
|
spinlock_t* lock;
|
||||||
vma_t** list;
|
vma_t** list;
|
||||||
|
|
||||||
kprintf("vma_add(0x%lx, 0x%lx, 0x%x)\n", start, end, flags);
|
|
||||||
|
|
||||||
if (BUILTIN_EXPECT(start >= end, 0))
|
if (BUILTIN_EXPECT(start >= end, 0))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
@ -217,16 +215,20 @@ int vma_add(size_t start, size_t end, uint32_t flags)
|
||||||
// search gap
|
// search gap
|
||||||
vma_t* pred = NULL;
|
vma_t* pred = NULL;
|
||||||
vma_t* succ = *list;
|
vma_t* succ = *list;
|
||||||
do {
|
|
||||||
|
while (pred || succ) {
|
||||||
if ((!pred || pred->end <= start) &&
|
if ((!pred || pred->end <= start) &&
|
||||||
(!succ || succ->start >= end))
|
(!succ || succ->start >= end))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
pred = succ;
|
pred = succ;
|
||||||
succ = succ->next;
|
succ = (succ) ? succ->next : NULL;
|
||||||
} while (pred || succ);
|
}
|
||||||
|
|
||||||
// TODO: check bounds
|
if (BUILTIN_EXPECT(*list && !pred && !succ, 0)) {
|
||||||
|
spinlock_unlock(lock);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
// insert new VMA
|
// insert new VMA
|
||||||
vma_t* new = kmalloc(sizeof(vma_t));
|
vma_t* new = kmalloc(sizeof(vma_t));
|
||||||
|
@ -258,13 +260,14 @@ int copy_vma_list(task_t* task)
|
||||||
task_t* parent_task = per_core(current_task);
|
task_t* parent_task = per_core(current_task);
|
||||||
|
|
||||||
spinlock_init(&task->vma_lock);
|
spinlock_init(&task->vma_lock);
|
||||||
|
|
||||||
spinlock_lock(&parent_task->vma_lock);
|
spinlock_lock(&parent_task->vma_lock);
|
||||||
spinlock_lock(&task->vma_lock);
|
spinlock_lock(&task->vma_lock);
|
||||||
|
|
||||||
vma_t* last = NULL;
|
vma_t* last = NULL;
|
||||||
vma_t* parent = parent_task->vma_list;
|
|
||||||
|
|
||||||
while (parent) {
|
vma_t* parent;
|
||||||
|
for (parent=parent_task->vma_list; parent; parent=parent->next) {
|
||||||
vma_t *new = kmalloc(sizeof(vma_t));
|
vma_t *new = kmalloc(sizeof(vma_t));
|
||||||
if (BUILTIN_EXPECT(!new, 0)) {
|
if (BUILTIN_EXPECT(!new, 0)) {
|
||||||
spinlock_unlock(&task->vma_lock);
|
spinlock_unlock(&task->vma_lock);
|
||||||
|
@ -283,9 +286,11 @@ int copy_vma_list(task_t* task)
|
||||||
task->vma_list = new;
|
task->vma_list = new;
|
||||||
|
|
||||||
last = new;
|
last = new;
|
||||||
parent = parent->next;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
spinlock_unlock(&task->vma_lock);
|
||||||
|
spinlock_unlock(&parent_task->vma_lock);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -294,8 +299,6 @@ int drop_vma_list()
|
||||||
task_t* task = per_core(current_task);
|
task_t* task = per_core(current_task);
|
||||||
vma_t* vma;
|
vma_t* vma;
|
||||||
|
|
||||||
kprintf("drop_vma_list: task = %u\n", task->id); // TODO: remove
|
|
||||||
|
|
||||||
spinlock_lock(&task->vma_lock);
|
spinlock_lock(&task->vma_lock);
|
||||||
|
|
||||||
while ((vma = task->vma_list)) {
|
while ((vma = task->vma_list)) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue