forked from Minki/linux
ARM: qcom: scm: Flush the command buffer only instead of the entire cache
scm_call flushes the entire cache before calling into the secure world. This is both a performance penalty as well as insufficient on SMP systems where the CPUs possess a write-back L1 cache. Flush only the command and response buffers instead, moving the responsibility of flushing any other cached buffer (being passed to the secure world) to callers. Signed-off-by: Vikram Mulukutla <markivx@codeaurora.org> Signed-off-by: Stephen Boyd <sboyd@codeaurora.org> Signed-off-by: Kumar Gala <galak@codeaurora.org>
This commit is contained in:
parent
30cbb0c01b
commit
404b5a97f5
@ -196,12 +196,12 @@ static int __scm_call(const struct scm_command *cmd)
|
||||
u32 cmd_addr = virt_to_phys(cmd);
|
||||
|
||||
/*
|
||||
* Flush the entire cache here so callers don't have to remember
|
||||
* to flush the cache when passing physical addresses to the secure
|
||||
* side in the buffer.
|
||||
* Flush the command buffer so that the secure world sees
|
||||
* the correct data.
|
||||
*/
|
||||
flush_cache_all();
|
||||
outer_flush_all();
|
||||
__cpuc_flush_dcache_area((void *)cmd, cmd->len);
|
||||
outer_flush_range(cmd_addr, cmd_addr + cmd->len);
|
||||
|
||||
ret = smc(cmd_addr);
|
||||
if (ret < 0)
|
||||
ret = scm_remap_error(ret);
|
||||
@ -238,6 +238,13 @@ static void scm_inv_range(unsigned long start, unsigned long end)
|
||||
* @resp_len: length of the response buffer
|
||||
*
|
||||
* Sends a command to the SCM and waits for the command to finish processing.
|
||||
*
|
||||
* A note on cache maintenance:
|
||||
* Note that any buffers that are expected to be accessed by the secure world
|
||||
* must be flushed before invoking scm_call and invalidated in the cache
|
||||
* immediately after scm_call returns. Cache maintenance on the command and
|
||||
* response buffers is taken care of by scm_call; however, callers are
|
||||
* responsible for any other cached buffers passed over to the secure world.
|
||||
*/
|
||||
int scm_call(u32 svc_id, u32 cmd_id, const void *cmd_buf, size_t cmd_len,
|
||||
void *resp_buf, size_t resp_len)
|
||||
|
Loading…
Reference in New Issue
Block a user