diff options
author | Mika Westerberg <mika.westerberg@linux.intel.com> | 2018-12-30 12:14:46 +0200 |
---|---|---|
committer | Mika Westerberg <mika.westerberg@linux.intel.com> | 2019-04-18 11:18:51 +0300 |
commit | f0342e757c271e7c6dd5adedfb6e6695c5af52bf (patch) | |
tree | beaa2c019b14a6f35e3f925a11c6ca78ad139df4 /drivers | |
parent | 09f11b6c99feaf86a26444bca85dc693b3f58f8b (diff) |
thunderbolt: Do not allocate switch if depth is greater than 6
Maximum depth in Thunderbolt topology is 6 so make sure it is not
possible to allocate switches that exceed the depth limit.
While at it update tb_switch_alloc() to use upper/lower_32_bits()
following tb_switch_alloc_safe_mode().
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/thunderbolt/icm.c | 5 | ||||
-rw-r--r-- | drivers/thunderbolt/switch.c | 18 | ||||
-rw-r--r-- | drivers/thunderbolt/tb.h | 1 |
3 files changed, 15 insertions, 9 deletions
diff --git a/drivers/thunderbolt/icm.c b/drivers/thunderbolt/icm.c index 7c923e16a7d8..bec360eef6cf 100644 --- a/drivers/thunderbolt/icm.c +++ b/drivers/thunderbolt/icm.c @@ -42,7 +42,6 @@ #define ICM_TIMEOUT 5000 /* ms */ #define ICM_APPROVE_TIMEOUT 10000 /* ms */ #define ICM_MAX_LINK 4 -#define ICM_MAX_DEPTH 6 /** * struct icm - Internal connection manager private data @@ -714,7 +713,7 @@ icm_fr_device_disconnected(struct tb *tb, const struct icm_pkg_header *hdr) depth = (pkg->link_info & ICM_LINK_INFO_DEPTH_MASK) >> ICM_LINK_INFO_DEPTH_SHIFT; - if (link > ICM_MAX_LINK || depth > ICM_MAX_DEPTH) { + if (link > ICM_MAX_LINK || depth > TB_SWITCH_MAX_DEPTH) { tb_warn(tb, "invalid topology %u.%u, ignoring\n", link, depth); return; } @@ -744,7 +743,7 @@ icm_fr_xdomain_connected(struct tb *tb, const struct icm_pkg_header *hdr) depth = (pkg->link_info & ICM_LINK_INFO_DEPTH_MASK) >> ICM_LINK_INFO_DEPTH_SHIFT; - if (link > ICM_MAX_LINK || depth > ICM_MAX_DEPTH) { + if (link > ICM_MAX_LINK || depth > TB_SWITCH_MAX_DEPTH) { tb_warn(tb, "invalid topology %u.%u, ignoring\n", link, depth); return; } diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c index 7fa4ab076404..1e29c06947af 100644 --- a/drivers/thunderbolt/switch.c +++ b/drivers/thunderbolt/switch.c @@ -1130,10 +1130,16 @@ static int tb_switch_get_generation(struct tb_switch *sw) struct tb_switch *tb_switch_alloc(struct tb *tb, struct device *parent, u64 route) { - int i; - int cap; struct tb_switch *sw; - int upstream_port = tb_cfg_get_upstream_port(tb->ctl, route); + int upstream_port; + int i, cap, depth; + + /* Make sure we do not exceed maximum topology limit */ + depth = tb_route_length(route); + if (depth > TB_SWITCH_MAX_DEPTH) + return NULL; + + upstream_port = tb_cfg_get_upstream_port(tb->ctl, route); if (upstream_port < 0) return NULL; @@ -1150,9 +1156,9 @@ struct tb_switch *tb_switch_alloc(struct tb *tb, struct device *parent, /* configure switch */ sw->config.upstream_port_number = upstream_port; - sw->config.depth = tb_route_length(route); - sw->config.route_lo = route; - sw->config.route_hi = route >> 32; + sw->config.depth = depth; + sw->config.route_hi = upper_32_bits(route); + sw->config.route_lo = lower_32_bits(route); sw->config.enabled = 0; /* initialize ports */ diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h index f7b0c43c29a7..93c1ea21feeb 100644 --- a/drivers/thunderbolt/tb.h +++ b/drivers/thunderbolt/tb.h @@ -43,6 +43,7 @@ struct tb_switch_nvm { }; #define TB_SWITCH_KEY_SIZE 32 +#define TB_SWITCH_MAX_DEPTH 6 /** * struct tb_switch - a thunderbolt switch |