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
dbc80717
Commit
dbc80717
authored
Feb 01, 2016
by
danh-arm
Browse files
Merge pull request #511 from soby-mathew/sm/psci_on_race_v2
Fix PSCI CPU ON race when setting state to ON_PENDING
parents
1a3986a4
203cdfe2
Changes
3
Hide whitespace changes
Inline
Side-by-side
services/std_svc/psci/psci_off.c
View file @
dbc80717
...
...
@@ -129,10 +129,13 @@ exit:
* Set the affinity info state to OFF. This writes directly to
* main memory as caches are disabled, so cache maintenance is
* required to ensure that later cached reads of aff_info_state
* return AFF_STATE_OFF.
* return AFF_STATE_OFF. A dsbish() ensures ordering of the
* update to the affinity info state prior to cache line
* invalidation.
*/
flush_cpu_data
(
psci_svc_cpu_data
.
aff_info_state
);
psci_set_aff_info_state
(
AFF_STATE_OFF
);
dsbish
();
inv_cpu_data
(
psci_svc_cpu_data
.
aff_info_state
);
/*
...
...
services/std_svc/psci/psci_on.c
View file @
dbc80717
...
...
@@ -56,24 +56,6 @@ static int cpu_on_validate_state(aff_info_state_t aff_state)
return
PSCI_E_SUCCESS
;
}
/*******************************************************************************
* This function sets the aff_info_state in the per-cpu data of the CPU
* specified by cpu_idx
******************************************************************************/
static
void
psci_set_aff_info_state_by_idx
(
unsigned
int
cpu_idx
,
aff_info_state_t
aff_state
)
{
set_cpu_data_by_index
(
cpu_idx
,
psci_svc_cpu_data
.
aff_info_state
,
aff_state
);
/*
* Flush aff_info_state as it will be accessed with caches turned OFF.
*/
flush_cpu_data_by_index
(
cpu_idx
,
psci_svc_cpu_data
.
aff_info_state
);
}
/*******************************************************************************
* Generic handler which is called to physically power on a cpu identified by
* its mpidr. It performs the generic, architectural, platform setup and state
...
...
@@ -90,6 +72,7 @@ int psci_cpu_on_start(u_register_t target_cpu,
{
int
rc
;
unsigned
int
target_idx
=
plat_core_pos_by_mpidr
(
target_cpu
);
aff_info_state_t
target_aff_state
;
/*
* This function must only be called on platforms where the
...
...
@@ -119,8 +102,26 @@ int psci_cpu_on_start(u_register_t target_cpu,
/*
* Set the Affinity info state of the target cpu to ON_PENDING.
* Flush aff_info_state as it will be accessed with caches
* turned OFF.
*/
psci_set_aff_info_state_by_idx
(
target_idx
,
AFF_STATE_ON_PENDING
);
flush_cpu_data_by_index
(
target_idx
,
psci_svc_cpu_data
.
aff_info_state
);
/*
* The cache line invalidation by the target CPU after setting the
* state to OFF (see psci_do_cpu_off()), could cause the update to
* aff_info_state to be invalidated. Retry the update if the target
* CPU aff_info_state is not ON_PENDING.
*/
target_aff_state
=
psci_get_aff_info_state_by_idx
(
target_idx
);
if
(
target_aff_state
!=
AFF_STATE_ON_PENDING
)
{
assert
(
target_aff_state
==
AFF_STATE_OFF
);
psci_set_aff_info_state_by_idx
(
target_idx
,
AFF_STATE_ON_PENDING
);
flush_cpu_data_by_index
(
target_idx
,
psci_svc_cpu_data
.
aff_info_state
);
assert
(
psci_get_aff_info_state_by_idx
(
target_idx
)
==
AFF_STATE_ON_PENDING
);
}
/*
* Perform generic, architecture and platform specific handling.
...
...
@@ -136,9 +137,11 @@ int psci_cpu_on_start(u_register_t target_cpu,
if
(
rc
==
PSCI_E_SUCCESS
)
/* Store the re-entry information for the non-secure world. */
cm_init_context_by_index
(
target_idx
,
ep
);
else
else
{
/* Restore the state on error. */
psci_set_aff_info_state_by_idx
(
target_idx
,
AFF_STATE_OFF
);
flush_cpu_data_by_index
(
target_idx
,
psci_svc_cpu_data
.
aff_info_state
);
}
exit:
psci_spin_unlock_cpu
(
target_idx
);
...
...
services/std_svc/psci/psci_private.h
View file @
dbc80717
...
...
@@ -78,6 +78,9 @@
get_cpu_data(psci_svc_cpu_data.aff_info_state)
#define psci_get_aff_info_state_by_idx(idx) \
get_cpu_data_by_index(idx, psci_svc_cpu_data.aff_info_state)
#define psci_set_aff_info_state_by_idx(idx, aff_state) \
set_cpu_data_by_index(idx, psci_svc_cpu_data.aff_info_state,\
aff_state)
#define psci_get_suspend_pwrlvl() \
get_cpu_data(psci_svc_cpu_data.target_pwrlvl)
#define psci_set_suspend_pwrlvl(target_lvl) \
...
...
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