aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Walbran <qwandor@google.com>2020-08-07 12:42:01 +0100
committerAndrew Walbran <qwandor@google.com>2020-08-17 12:23:42 +0100
commit4692a3ab1ba707feb15c2debc4b2e0fdc8127b59 (patch)
treea2bfba00eb1e4028b96eaf25030204467c0fcc57
parent08974eca36be6c3b90ab9f964c228af64c2259d1 (diff)
downloadhafnium-4692a3ab1ba707feb15c2debc4b2e0fdc8127b59.tar.gz
Make ffa_run on a blocked vCPU consistent with or without a timer.
Before it would return an error when called on a blocked vCPU with no timer; now it will return FFA_MSG_WAIT_32 or HF_FFA_RUN_WAIT_FOR_INTERRUPT as appropriate. Change-Id: I4d7cbe1c1a8b5a323ac1279b249dd43536a7c0d2
-rw-r--r--src/api.c22
-rw-r--r--test/vmapi/primary_with_secondaries/ffa.c25
-rw-r--r--test/vmapi/primary_with_secondaries/services/BUILD.gn11
-rw-r--r--test/vmapi/primary_with_secondaries/services/run_waiting.c21
4 files changed, 68 insertions, 11 deletions
diff --git a/src/api.c b/src/api.c
index 180bb1ba2..96386e3a3 100644
--- a/src/api.c
+++ b/src/api.c
@@ -561,8 +561,10 @@ static bool api_vcpu_prepare_run(const struct vcpu *current, struct vcpu *vcpu,
break;
}
+ uint64_t timer_remaining_ns = FFA_SLEEP_INDEFINITE;
+
if (arch_timer_enabled(&vcpu->regs)) {
- uint64_t timer_remaining_ns =
+ timer_remaining_ns =
arch_timer_remaining_ns(&vcpu->regs);
/*
@@ -572,19 +574,17 @@ static bool api_vcpu_prepare_run(const struct vcpu *current, struct vcpu *vcpu,
if (timer_remaining_ns == 0) {
break;
}
+ }
- /*
- * The vCPU is not ready to run, return the appropriate
- * code to the primary which called vcpu_run.
- */
- run_ret->func =
- vcpu->state == VCPU_STATE_BLOCKED_MAILBOX
+ /*
+ * The vCPU is not ready to run, return the appropriate code to
+ * the primary which called vcpu_run.
+ */
+ run_ret->func = vcpu->state == VCPU_STATE_BLOCKED_MAILBOX
? FFA_MSG_WAIT_32
: HF_FFA_RUN_WAIT_FOR_INTERRUPT;
- run_ret->arg1 =
- ffa_vm_vcpu(vcpu->vm->id, vcpu_index(vcpu));
- run_ret->arg2 = timer_remaining_ns;
- }
+ run_ret->arg1 = ffa_vm_vcpu(vcpu->vm->id, vcpu_index(vcpu));
+ run_ret->arg2 = timer_remaining_ns;
ret = false;
goto out;
diff --git a/test/vmapi/primary_with_secondaries/ffa.c b/test/vmapi/primary_with_secondaries/ffa.c
index 5ac042db2..3b9e2b5a3 100644
--- a/test/vmapi/primary_with_secondaries/ffa.c
+++ b/test/vmapi/primary_with_secondaries/ffa.c
@@ -165,3 +165,28 @@ TEST(ffa, ffa_partition_info)
ret = ffa_rx_release();
EXPECT_EQ(ret.func, FFA_SUCCESS_32);
}
+
+/**
+ * Trying to run a partition which is waiting for a message should not actually
+ * run it, but return FFA_MSG_WAIT again.
+ */
+TEST(ffa, run_waiting)
+{
+ struct mailbox_buffers mb = set_up_mailbox();
+ struct ffa_value run_res;
+
+ SERVICE_SELECT(SERVICE_VM1, "run_waiting", mb.send);
+
+ /* Let the secondary get started and wait for a message. */
+ run_res = ffa_run(SERVICE_VM1, 0);
+ EXPECT_EQ(run_res.func, FFA_MSG_WAIT_32);
+ EXPECT_EQ(run_res.arg2, FFA_SLEEP_INDEFINITE);
+
+ /*
+ * Trying to run it again should return the same value, and not actually
+ * run it.
+ */
+ run_res = ffa_run(SERVICE_VM1, 0);
+ EXPECT_EQ(run_res.func, FFA_MSG_WAIT_32);
+ EXPECT_EQ(run_res.arg2, FFA_SLEEP_INDEFINITE);
+}
diff --git a/test/vmapi/primary_with_secondaries/services/BUILD.gn b/test/vmapi/primary_with_secondaries/services/BUILD.gn
index 7def65fec..7f8e8e31c 100644
--- a/test/vmapi/primary_with_secondaries/services/BUILD.gn
+++ b/test/vmapi/primary_with_secondaries/services/BUILD.gn
@@ -169,6 +169,16 @@ source_set("relay") {
]
}
+# Service to wait for a message but expect never to get one.
+source_set("run_waiting") {
+ testonly = true
+ public_configs = [ "//test/hftest:hftest_config" ]
+
+ sources = [
+ "run_waiting.c",
+ ]
+}
+
# Service to start a second vCPU and send messages from both.
source_set("smp") {
testonly = true
@@ -230,6 +240,7 @@ vm_kernel("service_vm1") {
":perfmon",
":receive_block",
":relay",
+ ":run_waiting",
":unmapped",
":wfi",
"//test/hftest:hftest_secondary_vm",
diff --git a/test/vmapi/primary_with_secondaries/services/run_waiting.c b/test/vmapi/primary_with_secondaries/services/run_waiting.c
new file mode 100644
index 000000000..f09a9d7ea
--- /dev/null
+++ b/test/vmapi/primary_with_secondaries/services/run_waiting.c
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2020 The Hafnium Authors.
+ *
+ * Use of this source code is governed by a BSD-style
+ * license that can be found in the LICENSE file or at
+ * https://opensource.org/licenses/BSD-3-Clause.
+ */
+
+#include "vmapi/hf/call.h"
+
+#include "test/hftest.h"
+
+/**
+ * Service that waits for a message but expects never to get one.
+ */
+TEST_SERVICE(run_waiting)
+{
+ ffa_msg_wait();
+
+ FAIL("Secondary VM was run.");
+}