Commit e551c5bf authored by danh-arm's avatar danh-arm
Browse files

Merge pull request #469 from danh-arm/dh/fwu-resume-fix

FWU: Remove image_id arg from FWU_SMC_IMAGE_RESUME
parents 8e4f8291 28955d57
...@@ -58,8 +58,7 @@ static int bl1_fwu_image_auth(unsigned int image_id, ...@@ -58,8 +58,7 @@ static int bl1_fwu_image_auth(unsigned int image_id,
static int bl1_fwu_image_execute(unsigned int image_id, static int bl1_fwu_image_execute(unsigned int image_id,
void **handle, void **handle,
unsigned int flags); unsigned int flags);
static register_t bl1_fwu_image_resume(unsigned int image_id, static register_t bl1_fwu_image_resume(register_t image_param,
register_t image_param,
void **handle, void **handle,
unsigned int flags); unsigned int flags);
static int bl1_fwu_sec_image_done(void **handle, static int bl1_fwu_sec_image_done(void **handle,
...@@ -95,7 +94,7 @@ register_t bl1_fwu_smc_handler(unsigned int smc_fid, ...@@ -95,7 +94,7 @@ register_t bl1_fwu_smc_handler(unsigned int smc_fid,
SMC_RET1(handle, bl1_fwu_image_execute(x1, &handle, flags)); SMC_RET1(handle, bl1_fwu_image_execute(x1, &handle, flags));
case FWU_SMC_IMAGE_RESUME: case FWU_SMC_IMAGE_RESUME:
SMC_RET1(handle, bl1_fwu_image_resume(x1, x2, &handle, flags)); SMC_RET1(handle, bl1_fwu_image_resume(x1, &handle, flags));
case FWU_SMC_SEC_IMAGE_DONE: case FWU_SMC_SEC_IMAGE_DONE:
SMC_RET1(handle, bl1_fwu_sec_image_done(&handle, flags)); SMC_RET1(handle, bl1_fwu_sec_image_done(&handle, flags));
...@@ -363,6 +362,7 @@ static int bl1_fwu_image_execute(unsigned int image_id, ...@@ -363,6 +362,7 @@ static int bl1_fwu_image_execute(unsigned int image_id,
/* /*
* Execution is NOT allowed if: * Execution is NOT allowed if:
* image_id is invalid OR
* Caller is from Secure world OR * Caller is from Secure world OR
* Image is Non-Secure OR * Image is Non-Secure OR
* Image is Non-Executable OR * Image is Non-Executable OR
...@@ -393,40 +393,41 @@ static int bl1_fwu_image_execute(unsigned int image_id, ...@@ -393,40 +393,41 @@ static int bl1_fwu_image_execute(unsigned int image_id,
} }
/******************************************************************************* /*******************************************************************************
* This function is responsible for resuming Secure/Non-Secure images. * This function is responsible for resuming execution in the other security
* world
******************************************************************************/ ******************************************************************************/
static register_t bl1_fwu_image_resume(unsigned int image_id, static register_t bl1_fwu_image_resume(register_t image_param,
register_t image_param,
void **handle, void **handle,
unsigned int flags) unsigned int flags)
{ {
image_desc_t *image_desc; image_desc_t *image_desc;
unsigned int resume_sec_state; unsigned int resume_sec_state;
unsigned int caller_sec_state = GET_SEC_STATE(flags);
if (GET_SEC_STATE(flags) == SECURE) { /* Get the image descriptor for last executed secure image id. */
/* Get the image descriptor for last executed secure image id. */ image_desc = bl1_plat_get_image_desc(sec_exec_image_id);
image_desc = bl1_plat_get_image_desc(sec_exec_image_id); if (caller_sec_state == NON_SECURE) {
if (!image_desc) {
if ((!image_desc) || (image_desc->state != IMAGE_STATE_EXECUTED)) { WARN("BL1-FWU: Resume not allowed due to no available"
WARN("BL1-FWU: Resume not allowed for secure image " "secure image\n");
"due to invalid state\n");
return -EPERM; return -EPERM;
} }
} else {
/* image_desc must be valid for secure world callers */
assert(image_desc);
}
assert(GET_SEC_STATE(image_desc->ep_info.h.attr) == SECURE);
assert(GET_EXEC_STATE(image_desc->image_info.h.attr) == EXECUTABLE);
if (caller_sec_state == SECURE) {
assert(image_desc->state == IMAGE_STATE_EXECUTED);
/* Update the flags. */ /* Update the flags. */
image_desc->state = IMAGE_STATE_INTERRUPTED; image_desc->state = IMAGE_STATE_INTERRUPTED;
resume_sec_state = NON_SECURE; resume_sec_state = NON_SECURE;
} else { } else {
/* Get the image descriptor for image id to be resumed. */ assert(image_desc->state == IMAGE_STATE_INTERRUPTED);
image_desc = bl1_plat_get_image_desc(image_id);
/* Make sure image is secure and was interrupted. */
if ((!image_desc) ||
(GET_SEC_STATE(image_desc->ep_info.h.attr) == NON_SECURE) ||
(image_desc->state != IMAGE_STATE_INTERRUPTED)) {
WARN("BL1-FWU: Resume not allowed for NS image/ invalid state\n");
return -EPERM;
}
/* Update the flags. */ /* Update the flags. */
image_desc->state = IMAGE_STATE_EXECUTED; image_desc->state = IMAGE_STATE_EXECUTED;
...@@ -434,7 +435,7 @@ static register_t bl1_fwu_image_resume(unsigned int image_id, ...@@ -434,7 +435,7 @@ static register_t bl1_fwu_image_resume(unsigned int image_id,
} }
/* Save the EL1 system registers of calling world. */ /* Save the EL1 system registers of calling world. */
cm_el1_sysregs_context_save(GET_SEC_STATE(flags)); cm_el1_sysregs_context_save(caller_sec_state);
/* Restore the EL1 system registers of resuming world. */ /* Restore the EL1 system registers of resuming world. */
cm_el1_sysregs_context_restore(resume_sec_state); cm_el1_sysregs_context_restore(resume_sec_state);
...@@ -443,7 +444,7 @@ static register_t bl1_fwu_image_resume(unsigned int image_id, ...@@ -443,7 +444,7 @@ static register_t bl1_fwu_image_resume(unsigned int image_id,
cm_set_next_eret_context(resume_sec_state); cm_set_next_eret_context(resume_sec_state);
INFO("BL1-FWU: Resuming %s world context\n", INFO("BL1-FWU: Resuming %s world context\n",
(resume_sec_state == SECURE) ? "Secure" : "Normal"); (resume_sec_state == SECURE) ? "secure" : "normal");
*handle = cm_get_context(resume_sec_state); *handle = cm_get_context(resume_sec_state);
return image_param; return image_param;
...@@ -454,21 +455,23 @@ static register_t bl1_fwu_image_resume(unsigned int image_id, ...@@ -454,21 +455,23 @@ static register_t bl1_fwu_image_resume(unsigned int image_id,
******************************************************************************/ ******************************************************************************/
static int bl1_fwu_sec_image_done(void **handle, unsigned int flags) static int bl1_fwu_sec_image_done(void **handle, unsigned int flags)
{ {
image_desc_t *image_desc;
/* Get the image descriptor for last executed secure image id. */ /* Make sure caller is from the secure world */
image_desc_t *image_desc = bl1_plat_get_image_desc(sec_exec_image_id); if (GET_SEC_STATE(flags) == NON_SECURE) {
WARN("BL1-FWU: Image done not allowed from normal world\n");
/*
* Make sure caller is from secure world
* and the image is in EXECUTED state.
*/
if ((!image_desc) ||
(GET_SEC_STATE(flags) == NON_SECURE) ||
(image_desc->state != IMAGE_STATE_EXECUTED)) {
WARN("BL1-FWU: Done not allowed for NS caller/ invalid state\n");
return -EPERM; return -EPERM;
} }
/* Get the image descriptor for last executed secure image id */
image_desc = bl1_plat_get_image_desc(sec_exec_image_id);
/* image_desc must correspond to a valid secure executing image */
assert(image_desc);
assert(GET_SEC_STATE(image_desc->ep_info.h.attr) == SECURE);
assert(GET_EXEC_STATE(image_desc->image_info.h.attr) == EXECUTABLE);
assert(image_desc->state == IMAGE_STATE_EXECUTED);
/* Update the flags. */ /* Update the flags. */
image_desc->state = IMAGE_STATE_RESET; image_desc->state = IMAGE_STATE_RESET;
sec_exec_image_id = INVALID_IMAGE_ID; sec_exec_image_id = INVALID_IMAGE_ID;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment