Skip to content
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

Add SMC calls forwarding framework #21

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions src/arch/aarch64/smc.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#include "smc.h"
#include "psci.h"
#include "fault.h"
#include "../../util/util.h"

// Values in this file are taken from:
Expand All @@ -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;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my opinion the user of the library should not have to do this, and instead just have a wrapper for setting the handler.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also thank you for writing comments for how to use the API.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my opinion the user of the library should not have to do this, and instead just have a wrapper for setting the handler.

Agreed, that would be easier to use.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

API changed


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);
Expand Down Expand Up @@ -109,10 +133,44 @@ 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, &regs, fn_number);
#endif
default:
LOG_VMM_ERR("Unhandled SMC: unknown value service: 0x%lx, function number: 0x%lx\n", service, fn_number);
break;
}

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;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While it isn't the current case for the rest of the library, I would like the library to be agnostic to the seL4 environment it is in, this means that it should be up to the user to provide the library with what capability to use for SMC calls.

If it's not too hard for you, it'd be good if specifying the SMC cap was part of the API.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, good catch, I'll change it.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

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;
}
9 changes: 9 additions & 0 deletions src/arch/aarch64/smc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
malus-brandywine marked this conversation as resolved.
Show resolved Hide resolved

/* 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);
Loading