Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
adam.huang
Arm Trusted Firmware
Commits
cef7b3ce
Commit
cef7b3ce
authored
Dec 23, 2016
by
davidcunado-arm
Committed by
GitHub
Dec 23, 2016
Browse files
Merge pull request #798 from douglas-raillard-arm/dr/fix_std_smc_after_suspend
Abort preempted TSP STD SMC after PSCI CPU suspend
parents
153e5eb8
3df6012a
Changes
7
Hide whitespace changes
Inline
Side-by-side
bl32/tsp/aarch64/tsp_entrypoint.S
View file @
cef7b3ce
...
...
@@ -180,6 +180,7 @@ func tsp_vector_table
b
tsp_sel1_intr_entry
b
tsp_system_off_entry
b
tsp_system_reset_entry
b
tsp_abort_std_smc_entry
endfunc
tsp_vector_table
/*---------------------------------------------
...
...
@@ -441,3 +442,30 @@ func tsp_std_smc_entry
/
*
Should
never
reach
here
*/
no_ret
plat_panic_handler
endfunc
tsp_std_smc_entry
/*---------------------------------------------------------------------
*
This
entrypoint
is
used
by
the
TSPD
to
abort
a
pre
-
empted
Standard
*
SMC
.
It
could
be
on
behalf
of
non
-
secure
world
or
because
a
CPU
*
suspend
/
CPU
off
request
needs
to
abort
the
preempted
SMC
.
*
--------------------------------------------------------------------
*/
func
tsp_abort_std_smc_entry
/
*
*
Exceptions
masking
is
already
done
by
the
TSPD
when
entering
this
*
hook
so
there
is
no
need
to
do
it
here
.
*/
/
*
Reset
the
stack
used
by
the
pre
-
empted
SMC
*/
bl
plat_set_my_stack
/
*
*
Allow
some
cleanup
such
as
releasing
locks
.
*/
bl
tsp_abort_smc_handler
restore_args_call_smc
/
*
Should
never
reach
here
*/
bl
plat_panic_handler
endfunc
tsp_abort_std_smc_entry
bl32/tsp/tsp_main.c
View file @
cef7b3ce
/*
* Copyright (c) 2013-201
5
, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2013-201
6
, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
...
...
@@ -416,3 +416,20 @@ tsp_args_t *tsp_smc_handler(uint64_t func,
0
,
0
,
0
,
0
);
}
/*******************************************************************************
* TSP smc abort handler. This function is called when aborting a preemtped
* standard SMC request. It should cleanup all resources owned by the SMC
* handler such as locks or dynamically allocated memory so following SMC
* request are executed in a clean environment.
******************************************************************************/
tsp_args_t
*
tsp_abort_smc_handler
(
uint64_t
func
,
uint64_t
arg1
,
uint64_t
arg2
,
uint64_t
arg3
,
uint64_t
arg4
,
uint64_t
arg5
,
uint64_t
arg6
,
uint64_t
arg7
)
{
return
set_smc_args
(
TSP_ABORT_DONE
,
0
,
0
,
0
,
0
,
0
,
0
,
0
);
}
include/bl32/tsp/tsp.h
View file @
cef7b3ce
/*
* Copyright (c) 2013-201
4
, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2013-201
6
, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
...
...
@@ -41,6 +41,7 @@
#define TSP_SUSPEND_DONE 0xf2000003
#define TSP_RESUME_DONE 0xf2000004
#define TSP_PREEMPTED 0xf2000005
#define TSP_ABORT_DONE 0xf2000007
#define TSP_SYSTEM_OFF_DONE 0xf2000008
#define TSP_SYSTEM_RESET_DONE 0xf2000009
...
...
@@ -80,11 +81,18 @@
/* SMC function ID to request a previously preempted std smc */
#define TSP_FID_RESUME TSP_STD_FID(0x3000)
/*
* SMC function ID to request abortion of a previously preempted std smc. A
* fast SMC is used so that the TSP abort handler does not have to be
* reentrant.
*/
#define TSP_FID_ABORT TSP_FAST_FID(0x3001)
/*
* Total number of function IDs implemented for services offered to NS clients.
* The function IDs are defined above
*/
#define TSP_NUM_FID 0x
4
#define TSP_NUM_FID 0x
5
/* TSP implementation version numbers */
#define TSP_VERSION_MAJOR 0x0
/* Major version */
...
...
@@ -117,6 +125,7 @@ typedef struct tsp_vectors {
tsp_vector_isn_t
sel1_intr_entry
;
tsp_vector_isn_t
system_off_entry
;
tsp_vector_isn_t
system_reset_entry
;
tsp_vector_isn_t
abort_std_smc_entry
;
}
tsp_vectors_t
;
...
...
services/spd/tspd/tspd_common.c
View file @
cef7b3ce
/*
* Copyright (c) 2013-201
4
, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2013-201
6
, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
...
...
@@ -32,7 +32,9 @@
#include <assert.h>
#include <bl_common.h>
#include <context_mgmt.h>
#include <debug.h>
#include <string.h>
#include <tsp.h>
#include "tspd_private.h"
/*******************************************************************************
...
...
@@ -129,3 +131,31 @@ void tspd_synchronous_sp_exit(tsp_context_t *tsp_ctx, uint64_t ret)
/* Should never reach here */
assert
(
0
);
}
/*******************************************************************************
* This function takes an SP context pointer and abort any preempted SMC
* request.
* Return 1 if there was a preempted SMC request, 0 otherwise.
******************************************************************************/
int
tspd_abort_preempted_smc
(
tsp_context_t
*
tsp_ctx
)
{
if
(
!
get_std_smc_active_flag
(
tsp_ctx
->
state
))
return
0
;
/* Abort any preempted SMC request */
clr_std_smc_active_flag
(
tsp_ctx
->
state
);
/*
* Arrange for an entry into the test secure payload. It will
* be returned via TSP_ABORT_DONE case in tspd_smc_handler.
*/
cm_set_elr_el3
(
SECURE
,
(
uint64_t
)
&
tsp_vectors
->
abort_std_smc_entry
);
uint64_t
rc
=
tspd_synchronous_sp_entry
(
tsp_ctx
);
if
(
rc
!=
0
)
panic
();
return
1
;
}
services/spd/tspd/tspd_main.c
View file @
cef7b3ce
/*
* Copyright (c) 2013-201
5
, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2013-201
6
, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
...
...
@@ -459,6 +459,11 @@ uint64_t tspd_smc_handler(uint32_t smc_fid,
*/
tspd_synchronous_sp_exit
(
tsp_ctx
,
x1
);
#endif
/*
* This function ID is used only by the SP to indicate it has finished
* aborting a preempted Standard SMC request.
*/
case
TSP_ABORT_DONE
:
/*
* These function IDs are used only by the SP to indicate it has
...
...
@@ -596,6 +601,26 @@ uint64_t tspd_smc_handler(uint32_t smc_fid,
}
break
;
/*
* Request from the non-secure world to abort a preempted Standard SMC
* call.
*/
case
TSP_FID_ABORT
:
/* ABORT should only be invoked by normal world */
if
(
!
ns
)
{
assert
(
0
);
break
;
}
/* Abort the preempted SMC request */
if
(
!
tspd_abort_preempted_smc
(
tsp_ctx
))
/*
* If there was no preempted SMC to abort, return
* SMC_UNK.
*/
SMC_RET1
(
handle
,
SMC_UNK
);
break
;
/*
* Request from non secure world to resume the preempted
...
...
services/spd/tspd/tspd_pm.c
View file @
cef7b3ce
/*
* Copyright (c) 2013-201
5
, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2013-201
6
, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
...
...
@@ -58,6 +58,12 @@ static int32_t tspd_cpu_off_handler(uint64_t unused)
assert
(
tsp_vectors
);
assert
(
get_tsp_pstate
(
tsp_ctx
->
state
)
==
TSP_PSTATE_ON
);
/*
* Abort any preempted SMC request before overwriting the SECURE
* context.
*/
tspd_abort_preempted_smc
(
tsp_ctx
);
/* Program the entry point and enter the TSP */
cm_set_elr_el3
(
SECURE
,
(
uint64_t
)
&
tsp_vectors
->
cpu_off_entry
);
rc
=
tspd_synchronous_sp_entry
(
tsp_ctx
);
...
...
@@ -75,7 +81,7 @@ static int32_t tspd_cpu_off_handler(uint64_t unused)
*/
set_tsp_pstate
(
tsp_ctx
->
state
,
TSP_PSTATE_OFF
);
return
0
;
return
0
;
}
/*******************************************************************************
...
...
@@ -91,6 +97,12 @@ static void tspd_cpu_suspend_handler(uint64_t max_off_pwrlvl)
assert
(
tsp_vectors
);
assert
(
get_tsp_pstate
(
tsp_ctx
->
state
)
==
TSP_PSTATE_ON
);
/*
* Abort any preempted SMC request before overwriting the SECURE
* context.
*/
tspd_abort_preempted_smc
(
tsp_ctx
);
/* Program the entry point and enter the TSP */
cm_set_elr_el3
(
SECURE
,
(
uint64_t
)
&
tsp_vectors
->
cpu_suspend_entry
);
rc
=
tspd_synchronous_sp_entry
(
tsp_ctx
);
...
...
@@ -99,7 +111,7 @@ static void tspd_cpu_suspend_handler(uint64_t max_off_pwrlvl)
* Read the response from the TSP. A non-zero return means that
* something went wrong while communicating with the TSP.
*/
if
(
rc
!=
0
)
if
(
rc
)
panic
();
/* Update its context to reflect the state the TSP is in */
...
...
@@ -108,7 +120,7 @@ static void tspd_cpu_suspend_handler(uint64_t max_off_pwrlvl)
/*******************************************************************************
* This cpu has been turned on. Enter the TSP to initialise S-EL1 and other bits
* before passing control back to the Secure Monitor. Entry in S-E
l
1 is done
* before passing control back to the Secure Monitor. Entry in S-E
L
1 is done
* after initialising minimal architectural state that guarantees safe
* execution.
******************************************************************************/
...
...
@@ -205,6 +217,12 @@ static void tspd_system_off(void)
assert
(
tsp_vectors
);
assert
(
get_tsp_pstate
(
tsp_ctx
->
state
)
==
TSP_PSTATE_ON
);
/*
* Abort any preempted SMC request before overwriting the SECURE
* context.
*/
tspd_abort_preempted_smc
(
tsp_ctx
);
/* Program the entry point */
cm_set_elr_el3
(
SECURE
,
(
uint64_t
)
&
tsp_vectors
->
system_off_entry
);
...
...
@@ -225,11 +243,19 @@ static void tspd_system_reset(void)
assert
(
tsp_vectors
);
assert
(
get_tsp_pstate
(
tsp_ctx
->
state
)
==
TSP_PSTATE_ON
);
/*
* Abort any preempted SMC request before overwriting the SECURE
* context.
*/
tspd_abort_preempted_smc
(
tsp_ctx
);
/* Program the entry point */
cm_set_elr_el3
(
SECURE
,
(
uint64_t
)
&
tsp_vectors
->
system_reset_entry
);
/* Enter the TSP. We do not care about the return value because we
* must continue the reset anyway */
/*
* Enter the TSP. We do not care about the return value because we
* must continue the reset anyway
*/
tspd_synchronous_sp_entry
(
tsp_ctx
);
}
...
...
services/spd/tspd/tspd_private.h
View file @
cef7b3ce
/*
* Copyright (c) 2013-201
4
, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2013-201
6
, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
...
...
@@ -242,6 +242,7 @@ void tspd_init_tsp_ep_state(struct entry_point_info *tsp_ep,
uint32_t
rw
,
uint64_t
pc
,
tsp_context_t
*
tsp_ctx
);
int
tspd_abort_preempted_smc
(
tsp_context_t
*
tsp_ctx
);
extern
tsp_context_t
tspd_sp_context
[
TSPD_CORE_COUNT
];
extern
struct
tsp_vectors
*
tsp_vectors
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment