@@ -44,6 +44,7 @@ bool smp_sense_running_status(uint16_t idx);
int smp_cpu_restart(uint16_t idx);
int smp_cpu_start(uint16_t idx, struct psw psw);
int smp_cpu_stop(uint16_t idx);
+int smp_cpu_stop_nowait(uint16_t idx);
int smp_cpu_stop_store_status(uint16_t idx);
int smp_cpu_destroy(uint16_t idx);
int smp_cpu_setup(uint16_t idx, struct psw psw);
@@ -119,6 +119,33 @@ int smp_cpu_stop(uint16_t idx)
return rc;
}
+/*
+ * Functionally equivalent to smp_cpu_stop(), but without the
+ * elements that wait/serialize matters itself.
+ * Used to see if KVM itself is serialized correctly.
+ */
+int smp_cpu_stop_nowait(uint16_t idx)
+{
+ check_idx(idx);
+
+ /* refuse to work on the boot CPU */
+ if (idx == 0)
+ return -1;
+
+ spin_lock(&lock);
+
+ /* Don't suppress a CC2 with sigp_retry() */
+ if (sigp(cpus[idx].addr, SIGP_STOP, 0, NULL)) {
+ spin_unlock(&lock);
+ return -1;
+ }
+
+ cpus[idx].active = false;
+ spin_unlock(&lock);
+
+ return 0;
+}
+
int smp_cpu_stop_store_status(uint16_t idx)
{
int rc;
@@ -76,14 +76,15 @@ static void test_restart(void)
static void test_stop(void)
{
- smp_cpu_stop(1);
- /*
- * The smp library waits for the CPU to shut down, but let's
- * also do it here, so we don't rely on the library
- * implementation
- */
- while (!smp_cpu_stopped(1)) {}
- report_pass("stop");
+ int rc;
+
+ report_prefix_push("stop");
+
+ rc = smp_cpu_stop_nowait(1);
+ report(!rc, "return code");
+ report(smp_cpu_stopped(1), "cpu stopped");
+
+ report_prefix_pop();
}
static void test_stop_store_status(void)