summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorJett Rink <jettrink@chromium.org>2019-11-19 09:50:46 -0700
committerCommit Bot <commit-bot@chromium.org>2019-11-22 20:23:52 +0000
commit044f15584125158c867f581004551b7d4e82b9ac (patch)
tree542ee6f18e96846283fcf0ccd69470547d24864b /common
parent33991367ca56493c68dc2fd6937d7858a39d2811 (diff)
downloadchrome-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.c15
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