Platform hook for SMC forwarding return path.
Bug: 132421542
Change-Id: If931014ccc91254f164dc8875bdbf00de8477e4a
diff --git a/inc/hf/arch/plat/smc.h b/inc/hf/arch/plat/smc.h
new file mode 100644
index 0000000..29493fc
--- /dev/null
+++ b/inc/hf/arch/plat/smc.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2019 The Hafnium Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "vmapi/hf/spci.h"
+
+/**
+ * Called after an SMC has been forwarded. `args` contains the arguments passed
+ * to the SMC and `ret` contains the return values that will be set in the vCPU
+ * registers after this call returns.
+ */
+void plat_smc_post_forward(struct spci_value args, struct spci_value *ret);
diff --git a/src/arch/aarch64/args.gni b/src/arch/aarch64/args.gni
new file mode 100644
index 0000000..1582b34
--- /dev/null
+++ b/src/arch/aarch64/args.gni
@@ -0,0 +1,18 @@
+# Copyright 2019 The Hafnium Authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+declare_args() {
+ # SMC hooks to be used for the platform, specified as build target.
+ plat_smc = "//src/arch/aarch64/smc:absent"
+}
diff --git a/src/arch/aarch64/hypervisor/BUILD.gn b/src/arch/aarch64/hypervisor/BUILD.gn
index e72833a..8a057e9 100644
--- a/src/arch/aarch64/hypervisor/BUILD.gn
+++ b/src/arch/aarch64/hypervisor/BUILD.gn
@@ -13,6 +13,7 @@
# limitations under the License.
import("//build/toolchain/offset_size_header.gni")
+import("//src/arch/aarch64/args.gni")
offset_size_header("offsets") {
sources = [
@@ -46,5 +47,6 @@
"//src/arch/aarch64:arch",
"//src/arch/aarch64:entry",
"//src/arch/aarch64:smc",
+ plat_smc,
]
}
diff --git a/src/arch/aarch64/hypervisor/handler.c b/src/arch/aarch64/hypervisor/handler.c
index fd490ff..a2d0437 100644
--- a/src/arch/aarch64/hypervisor/handler.c
+++ b/src/arch/aarch64/hypervisor/handler.c
@@ -19,6 +19,7 @@
#include "hf/arch/barriers.h"
#include "hf/arch/init.h"
#include "hf/arch/mm.h"
+#include "hf/arch/plat/smc.h"
#include "hf/api.h"
#include "hf/check.h"
@@ -286,6 +287,7 @@
*/
static void smc_forwarder(const struct vm *vm, struct spci_value *args)
{
+ struct spci_value ret;
uint32_t client_id = vm->id;
uintreg_t arg7 = args->arg7;
@@ -300,8 +302,8 @@
* upper bits.
*/
args->arg7 = client_id | (arg7 & ~CLIENT_ID_MASK);
- *args = smc_forward(args->func, args->arg1, args->arg2, args->arg3,
- args->arg4, args->arg5, args->arg6, args->arg7);
+ ret = smc_forward(args->func, args->arg1, args->arg2, args->arg3,
+ args->arg4, args->arg5, args->arg6, args->arg7);
/*
* Preserve the value passed by the caller, rather than the client_id we
@@ -309,7 +311,11 @@
* may be in x7, but the SMCs that we are forwarding are legacy calls
* from before SMCCC 1.2 so won't have more than 4 return values anyway.
*/
- args->arg7 = arg7;
+ ret.arg7 = arg7;
+
+ plat_smc_post_forward(*args, &ret);
+
+ *args = ret;
}
static bool spci_handler(struct spci_value *args, struct vcpu **next)
@@ -425,12 +431,12 @@
switch (args.func & ~SMCCC_CONVENTION_MASK) {
case HF_DEBUG_LOG:
vcpu->regs.r[0] = api_debug_log(args.arg1, vcpu);
- return next;
+ return NULL;
}
smc_forwarder(vcpu->vm, &args);
arch_regs_set_retval(&vcpu->regs, args);
- return next;
+ return NULL;
}
struct vcpu *hvc_handler(struct vcpu *vcpu)
diff --git a/src/arch/aarch64/smc/BUILD.gn b/src/arch/aarch64/smc/BUILD.gn
new file mode 100644
index 0000000..00004f3
--- /dev/null
+++ b/src/arch/aarch64/smc/BUILD.gn
@@ -0,0 +1,19 @@
+# Copyright 2019 The Hafnium Authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+source_set("absent") {
+ sources = [
+ "absent.c",
+ ]
+}
diff --git a/src/arch/aarch64/smc/absent.c b/src/arch/aarch64/smc/absent.c
new file mode 100644
index 0000000..6ea9b8d
--- /dev/null
+++ b/src/arch/aarch64/smc/absent.c
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2019 The Hafnium Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "hf/arch/plat/smc.h"
+
+void plat_smc_post_forward(struct spci_value args, struct spci_value *ret)
+{
+ (void)args;
+ (void)ret;
+}