New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Starting Xen hypervisor in EL2 coming from EL1? #353
Comments
Hello, The patch that you've linked [1] adds support for both SMC and HVC calls in U-Boot. Have you tried that? Regards, [1] http://git.denx.de/?p=u-boot.git;a=commitdiff;h=a5b9fa30cebd91082f9fea93d7ef33812910da6a |
This flow Sandrine suggests relies on your Trusted Firmware platform port (in BL2) starting U-Boot at EL2 (to install the HVC functionality), even if U-Boot subsequently drops down to EL1 to load Xen. |
Assuming that U-Boot remains in EL1, does the Trusted Firmware supports (a smc call?) to start anything at EL2? I'm thinking on a smc call passing a pointer to an entry address and a target ELx. |
In short, no. Any such SMC would be platform-specific and not supported by the upstream Trusted Firmware. In particular, unless the caller of the SMC were authenticated in some way, this would be a privilege escalation back door. |
BL3-1 is currently written so that if the initial non-secure payload requests to start at EL1, then the hypervisor layer is disabled (SCR_EL3.HCE=0) and bypassed. Subsequently starting other CPUs will cause them to do the same - as required by the PSCI specification. Provision of an SMC to support elevation from EL1 execution to EL2 is a security vulnerability as Dan explains, provision of a generic implementation of this would be inadvisable. The recommended approach is that in this situation the non-secure boot payload runs initially at EL2 (so BL3-1 activates the hypervisor layer), which sets up a simple EL2 exception vector and minimally configures EL2 before continuing U-Boot at EL1. That exception vector supports a single HVC call to return to EL2 to execute the Xen hypervisor (or other loaded image designed to execute at EL2 such as Linux). |
Many thanks! I'll look into that, we can close this question. Thanks again! |
Just for the logs as I understood that this isn't allowed to be done (see above: "In particular, unless the caller of the SMC were authenticated in some way, this would be a privilege escalation back door."): Using a U-Boot patch like http://lists.denx.de/pipermail/u-boot/2016-June/259177.html to issue a smc call to get back from U-Boot running at EL1 to EL3 and then a arm trusted firmware hack (hack!) like below [1] would allow to start a hypervisor loaded by U-Boot in the memory. Dirk [1] From a605d32223188a0665783d57b1c17eaf42c27603 Mon Sep 17 00:00:00 2001
From: Dirk Behme <dirk.behme@de.bosch.com>
Date: Tue, 28 Jun 2016 09:34:54 +0200
Subject: [PATCH] Add SMC call to start hypervisor
Add a SMC call to start a hypervisor at EL2 already loaded to
memory before this call.
Signed-off-by: Dirk Behme <dirk.behme@de.bosch.com>
---
include/bl31/services/std_svc.h | 1 +
services/std_svc/std_svc_setup.c | 23 +++++++++++++++++++++++
2 files changed, 24 insertions(+), 0 deletions(-)
diff --git a/include/bl31/services/std_svc.h b/include/bl31/services/std_svc.h
index cbd5b62..41fe19b 100644
--- a/include/bl31/services/std_svc.h
+++ b/include/bl31/services/std_svc.h
@@ -37,6 +37,7 @@
#define ARM_STD_SVC_UID 0x8400ff01
/* 0x8400ff02 is reserved */
#define ARM_STD_SVC_VERSION 0x8400ff03
+#define ARM_STD_SVC_CALL_HYPERVISOR 0x8400ff04
/* ARM Standard Service Calls version numbers */
#define STD_SVC_VERSION_MAJOR 0x0
diff --git a/services/std_svc/std_svc_setup.c b/services/std_svc/std_svc_setup.c
index 6cb0319..c8b77f0 100644
--- a/services/std_svc/std_svc_setup.c
+++ b/services/std_svc/std_svc_setup.c
@@ -30,6 +30,10 @@
#include <debug.h>
#include <psci.h>
+#include <assert.h>
+#include <bl_common.h>
+#include <context_mgmt.h>
+#include <platform.h>
#include <runtime_svc.h>
#include <std_svc.h>
#include <stdint.h>
@@ -63,6 +67,8 @@ uint64_t std_svc_smc_handler(uint32_t smc_fid,
void *handle,
uint64_t flags)
{
+ entry_point_info_t *next_image_info;
+
/*
* Dispatch PSCI calls to PSCI SMC handler and return its return
* value
@@ -88,6 +94,23 @@ uint64_t std_svc_smc_handler(uint32_t smc_fid,
/* Return the version of current implementation */
SMC_RET2(handle, STD_SVC_VERSION_MAJOR, STD_SVC_VERSION_MINOR);
+ case ARM_STD_SVC_CALL_HYPERVISOR:
+ /*
+ * Call a hypervisor at EL2 already present in memory
+ * Parameters passed to us:
+ * x1: Entry address of the hypervisor (jump target)
+ * x2: argument 0 for the hypervisor, e.g. the device tree address
+ * x3: argument 2 for the hypervisor, e.g. the Linux kernel Image address
+ */
+
+ next_image_info = bl31_plat_get_next_image_ep_info(NON_SECURE);
+ next_image_info->spsr = 0x3C9; /* EL2 */
+ next_image_info->pc = x1;
+ next_image_info->args.arg0 = x2;
+ next_image_info->args.arg2 = x3;
+ cm_init_my_context(next_image_info);
+ SMC_RET0(handle);
+
default:
WARN("Unimplemented Standard Service Call: 0x%x \n", smc_fid);
SMC_RET1(handle, SMC_UNK); |
My ARMv8 aarch64 system uses trusted firmware (BL2, BL31 available, too) to start U-Boot. U-Boot is running at EL1, then. Short boot log:
...
NOTICE: BL2: Normal boot
U-Boot 2015.04 (Nov 02 2015 - 10:04:48)
...
With this I'd like to start / run the hypervisor Xen. This has to run at EL2.
If I understood correctly, I load Xen via U-Boot to RAM, e.g. via tftp. Then, in U-Boot at EL1 I have to do a secure monitor call (using e.g. [1]) to enter the trusted firmware at EL3. This has to "call" the Xen hypervisor at EL2, then.
Is this understanding correct? Does the trusted firmware supports this?
If this is supported, how does the smc have to look, then (giving the start address of the Xen image)? Any pointers to code / examples?
Best regards
Dirk
[1] http://git.denx.de/?p=u-boot.git;a=commitdiff;h=a5b9fa30cebd91082f9fea93d7ef33812910da6a
The text was updated successfully, but these errors were encountered: