Use correct arguments for SPCI calls via SMC.
Change-Id: I9859934b8a05a973c1e159211e01886e89be961d
diff --git a/src/arch/aarch64/hypervisor/handler.c b/src/arch/aarch64/hypervisor/handler.c
index c3c6f77..7b9ac24 100644
--- a/src/arch/aarch64/hypervisor/handler.c
+++ b/src/arch/aarch64/hypervisor/handler.c
@@ -402,21 +402,31 @@
static void smc_handler(struct vcpu *vcpu, struct spci_value *ret,
struct vcpu **next)
{
- uint32_t func = vcpu->regs.r[0];
+ struct spci_value args = {
+ .func = vcpu->regs.r[0],
+ .arg1 = vcpu->regs.r[1],
+ .arg2 = vcpu->regs.r[2],
+ .arg3 = vcpu->regs.r[3],
+ .arg4 = vcpu->regs.r[4],
+ .arg5 = vcpu->regs.r[5],
+ .arg6 = vcpu->regs.r[6],
+ .arg7 = vcpu->regs.r[7],
+ };
- if (psci_handler(vcpu, func, vcpu->regs.r[1], vcpu->regs.r[2],
- vcpu->regs.r[3], &ret->func, next)) {
+ if (psci_handler(vcpu, args.func, args.arg1, args.arg2, args.arg3,
+ &ret->func, next)) {
return;
}
- if (spci_handler(ret, next)) {
+ if (spci_handler(&args, next)) {
+ *ret = args;
update_vi(*next);
return;
}
- switch (func & ~SMCCC_CONVENTION_MASK) {
+ switch (args.func & ~SMCCC_CONVENTION_MASK) {
case HF_DEBUG_LOG:
- ret->func = api_debug_log(vcpu->regs.r[1], vcpu);
+ ret->func = api_debug_log(args.arg1, vcpu);
return;
}
diff --git a/test/vmapi/arch/aarch64/smccc.c b/test/vmapi/arch/aarch64/smccc.c
index 11f4dc3..b078e27 100644
--- a/test/vmapi/arch/aarch64/smccc.c
+++ b/test/vmapi/arch/aarch64/smccc.c
@@ -35,3 +35,22 @@
EXPECT_EQ(smc_res.arg6, UINT64_C(0x6666666666666666));
EXPECT_EQ(smc_res.arg7, UINT64_C(0x77777777));
}
+
+/**
+ * Checks that calling SPCI_FEATURES via an SMC works as expected.
+ * The spci_features helper function uses an HVC, but an SMC should also work.
+ */
+TEST(smccc, spci_features_smc)
+{
+ struct spci_value ret;
+
+ ret = smc32(SPCI_FEATURES_32, SPCI_VERSION_32, 0, 0, 0, 0, 0, 0);
+ EXPECT_EQ(ret.func, SPCI_SUCCESS_32);
+ EXPECT_EQ(ret.arg1, 0);
+ EXPECT_EQ(ret.arg2, 0);
+ EXPECT_EQ(ret.arg3, 0);
+ EXPECT_EQ(ret.arg4, 0);
+ EXPECT_EQ(ret.arg5, 0);
+ EXPECT_EQ(ret.arg6, 0);
+ EXPECT_EQ(ret.arg7, 0);
+}