BACKPORT: x86: harden tsc udelay() function
Since the TSC udelay() function can be used in SMM that means the TSC can count up to whatever value. The current loop was not handling TSC rollover properly. In most cases this should not matter as the TSC typically starts ticking at value 0, and it would take a very long time to roll it over. However, it is my understanding that this behavior is not guaranteed. Theoretically the TSC could start or be be written to with a large value that would cause the rollover. BUG=None BRANCH=None TEST=Compiled and booted Change-Id: I0f86672e0951b51c791c63bb1173eb371b347f40 Signed-off-by: Aaron Durbin <adurbin@chromium.org> Reviewed-on: https://gerrit.chromium.org/gerrit/50457 Reviewed-by: Stefan Reinauer <reinauer@google.com>
This commit is contained in:
parent
a8e1aec4b3
commit
7f20f4cae9
1 changed files with 8 additions and 8 deletions
|
|
@ -172,18 +172,18 @@ static inline unsigned long get_clocks_per_usec(void)
|
|||
|
||||
void udelay(unsigned us)
|
||||
{
|
||||
unsigned long long count;
|
||||
unsigned long long stop;
|
||||
unsigned long long clocks;
|
||||
unsigned long long start;
|
||||
unsigned long long current;
|
||||
unsigned long long clocks;
|
||||
|
||||
start = rdtscll();
|
||||
clocks = us;
|
||||
clocks *= get_clocks_per_usec();
|
||||
count = rdtscll();
|
||||
stop = clocks + count;
|
||||
while(stop > count) {
|
||||
current = rdtscll();
|
||||
while((current - start) < clocks) {
|
||||
cpu_relax();
|
||||
count = rdtscll();
|
||||
}
|
||||
current = rdtscll();
|
||||
}
|
||||
}
|
||||
|
||||
#if CONFIG_TSC_MONOTONIC_TIMER && !defined(__PRE_RAM__) && !defined(__SMM__)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue