diff options
author | Evan Green <evgreen@chromium.org> | 2021-04-06 09:41:14 -0700 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2021-04-07 20:35:51 +0000 |
commit | 5e057d61ff8e37c9a1f334c9ae68102172aa3c14 (patch) | |
tree | d147c349b819429d489999c943476985288fe414 /common/ocpc.c | |
parent | e8d4831bd75804cc63c679204719dcd163c2637d (diff) | |
download | chrome-ec-5e057d61ff8e37c9a1f334c9ae68102172aa3c14.tar.gz |
hooks: Avoid torn accesses in the hook task
The hook task runs at the lowest priority, and both reads from and
writes to a data structure that can be changed out from under it at any
time. This is unsafe, and can cause missed hook events and double hook
events.
For example, the hook task reads __deferred_until[i], a 64-bit value, in
two 32-bit reads. If the hook task is interrupted during this read, and
the interruption changes the value, the hook task may read a totally
bogus value. This is rare, as overflows across this 32-bit boundary
don't happen often, but leads to unpredicable behavior when they do.
The writes the hook task does are also problematic, since for instance
the hook may have been rescheduled just after the slow old hook task
entered its if clause deciding to run the hook, but before it clobbered
__deferred_until[i] back to zero. Things get worse if the hook routine
pointer ever changes, though I don't think we're currently doing that
anywhere today.
Instead, disable interrupts while the hook data structure is being
manipulated as a makeshift lock around it. Remove the defer_new_call
variable as well, since the new deadline is now computed atomically (and
without the possibility of torn reads).
BUG=b:178660461, b:179062230
BRANCH=None
TEST=Run suspend 2500 on Boten, observe no spurious s0ix timeouts.
Signed-off-by: Evan Green <evgreen@chromium.org>
Change-Id: Iff0d596014e1e79dd9691d363fdc8e54bfe2dff0
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2805222
Reviewed-by: Wai-Hong Tam <waihong@google.com>
Diffstat (limited to 'common/ocpc.c')
0 files changed, 0 insertions, 0 deletions