diff options
author | Andrew Walbran <qwandor@google.com> | 2020-08-07 12:42:01 +0100 |
---|---|---|
committer | Andrew Walbran <qwandor@google.com> | 2020-08-17 12:23:42 +0100 |
commit | 4692a3ab1ba707feb15c2debc4b2e0fdc8127b59 (patch) | |
tree | a2bfba00eb1e4028b96eaf25030204467c0fcc57 | |
parent | 08974eca36be6c3b90ab9f964c228af64c2259d1 (diff) | |
download | hafnium-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.c | 22 | ||||
-rw-r--r-- | test/vmapi/primary_with_secondaries/ffa.c | 25 | ||||
-rw-r--r-- | test/vmapi/primary_with_secondaries/services/BUILD.gn | 11 | ||||
-rw-r--r-- | test/vmapi/primary_with_secondaries/services/run_waiting.c | 21 |
4 files changed, 68 insertions, 11 deletions
@@ -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."); +} |