Index: kernel/generic/include/ipc/ipc.h
===================================================================
--- kernel/generic/include/ipc/ipc.h	(revision b1e6269e0d19f6fc32213d11e1344dccf38f6bf7)
+++ kernel/generic/include/ipc/ipc.h	(revision 20282ef3b461efd28e3f237a408f7f5a3021ab1a)
@@ -131,4 +131,7 @@
 	 */
 	bool forget;
+
+	/** True if the call is in the active list. */
+	bool active;
 	
 	/**
Index: kernel/generic/src/ipc/ipc.c
===================================================================
--- kernel/generic/src/ipc/ipc.c	(revision b1e6269e0d19f6fc32213d11e1344dccf38f6bf7)
+++ kernel/generic/src/ipc/ipc.c	(revision 20282ef3b461efd28e3f237a408f7f5a3021ab1a)
@@ -73,4 +73,5 @@
 	memsetb(call, sizeof(*call), 0);
 	spinlock_initialize(&call->forget_lock, "forget_lock");
+	call->active = false;
 	call->forget = false;
 	call->sender = TASK;
@@ -201,13 +202,13 @@
 
 		/*
-		 * Remove the call from the sender's active call list.
-		 * We enforce this locking order so that any potential
-		 * concurrently executing forget operation is forced to
-		 * release its active_calls_lock and lose the race to
-		 * forget this soon to be answered call. 
+		 * If the call is still active, i.e. it was answered
+		 * in a non-standard way, remove the call from the
+		 * sender's active call list.
 		 */
-		spinlock_lock(&call->sender->active_calls_lock);
-		list_remove(&call->ta_link);
-		spinlock_unlock(&call->sender->active_calls_lock);
+		if (call->active) {
+			spinlock_lock(&call->sender->active_calls_lock);
+			list_remove(&call->ta_link);
+			spinlock_unlock(&call->sender->active_calls_lock);
+		}
 	}
 	spinlock_unlock(&call->forget_lock);
@@ -291,4 +292,6 @@
 	if (!(call->flags & IPC_CALL_FORWARDED)) {
 		atomic_inc(&phone->active_calls);
+
+		call->active = true;
 
 		spinlock_lock(&TASK->active_calls_lock);
@@ -594,6 +597,7 @@
 	if (!spinlock_trylock(&call->forget_lock)) {
 		/*
-		 * Avoid deadlock and let _ipc_answer_free_call() win the race
-		 * to answer the first call on the list.
+		 * Avoid deadlock and let async_answer() or
+		 *  _ipc_answer_free_call() win the race to dequeue the first
+		 * call on the list.
 		 */
 		spinlock_unlock(&TASK->active_calls_lock);	
Index: kernel/generic/src/ipc/sysipc.c
===================================================================
--- kernel/generic/src/ipc/sysipc.c	(revision b1e6269e0d19f6fc32213d11e1344dccf38f6bf7)
+++ kernel/generic/src/ipc/sysipc.c	(revision 20282ef3b461efd28e3f237a408f7f5a3021ab1a)
@@ -175,4 +175,24 @@
 		return rc;
 	} else {
+		ASSERT(answer->active);
+
+		/*
+		 * Mark the call as inactive to prevent _ipc_answer_free_call()
+		 * from attempting to remove the call from the active list
+		 * itself.
+		 */
+		answer->active = false;
+
+		/*
+		 * Remove the call from the sender's active call list.
+		 * We enforce this locking order so that any potential
+		 * concurrently executing forget operation is forced to
+		 * release its active_calls_lock and lose the race to
+		 * forget this soon to be answered call. 
+		 */
+		spinlock_lock(&answer->sender->active_calls_lock);
+		list_remove(&answer->ta_link);
+		spinlock_unlock(&answer->sender->active_calls_lock);
+
 		/*
 		 * Hold the sender task so that it cannot suddenly disappear
