thunderbolt: Do not allocate switch if depth is greater than 6
authorMika Westerberg <mika.westerberg@linux.intel.com>
Sun, 30 Dec 2018 10:14:46 +0000 (12:14 +0200)
committerMika Westerberg <mika.westerberg@linux.intel.com>
Thu, 18 Apr 2019 08:18:51 +0000 (11:18 +0300)
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>
drivers/thunderbolt/icm.c
drivers/thunderbolt/switch.c
drivers/thunderbolt/tb.h

index 7c923e16a7d82b41532a0ddf0201289f2add1410..bec360eef6cf73ee15913c95b2bfd9506ec72bf8 100644 (file)
@@ -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;
        }
index 7fa4ab076404d4c37e865f8bcf213ae895fd148d..1e29c06947af7c5f8ef83ac3dcbc803476ae6b60 100644 (file)
@@ -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 */
index f7b0c43c29a73b21277ac519f1e670e0c68f9299..93c1ea21feeb744d68e9ce1f1298b478c98a2170 100644 (file)
@@ -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