Index: kernel/generic/src/smp/smp_call.c
===================================================================
--- kernel/generic/src/smp/smp_call.c	(revision 1f8c11fb8cdd200759b495ae526cf6d894d543f0)
+++ kernel/generic/src/smp/smp_call.c	(revision d70fc74015f71b1a86ddbe532d59d15b791514c5)
@@ -54,10 +54,11 @@
  * 
  * If @a cpu_id is the local CPU, the function will be invoked
- * directly.
+ * directly. If the destination cpu id @a cpu_id is invalid
+ * or denotes an inactive cpu, the call is discarded immediately.
  * 
  * Interrupts must be enabled. Otherwise you run the risk
  * of a deadlock.
  * 
- * @param cpu_id Destination CPU's logical id (eg CPU->id)
+ * @param cpu_id Destination CPU's logical id (eg CPU->id).
  * @param func Function to call.
  * @param arg Argument to pass to the user supplied function @a func.
@@ -73,5 +74,5 @@
 	
 	/* Discard invalid calls. */
-	if (config.cpu_count <= cpu_id) {
+	if (config.cpu_count <= cpu_id || !cpus[cpu_id].active) {
 		call_start(call_info, func, arg);
 		call_done(call_info);
@@ -81,5 +82,5 @@
 	/* Protect cpu->id against migration. */
 	preemption_disable();
-	
+
 	call_start(call_info, func, arg);
 	
@@ -89,5 +90,15 @@
 		list_append(&call_info->calls_link, &cpus[cpu_id].smp_pending_calls);
 		spinlock_unlock(&cpus[cpu_id].smp_calls_lock);
-				
+
+		/*
+		 * If a platform supports SMP it must implement arch_smp_call_ipi().
+		 * It should issue an IPI an cpu_id and invoke smp_call_ipi_recv()
+		 * on cpu_id in turn. 
+		 * 
+		 * Do not implement as just an empty dummy function. Instead
+		 * consider providing a full implementation or at least a version 
+		 * that panics if invoked. Note that smp_call_async() never
+		 * calls arch_smp_call_ipi() on uniprocessors even if CONFIG_SMP.
+		 */
 		arch_smp_call_ipi(cpu_id);
 #endif
@@ -131,5 +142,5 @@
 /** Architecture independent smp call IPI handler.
  * 
- * Interrupts must be disabled.
+ * Interrupts must be disabled. Tolerates spurious calls.
  */
 void smp_call_ipi_recv(void)
Index: kernel/test/smpcall/smpcall1.c
===================================================================
--- kernel/test/smpcall/smpcall1.c	(revision 1f8c11fb8cdd200759b495ae526cf6d894d543f0)
+++ kernel/test/smpcall/smpcall1.c	(revision d70fc74015f71b1a86ddbe532d59d15b791514c5)
@@ -14,8 +14,8 @@
 /* 
  * Maximum total number of smp_calls in the system is: 
- *  128000 == 8^2 * 1000 * 2 
+ *  162000 == 9^2 * 1000 * 2 
  *  == MAX_CPUS^2 * ITERATIONS * EACH_CPU_INC_PER_ITER
  */
-#define MAX_CPUS   8
+#define MAX_CPUS   9
 #define ITERATIONS 1000
 #define EACH_CPU_INC_PER_ITER 2
@@ -40,5 +40,5 @@
 	smp_call_t call_info[MAX_CPUS];
 	
-	size_t cpu_count = min(config.cpu_count, MAX_CPUS);
+	unsigned int cpu_count = min(config.cpu_active, MAX_CPUS);
 	
 	for (int iter = 0; iter < ITERATIONS; ++iter) {
@@ -75,4 +75,8 @@
 }
 
+static size_t calc_exp_calls(size_t thread_cnt)
+{
+	return thread_cnt * ITERATIONS * EACH_CPU_INC_PER_ITER;
+}
 
 const char *test_smpcall1(void)
@@ -82,5 +86,5 @@
 	thread_t *thread[MAX_CPUS] = {0};
 	
-	unsigned int cpu_count = min(config.cpu_count, MAX_CPUS);
+	unsigned int cpu_count = min(config.cpu_active, MAX_CPUS);
 	size_t running_thread_cnt = 0;
 
@@ -100,5 +104,9 @@
 	}
 
-	TPRINTF("Running %u wired threads.\n", running_thread_cnt);
+	size_t exp_calls = calc_exp_calls(running_thread_cnt);
+	size_t exp_calls_sum = exp_calls * cpu_count;
+	
+	TPRINTF("Running %zu wired threads. Expecting %zu calls. Be patient.\n", 
+		running_thread_cnt, exp_calls_sum);
 
 	for (unsigned int i = 0; i < cpu_count; ++i) {
@@ -112,11 +120,9 @@
 		if (thread[i] != NULL) {
 			thread_join(thread[i]);
+			thread_detach(thread[i]);
 		}
 	}
 
 	TPRINTF("Threads finished. Checking number of smp_call()s.\n");
-	
-	size_t exp_calls = running_thread_cnt * ITERATIONS * EACH_CPU_INC_PER_ITER;
-	size_t exp_calls_sum = exp_calls * cpu_count;
 	
 	bool ok = true;
@@ -127,5 +133,5 @@
 			if (call_cnt[i] != exp_calls) {
 				ok = false;
-				TPRINTF("Error: %u instead of %u cpu%u's calls were"
+				TPRINTF("Error: %zu instead of %zu cpu%u's calls were"
 					" acknowledged.\n", call_cnt[i], exp_calls, i);
 			} 
@@ -136,5 +142,5 @@
 	
 	if (calls_sum != exp_calls_sum) {
-		TPRINTF("Error: total acknowledged sum: %u instead of %u.\n",
+		TPRINTF("Error: total acknowledged sum: %zu instead of %zu.\n",
 			calls_sum, exp_calls_sum);
 		
@@ -143,5 +149,5 @@
 	
 	if (ok) {
-		TPRINTF("Success: number of received smp_calls is as expected (%u).\n",
+		TPRINTF("Success: number of received smp_calls is as expected (%zu).\n",
 			exp_calls_sum);
 		return NULL;
