From 0a5889ffb5864581f4c04577c9427334c1ac8fef Mon Sep 17 00:00:00 2001 From: Nataliya Korovkina Date: Tue, 3 Oct 2023 17:33:05 -0400 Subject: [PATCH 1/3] Add SMC calls forwarding framework Added: - a framework for forwarding SMC calls to Secure Monitor, - SiP Service entry in the framework. Signed-off-by: Nataliya Korovkina --- src/arch/aarch64/smc.c | 58 ++++++++++++++++++++++++++++++++++++++++++ src/arch/aarch64/smc.h | 9 +++++++ 2 files changed, 67 insertions(+) diff --git a/src/arch/aarch64/smc.c b/src/arch/aarch64/smc.c index 21a6c5f2..76244b9d 100644 --- a/src/arch/aarch64/smc.c +++ b/src/arch/aarch64/smc.c @@ -7,6 +7,7 @@ #include "smc.h" #include "psci.h" +#include "fault.h" #include "../../util/util.h" // Values in this file are taken from: @@ -32,6 +33,29 @@ typedef enum { SMC_CALL_RESERVED = 64, } smc_call_id_t; +#if defined(CONFIG_ALLOW_SMC_CALLS) +/* Service handlers for services that require "physical" access to EL3 components + (vs emulation) are listed here. + + 'Active' handler is a pointer to fucntion that actually will be invoked; + by default active handlers are set to NULL. Application should assign to an active handler + wheither a default handler that unconditionally forwards calls to Secure Monitor: + + extern handle_service_type handle_xxx; + handle_service_type handle_xxx = default_handle_service; + + or assign a custom handler impelemntating some forwarding policy: + + extern handle_service_type handle_xxx; + handle_service_type handle_xxx = wary_handle_service; + + Note: application code should include smc.h +*/ + +/* 'handle_sip()' is an active handler of SiP Service calls */ +handle_service_type handle_sip = NULL; +#endif + static smc_call_id_t smc_get_call(size_t func_id) { uint64_t service = ((func_id >> SMC_SERVICE_CALL_SHIFT) & SMC_SERVICE_CALL_MASK); @@ -109,6 +133,10 @@ bool handle_smc(size_t vcpu_id, uint32_t hsr) } LOG_VMM_ERR("Unhandled SMC: standard service call %lu\n", fn_number); break; +#if defined(CONFIG_ALLOW_SMC_CALLS) + case SMC_CALL_SIP_SERVICE: + return handle_sip(vcpu_id, ®s, fn_number); +#endif default: LOG_VMM_ERR("Unhandled SMC: unknown value service: 0x%lx, function number: 0x%lx\n", service, fn_number); break; @@ -116,3 +144,33 @@ bool handle_smc(size_t vcpu_id, uint32_t hsr) return false; } + + +/* Default handler of calls to a Service (group of Functions) running at Secure Monitor level; + forwards all the calls without applying any policy +*/ +bool default_handle_service(uint64_t vcpu_id, seL4_UserContext *regs, uint64_t fn_number) +{ + + seL4_CPtr smc_cap = SMC_CAP; + seL4_ARM_SMCContext request; + seL4_ARM_SMCContext response; + + request.x0 = regs->x0; request.x1 = regs->x1; + request.x2 = regs->x2; request.x3 = regs->x3; + request.x4 = regs->x4; request.x5 = regs->x5; + request.x6 = regs->x6; request.x7 = regs->x7; + + seL4_ARM_SMC_Call(smc_cap, &request, &response); + + regs->x0 = response.x0; regs->x1 = response.x1; + regs->x2 = response.x2; regs->x3 = response.x3; + regs->x4 = response.x4; regs->x5 = response.x5; + regs->x6 = response.x6; regs->x7 = response.x7; + + + bool success = fault_advance_vcpu(vcpu_id, regs); + assert(success); + + return success; +} diff --git a/src/arch/aarch64/smc.h b/src/arch/aarch64/smc.h index bc5e6abf..0fa303fd 100644 --- a/src/arch/aarch64/smc.h +++ b/src/arch/aarch64/smc.h @@ -20,3 +20,12 @@ void smc_set_return_value(seL4_UserContext *u, uint64_t val); /* Gets the value of x1-x6 */ uint64_t smc_get_arg(seL4_UserContext *u, uint64_t arg); + +/* Default handler of calls to a SMC Service */ +bool default_handle_service(uint64_t vcpu_id, seL4_UserContext *regs, uint64_t fn_number); + +/* Service handler type */ +typedef bool (* handle_service_type)(uint64_t, seL4_UserContext *, uint64_t); + +/* Default handler of SiP service calls */ +bool default_handle_sip(uint64_t vcpu_id, seL4_UserContext *regs, uint64_t fn_number); From cfcedb3883477e7be4122556de29973acc3536e6 Mon Sep 17 00:00:00 2001 From: Nataliya Korovkina Date: Wed, 4 Oct 2023 13:24:44 -0400 Subject: [PATCH 2/3] Add SMC calls forwarding framework Added: - a framework for forwarding SMC calls to Secure Monitor, - SiP Service entry in the framework. Signed-off-by: Nataliya Korovkina --- src/arch/aarch64/smc.c | 68 +++++++++++++++++++++++++++++++++--------- src/arch/aarch64/smc.h | 16 ++++++++-- 2 files changed, 67 insertions(+), 17 deletions(-) diff --git a/src/arch/aarch64/smc.c b/src/arch/aarch64/smc.c index 76244b9d..7c5ed5bd 100644 --- a/src/arch/aarch64/smc.c +++ b/src/arch/aarch64/smc.c @@ -34,27 +34,67 @@ typedef enum { } smc_call_id_t; #if defined(CONFIG_ALLOW_SMC_CALLS) +/* SMC Call Cap that the library makes SMC calls on; passed from an application */ +seL4_CPtr smc_cap_current; + +/* Set SMC Call Cap to use by the library API; + should be called before an application starts + handling exceptions from a VM thread +*/ +bool smc_set_cap(seL4_CPtr smcccap) +{ + if (!smcccap) + { + LOG_VMM_ERR("SMC forwarding: attempted to set zero SMC Call cap\n"); + return false; + } + smc_cap_current = smcccap; + return true; +} +#endif /*CONFIG_ALLOW_SMC_CALLS*/ + +#if defined(CONFIG_ALLOW_SMC_CALLS) + /* Service handlers for services that require "physical" access to EL3 components (vs emulation) are listed here. - 'Active' handler is a pointer to fucntion that actually will be invoked; + 'Active' handler is a pointer to a fucntion that actually will be invoked; by default active handlers are set to NULL. Application should assign to an active handler wheither a default handler that unconditionally forwards calls to Secure Monitor: - extern handle_service_type handle_xxx; - handle_service_type handle_xxx = default_handle_service; + smc_set_handler_xxx_service(smc_default_handle_service); + + or assign a custom handler impelemnting some forwarding policy: - or assign a custom handler impelemntating some forwarding policy: + smc_set_handler_xxx_service(wary_handle_service); - extern handle_service_type handle_xxx; - handle_service_type handle_xxx = wary_handle_service; + To remove active handler invoke: + + smc_set_handler_xxx_service(NULL); Note: application code should include smc.h */ -/* 'handle_sip()' is an active handler of SiP Service calls */ -handle_service_type handle_sip = NULL; -#endif +/* 'smc_handle_sip()' is an active handler of SiP Service calls */ +smc_handle_service_type smc_handle_sip = NULL; + +/* 'smc_set_handler_sip_service()' assigns/removes active SiP Service handler; + NULL is a valid value to remove an earlier assigned handler; + function returns 'True' if handler was initialized with pointer to a function, + and 'False' if a handler was removed */ +bool smc_set_handler_sip_service (smc_handle_service_type handler_func) +{ + if (handler_func == NULL) + { + smc_handle_sip = NULL; + return false; + } + else + smc_handle_sip = handler_func; + + return true; +} +#endif /*CONFIG_ALLOW_SMC_CALLS*/ static smc_call_id_t smc_get_call(size_t func_id) { @@ -135,7 +175,7 @@ bool handle_smc(size_t vcpu_id, uint32_t hsr) break; #if defined(CONFIG_ALLOW_SMC_CALLS) case SMC_CALL_SIP_SERVICE: - return handle_sip(vcpu_id, ®s, fn_number); + return smc_handle_sip(vcpu_id, ®s, fn_number); #endif default: LOG_VMM_ERR("Unhandled SMC: unknown value service: 0x%lx, function number: 0x%lx\n", service, fn_number); @@ -145,14 +185,13 @@ bool handle_smc(size_t vcpu_id, uint32_t hsr) return false; } - +#if defined(CONFIG_ALLOW_SMC_CALLS) /* Default handler of calls to a Service (group of Functions) running at Secure Monitor level; forwards all the calls without applying any policy */ -bool default_handle_service(uint64_t vcpu_id, seL4_UserContext *regs, uint64_t fn_number) +bool smc_default_handle_service(size_t vcpu_id, seL4_UserContext *regs, uint64_t fn_number) { - seL4_CPtr smc_cap = SMC_CAP; seL4_ARM_SMCContext request; seL4_ARM_SMCContext response; @@ -161,7 +200,7 @@ bool default_handle_service(uint64_t vcpu_id, seL4_UserContext *regs, uint64_t f request.x4 = regs->x4; request.x5 = regs->x5; request.x6 = regs->x6; request.x7 = regs->x7; - seL4_ARM_SMC_Call(smc_cap, &request, &response); + seL4_ARM_SMC_Call(smc_cap_current, &request, &response); regs->x0 = response.x0; regs->x1 = response.x1; regs->x2 = response.x2; regs->x3 = response.x3; @@ -174,3 +213,4 @@ bool default_handle_service(uint64_t vcpu_id, seL4_UserContext *regs, uint64_t f return success; } +#endif /*CONFIG_ALLOW_SMC_CALLS*/ diff --git a/src/arch/aarch64/smc.h b/src/arch/aarch64/smc.h index 0fa303fd..74dc14e1 100644 --- a/src/arch/aarch64/smc.h +++ b/src/arch/aarch64/smc.h @@ -21,11 +21,21 @@ void smc_set_return_value(seL4_UserContext *u, uint64_t val); /* Gets the value of x1-x6 */ uint64_t smc_get_arg(seL4_UserContext *u, uint64_t arg); +#if defined(CONFIG_ALLOW_SMC_CALLS) + +/* Set SMC Call Cap to use by the library API */ +bool smc_set_cap(seL4_CPtr smcccap); + /* Default handler of calls to a SMC Service */ -bool default_handle_service(uint64_t vcpu_id, seL4_UserContext *regs, uint64_t fn_number); +bool smc_default_handle_service(size_t vcpu_id, seL4_UserContext *regs, uint64_t fn_number); /* Service handler type */ -typedef bool (* handle_service_type)(uint64_t, seL4_UserContext *, uint64_t); +typedef bool (* smc_handle_service_type)(size_t, seL4_UserContext *, uint64_t); /* Default handler of SiP service calls */ -bool default_handle_sip(uint64_t vcpu_id, seL4_UserContext *regs, uint64_t fn_number); +bool smc_default_handle_sip(size_t vcpu_id, seL4_UserContext *regs, uint64_t fn_number); + +/* 'set_handler_sip_service()' assigns/removes active SiP Service handler */ +bool smc_set_handler_sip_service(smc_handle_service_type handler_func); + +#endif From 1de8893302ee9fb9c91408f2fc3e0f5709798657 Mon Sep 17 00:00:00 2001 From: Nataliya Korovkina Date: Thu, 5 Oct 2023 14:26:56 -0400 Subject: [PATCH 3/3] Add SMC calls forwarding framework Added: - a framework for forwarding SMC calls to Secure Monitor, - SiP Service entry in the framework. Signed-off-by: Nataliya Korovkina --- src/arch/aarch64/smc.h | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/arch/aarch64/smc.h b/src/arch/aarch64/smc.h index 74dc14e1..009b5511 100644 --- a/src/arch/aarch64/smc.h +++ b/src/arch/aarch64/smc.h @@ -23,17 +23,16 @@ uint64_t smc_get_arg(seL4_UserContext *u, uint64_t arg); #if defined(CONFIG_ALLOW_SMC_CALLS) -/* Set SMC Call Cap to use by the library API */ -bool smc_set_cap(seL4_CPtr smcccap); - /* Default handler of calls to a SMC Service */ bool smc_default_handle_service(size_t vcpu_id, seL4_UserContext *regs, uint64_t fn_number); /* Service handler type */ typedef bool (* smc_handle_service_type)(size_t, seL4_UserContext *, uint64_t); -/* Default handler of SiP service calls */ -bool smc_default_handle_sip(size_t vcpu_id, seL4_UserContext *regs, uint64_t fn_number); +/* API for user: */ + +/* Set SMC Call Cap to use by the library API */ +bool smc_set_cap(seL4_CPtr smcccap); /* 'set_handler_sip_service()' assigns/removes active SiP Service handler */ bool smc_set_handler_sip_service(smc_handle_service_type handler_func);