Index: generic/src/ipc/ipc.c
===================================================================
--- generic/src/ipc/ipc.c	(revision 7c7aae1655a7653ed95980918529a6c78e15b376)
+++ generic/src/ipc/ipc.c	(revision 9055bd1e382317fb80de95de7307da53453a4289)
@@ -323,4 +323,7 @@
 		list_append(&request->list, &box->dispatched_calls);
 	} else {
+		/* This can happen regularly after ipc_cleanup, remove
+		 * the warning in the future when the IPC is
+		 * more debugged */
 		printf("WARNING: Spurious IPC wakeup.\n");
 		spinlock_unlock(&box->lock);
@@ -340,4 +343,18 @@
 }
 
+/** Answer all calls from list with EHANGUP msg */
+static void ipc_cleanup_call_list(link_t *lst)
+{
+	call_t *call;
+
+	while (!list_empty(lst)) {
+		call = list_get_instance(lst->next, call_t, list);
+		list_remove(&call->list);
+
+		IPC_SET_RETVAL(call->data, EHANGUP);
+		_ipc_answer_free_call(call);
+	}
+}
+
 /** Cleans up all IPC communication of the given task
  *
@@ -347,13 +364,44 @@
 {
 	int i;
-
+	call_t *call;
+	phone_t *phone;
+	
 	/* Disconnect all our phones ('ipc_phone_hangup') */
 	for (i=0;i < IPC_MAX_PHONES; i++)
 		ipc_phone_hangup(&task->phones[i]);
 
-	/* Disconnect all phones connected to answerbox */
+	/* Disconnect all phones connected to our answerbox */
+restart_phones:
+	spinlock_lock(&task->answerbox.lock);
+	while (!list_empty(&task->answerbox.connected_phones)) {
+		phone = list_get_instance(task->answerbox.connected_phones.next,
+					  phone_t,
+					  list);
+		if (! spinlock_trylock(&phone->lock)) {
+			spinlock_unlock(&task->answerbox.lock);
+			goto restart_phones;
+		}
+		
+		/* Disconnect phone */
+		phone->callee = NULL;
+		list_remove(&phone->list);
+
+		spinlock_unlock(&phone->lock);
+	}
 
 	/* Answer all messages in 'calls' and 'dispatched_calls' queues */
+	spinlock_lock(&task->answerbox.lock);
+	ipc_cleanup_call_list(&task->answerbox.dispatched_calls);
+	ipc_cleanup_call_list(&task->answerbox.calls);
+	spinlock_unlock(&task->answerbox.lock);
 	
 	/* Wait for all async answers to arrive */
-}
+	while (atomic_get(&task->active_calls)) {
+		call = ipc_wait_for_call(&task->answerbox, 0);
+		ASSERT(call->flags & IPC_CALL_ANSWERED);
+		ASSERT(! (call->flags & IPC_CALL_STATIC_ALLOC));
+		
+		atomic_dec(&task->active_calls);
+		ipc_call_free(call);
+	}
+}
Index: generic/src/ipc/ipcrsc.c
===================================================================
--- generic/src/ipc/ipcrsc.c	(revision 7c7aae1655a7653ed95980918529a6c78e15b376)
+++ generic/src/ipc/ipcrsc.c	(revision 9055bd1e382317fb80de95de7307da53453a4289)
@@ -130,11 +130,23 @@
 /** Find call_t * in call table according to callid
  *
+ * TODO: Some speedup (hash table?)
  * @return NULL on not found, otherwise pointer to call structure
  */
 call_t * get_call(__native callid)
 {
-	/* TODO: Traverse list of dispatched calls and find one */
-	/* TODO: locking of call, ripping it from dispatched calls etc.  */
-	return (call_t *) callid;
+	link_t *lst;
+	call_t *call, *result = NULL;
+
+	spinlock_lock(&TASK->answerbox.lock);
+	for (lst = TASK->answerbox.dispatched_calls.next;
+	     lst != &TASK->answerbox.dispatched_calls; lst = lst->next) {
+		call = list_get_instance(lst, call_t, list);
+		if ((__native)call == callid) {
+			result = call;
+			break;
+		}
+	}
+	spinlock_unlock(&TASK->answerbox.lock);
+	return result;
 }
 
Index: generic/src/ipc/sysipc.c
===================================================================
--- generic/src/ipc/sysipc.c	(revision 7c7aae1655a7653ed95980918529a6c78e15b376)
+++ generic/src/ipc/sysipc.c	(revision 9055bd1e382317fb80de95de7307da53453a4289)
@@ -93,6 +93,15 @@
 
 	if (IPC_GET_RETVAL(answer->data) == EHANGUP) {
-		/* Atomic operation */
-		answer->data.phone->callee = NULL;
+		/* In case of forward, hangup the forwared phone,
+		 * not the originator
+		 */
+		spinlock_lock(&answer->data.phone->lock);
+		spinlock_lock(&TASK->answerbox.lock);
+		if (answer->data.phone->callee) {
+			list_remove(&answer->data.phone->list);
+			answer->data.phone->callee = 0;
+		}
+		spinlock_unlock(&TASK->answerbox.lock);
+		spinlock_unlock(&answer->data.phone->lock);
 	}
 
