diff options
author | Soby Mathew <soby.mathew@arm.com> | 2017-06-23 09:28:32 +0100 |
---|---|---|
committer | Soby Mathew <soby.mathew@arm.com> | 2017-06-29 11:04:43 +0100 |
commit | 186628ee07724a8e1dd6b5cc3c38d7a035c80dea (patch) | |
tree | c44765c5d10c94e1002608cacbc74883075eb26d /framework | |
parent | c8fe48a2e86131b439fd60088907cda2810099aa (diff) |
Fix sequencing issues in TFTF
The migration to the latest model exposed some sequencing issues in TFTF
hotplug and Timer frameworks. The details are as follows:
1. The `tftf_try_cpu_on` function in the hotplug framwork invokes the CPU_ON
and then updated the `cpus_status_map[core_pos].state` based the return of
CPU_ON call. The spin lock protecting the access to the `state` was acquired
after the CPU_ON call which allowed the turned ON cpu to warm boot and execute
hotplug framework functions which depends on the state of this variable. This
resulted in assertion failures because the caller CPU still has not had a
chance to update the variable. This could be solved acquiring the spin lock
prior to making the CPU_ON call, but this solution is not adopted because some
of the CPU_ON Stress test requires to make concurrent calls to PSCI_CPU_ON to
trigger race conditions. Hence the solution is to delay the woken up CPU till
the caller CPU has had a chance to update the variable.
2. The timer handler function in timer framework had a similar problem wherein
`tftf_send_sgi` wokeup the target CPU and it accessed the `interrupt_req_time`
in `tftf_program_timer` prior to the update by the timer handler. This is
resolved by doing the update prior to the `tftf_send_sgi`. Also a dsbish()
is added in the `tftf_send_sgi` so as to ensure that all memory accesses
are completed prior to triggering the SGI.
Change-Id: I7afe99653032fc3ec4a799e58436f5efc4d844a9
Signed-off-by: Soby Mathew <soby.mathew@arm.com>
Diffstat (limited to 'framework')
-rw-r--r-- | framework/timer/timer_framework.c | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/framework/timer/timer_framework.c b/framework/timer/timer_framework.c index 7928378..90073ec 100644 --- a/framework/timer/timer_framework.c +++ b/framework/timer/timer_framework.c @@ -61,7 +61,7 @@ static const plat_timer_t *plat_timer_info; /* * Interrupt requested time by cores in terms of absolute time. */ -static unsigned long long interrupt_req_time[PLATFORM_CORE_COUNT]; +static volatile unsigned long long interrupt_req_time[PLATFORM_CORE_COUNT]; /* * Contains the target core number of the timer interrupt. */ @@ -472,8 +472,8 @@ int tftf_timer_framework_handler(void *data) for (int i = 0; i < PLATFORM_CORE_COUNT; i++) { if ((interrupt_req_time[i] <= (current_time + TIMER_STEP_VALUE))) { - tftf_send_sgi(IRQ_WAKE_SGI, i); interrupt_req_time[i] = INVALID_TIME; + tftf_send_sgi(IRQ_WAKE_SGI, i); } } |