Handle failures in the middle of alloc_kumem_chunk correctly

Christian Ehrhardt Christian_Ehrhardt at genua.de
Tue May 3 13:57:21 CEST 2011


Task::alloc_ku_mem_chunk() calls free_ku_mem_chunk in case of errors.
However, free_ku_mem_chunk() will try to unmap the entire area which is
wrong when called from Task::alloc_ku_mem_chunk().

diff --git a/src/kernel/fiasco/src/kern/task.cpp b/src/kernel/fiasco/src/kern/task.cpp
index 35fef8c..4537450 100644
--- a/src/kernel/fiasco/src/kern/task.cpp
+++ b/src/kernel/fiasco/src/kern/task.cpp
@@ -146,18 +146,18 @@ Task::alloc_ku_mem_chunk(User<void>::Ptr u_addr, unsigned size, void **k_addr)
 	{
 	case Mem_space::Insert_ok: break;
 	case Mem_space::Insert_err_nomem:
-	  free_ku_mem_chunk(p, u_addr, size);
+	  free_ku_mem_chunk(p, u_addr, size, i);
 	  return -L4_err::ENomem;
 
 	case Mem_space::Insert_err_exists:
-	  free_ku_mem_chunk(p, u_addr, size);
+	  free_ku_mem_chunk(p, u_addr, size, i);
 	  return -L4_err::EExists;
 
 	default:
 	  printf("UTCB mapping failed: va=%p, ph=%p, res=%d\n",
 	      (void*)user_va, (void*)kern_va, res);
 	  kdb_ke("BUG in utcb allocation");
-	  free_ku_mem_chunk(p, u_addr, size);
+	  free_ku_mem_chunk(p, u_addr, size, i);
 	  return 0;
 	}
     }
@@ -208,13 +208,14 @@ PRIVATE inline NOEXPORT
 void
 Task::free_ku_mem(Ku_mem *m)
 {
-  free_ku_mem_chunk(m->k_addr, m->u_addr, m->size);
+  free_ku_mem_chunk(m->k_addr, m->u_addr, m->size, m->size);
   m->free(ram_quota());
 }
 
 PRIVATE
 void
-Task::free_ku_mem_chunk(void *k_addr, User<void>::Ptr u_addr, unsigned size)
+Task::free_ku_mem_chunk(void *k_addr, User<void>::Ptr u_addr, unsigned size,
+  unsigned mapped_size)
 {
 
   Mapped_allocator * const alloc = Mapped_allocator::allocator();
@@ -226,7 +227,7 @@ Task::free_ku_mem_chunk(void *k_addr, User<void>::Ptr u_addr, unsigned size)
   if (size >= Config::SUPERPAGE_SIZE)
     page_size = Config::SUPERPAGE_SIZE;
 
-  for (unsigned long i = 0; i < size; i += page_size)
+  for (unsigned long i = 0; i < mapped_size; i += page_size)
     {
       Address user_va = (Address)u_addr.get() + i;
       mem_space()->v_delete(Mem_space::Addr(user_va),




More information about the l4-hackers mailing list