mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-17 10:04:26 +00:00
SPM: Prevent simultaneous blocking calls
Blocking calls can only succeed if the target Secure Partition is idle. Change-Id: Iabeaa0b8d3e653fd8581fa086758936abfc1c772 Signed-off-by: Antonio Nino Diaz <antonio.ninodiaz@arm.com>
This commit is contained in:
parent
d54f0cab3b
commit
2f48ddae74
3 changed files with 48 additions and 0 deletions
|
@ -291,6 +291,12 @@ static uint64_t spci_service_request_blocking(void *handle,
|
|||
SMC_RET1(handle, SPCI_BUSY);
|
||||
}
|
||||
|
||||
if (spm_sp_request_increase_if_zero(sp_ctx) == -1) {
|
||||
spin_unlock(&spci_handles_lock);
|
||||
|
||||
SMC_RET1(handle, SPCI_BUSY);
|
||||
}
|
||||
|
||||
/* Prevent this handle from being closed */
|
||||
handle_info->num_active_requests += 1;
|
||||
|
||||
|
@ -348,6 +354,7 @@ static uint64_t spci_service_request_blocking(void *handle,
|
|||
spin_lock(&spci_handles_lock);
|
||||
handle_info->num_active_requests -= 1;
|
||||
spin_unlock(&spci_handles_lock);
|
||||
spm_sp_request_decrease(sp_ctx);
|
||||
|
||||
/* Restore non-secure state */
|
||||
cm_el1_sysregs_context_restore(NON_SECURE);
|
||||
|
|
|
@ -46,6 +46,39 @@ sp_context_t *spm_cpu_get_sp_ctx(unsigned int linear_id)
|
|||
return cpu_sp_ctx[linear_id];
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Functions to keep track of how many requests a Secure Partition has received
|
||||
* and hasn't finished.
|
||||
******************************************************************************/
|
||||
void spm_sp_request_increase(sp_context_t *sp_ctx)
|
||||
{
|
||||
spin_lock(&(sp_ctx->request_count_lock));
|
||||
sp_ctx->request_count++;
|
||||
spin_unlock(&(sp_ctx->request_count_lock));
|
||||
}
|
||||
|
||||
void spm_sp_request_decrease(sp_context_t *sp_ctx)
|
||||
{
|
||||
spin_lock(&(sp_ctx->request_count_lock));
|
||||
sp_ctx->request_count--;
|
||||
spin_unlock(&(sp_ctx->request_count_lock));
|
||||
}
|
||||
|
||||
/* Returns 0 if it was originally 0, -1 otherwise. */
|
||||
int spm_sp_request_increase_if_zero(sp_context_t *sp_ctx)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
spin_lock(&(sp_ctx->request_count_lock));
|
||||
if (sp_ctx->request_count == 0U) {
|
||||
sp_ctx->request_count++;
|
||||
ret = 0U;
|
||||
}
|
||||
spin_unlock(&(sp_ctx->request_count_lock));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* This function returns a pointer to the context of the Secure Partition that
|
||||
* handles the service specified by an UUID. It returns NULL if the UUID wasn't
|
||||
|
|
|
@ -58,6 +58,9 @@ typedef struct sp_context {
|
|||
sp_state_t state;
|
||||
spinlock_t state_lock;
|
||||
|
||||
unsigned int request_count;
|
||||
spinlock_t request_count_lock;
|
||||
|
||||
/* Base and size of the shared SPM<->SP buffer */
|
||||
uintptr_t spm_sp_buffer_base;
|
||||
size_t spm_sp_buffer_size;
|
||||
|
@ -80,6 +83,11 @@ void sp_state_set(sp_context_t *sp_ptr, sp_state_t state);
|
|||
void sp_state_wait_switch(sp_context_t *sp_ptr, sp_state_t from, sp_state_t to);
|
||||
int sp_state_try_switch(sp_context_t *sp_ptr, sp_state_t from, sp_state_t to);
|
||||
|
||||
/* Functions to keep track of the number of active requests per SP */
|
||||
void spm_sp_request_increase(sp_context_t *sp_ctx);
|
||||
void spm_sp_request_decrease(sp_context_t *sp_ctx);
|
||||
int spm_sp_request_increase_if_zero(sp_context_t *sp_ctx);
|
||||
|
||||
/* Functions related to the translation tables management */
|
||||
xlat_ctx_t *spm_sp_xlat_context_alloc(void);
|
||||
void sp_map_memory_regions(sp_context_t *sp_ctx);
|
||||
|
|
Loading…
Add table
Reference in a new issue