Skip to content

Commit 5963e07

Browse files
committed
Merge tag 'thunderbolt-for-v6.12-rc5' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/westeri/thunderbolt into usb-linus
Mika writes: thunderbolt: Fixes for v6.12-rc5 This includes following USB4/Thunderbolt fixes for v6.12-rc5: - Fix KASAN reported stack out-of-bounds read - Honor Time Management Unit (TMU) requirements in the domain when configuring TMU mode of a newly plugged router. Both have been in linux-next with no reported issues. * tag 'thunderbolt-for-v6.12-rc5' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/westeri/thunderbolt: thunderbolt: Honor TMU requirements in the domain when setting TMU mode thunderbolt: Fix KASAN reported stack out-of-bounds read in tb_retimer_scan()
2 parents 42f7652 + 3cea8af commit 5963e07

File tree

2 files changed

+45
-8
lines changed

2 files changed

+45
-8
lines changed

drivers/thunderbolt/retimer.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -516,7 +516,7 @@ int tb_retimer_scan(struct tb_port *port, bool add)
516516
*/
517517
tb_retimer_set_inbound_sbtx(port);
518518

519-
for (i = 1; i <= TB_MAX_RETIMER_INDEX; i++) {
519+
for (max = 1, i = 1; i <= TB_MAX_RETIMER_INDEX; i++) {
520520
/*
521521
* Last retimer is true only for the last on-board
522522
* retimer (the one connected directly to the Type-C
@@ -527,9 +527,10 @@ int tb_retimer_scan(struct tb_port *port, bool add)
527527
last_idx = i;
528528
else if (ret < 0)
529529
break;
530+
531+
max = i;
530532
}
531533

532-
max = i;
533534
ret = 0;
534535

535536
/* Add retimers if they do not exist already */

drivers/thunderbolt/tb.c

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,24 @@ static void tb_increase_tmu_accuracy(struct tb_tunnel *tunnel)
288288
device_for_each_child(&sw->dev, NULL, tb_increase_switch_tmu_accuracy);
289289
}
290290

291+
static int tb_switch_tmu_hifi_uni_required(struct device *dev, void *not_used)
292+
{
293+
struct tb_switch *sw = tb_to_switch(dev);
294+
295+
if (sw && tb_switch_tmu_is_enabled(sw) &&
296+
tb_switch_tmu_is_configured(sw, TB_SWITCH_TMU_MODE_HIFI_UNI))
297+
return 1;
298+
299+
return device_for_each_child(dev, NULL,
300+
tb_switch_tmu_hifi_uni_required);
301+
}
302+
303+
static bool tb_tmu_hifi_uni_required(struct tb *tb)
304+
{
305+
return device_for_each_child(&tb->dev, NULL,
306+
tb_switch_tmu_hifi_uni_required) == 1;
307+
}
308+
291309
static int tb_enable_tmu(struct tb_switch *sw)
292310
{
293311
int ret;
@@ -302,12 +320,30 @@ static int tb_enable_tmu(struct tb_switch *sw)
302320
ret = tb_switch_tmu_configure(sw,
303321
TB_SWITCH_TMU_MODE_MEDRES_ENHANCED_UNI);
304322
if (ret == -EOPNOTSUPP) {
305-
if (tb_switch_clx_is_enabled(sw, TB_CL1))
306-
ret = tb_switch_tmu_configure(sw,
307-
TB_SWITCH_TMU_MODE_LOWRES);
308-
else
309-
ret = tb_switch_tmu_configure(sw,
310-
TB_SWITCH_TMU_MODE_HIFI_BI);
323+
if (tb_switch_clx_is_enabled(sw, TB_CL1)) {
324+
/*
325+
* Figure out uni-directional HiFi TMU requirements
326+
* currently in the domain. If there are no
327+
* uni-directional HiFi requirements we can put the TMU
328+
* into LowRes mode.
329+
*
330+
* Deliberately skip bi-directional HiFi links
331+
* as these work independently of other links
332+
* (and they do not allow any CL states anyway).
333+
*/
334+
if (tb_tmu_hifi_uni_required(sw->tb))
335+
ret = tb_switch_tmu_configure(sw,
336+
TB_SWITCH_TMU_MODE_HIFI_UNI);
337+
else
338+
ret = tb_switch_tmu_configure(sw,
339+
TB_SWITCH_TMU_MODE_LOWRES);
340+
} else {
341+
ret = tb_switch_tmu_configure(sw, TB_SWITCH_TMU_MODE_HIFI_BI);
342+
}
343+
344+
/* If not supported, fallback to bi-directional HiFi */
345+
if (ret == -EOPNOTSUPP)
346+
ret = tb_switch_tmu_configure(sw, TB_SWITCH_TMU_MODE_HIFI_BI);
311347
}
312348
if (ret)
313349
return ret;

0 commit comments

Comments
 (0)