fixed vma_add() when area is already in use

This commit is contained in:
Steffen Vogel 2014-02-03 09:58:32 +01:00
parent 96e7a99b38
commit 2f903deebd

View file

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