diff options
author | Jett Rink <jettrink@chromium.org> | 2019-11-19 09:50:46 -0700 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2019-11-22 20:23:52 +0000 |
commit | 044f15584125158c867f581004551b7d4e82b9ac (patch) | |
tree | 542ee6f18e96846283fcf0ccd69470547d24864b /common | |
parent | 33991367ca56493c68dc2fd6937d7858a39d2811 (diff) | |
download | chrome-ec-044f15584125158c867f581004551b7d4e82b9ac.tar.gz |
usbc: fix storm tracker overflow issue
If there is no USB-C interrupt activity for 2^31 microseconds, then
there are more than ALERT_STORM_MAX_COUNT events within 2^31
microsecond (instead of ALERT_STORM_INTERVAL), then the interrupt
storm would incorrectly detect a storm and disable the port due
to incorrect math regarding 32-bit overflow.
BRANCH=octopus and all branches with original storm detection
(CL:1650484)
BUG=b:144369187
TEST=unit test in CL
Change-Id: I90b888ac092f81d151538d6018771fb32f8e9c39
Signed-off-by: Jett Rink <jettrink@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1925668
Commit-Queue: Denis Brockus <dbrockus@chromium.org>
Reviewed-by: Denis Brockus <dbrockus@chromium.org>
Diffstat (limited to 'common')
-rw-r--r-- | common/usb_pd_protocol.c | 15 |
1 files changed, 9 insertions, 6 deletions
diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c index 641909cbb9..f85efa6717 100644 --- a/common/usb_pd_protocol.c +++ b/common/usb_pd_protocol.c @@ -2744,7 +2744,7 @@ void pd_interrupt_handler_task(void *p) const int port_mask = (PD_STATUS_TCPC_ALERT_0 << port); struct { int count; - uint32_t time; + timestamp_t time; } storm_tracker[CONFIG_USB_PD_PORT_MAX_COUNT] = {}; ASSERT(port >= 0 && port < CONFIG_USB_PD_PORT_MAX_COUNT); @@ -2768,14 +2768,17 @@ void pd_interrupt_handler_task(void *p) */ while ((tcpc_get_alert_status() & port_mask) && pd_is_port_enabled(port)) { - uint32_t now; + timestamp_t now; tcpc_alert(port); - now = get_time().le.lo; - if (time_after(now, storm_tracker[port].time)) { - storm_tracker[port].time = - now + ALERT_STORM_INTERVAL; + now = get_time(); + if (timestamp_expired( + storm_tracker[port].time, &now)) { + /* Reset timer into future */ + storm_tracker[port].time.val = + now.val + ALERT_STORM_INTERVAL; + /* * Start at 1 since we are processing * an interrupt now |