Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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()

+45 -8
+3 -2
drivers/thunderbolt/retimer.c
··· 516 516 */ 517 517 tb_retimer_set_inbound_sbtx(port); 518 518 519 - for (i = 1; i <= TB_MAX_RETIMER_INDEX; i++) { 519 + for (max = 1, i = 1; i <= TB_MAX_RETIMER_INDEX; i++) { 520 520 /* 521 521 * Last retimer is true only for the last on-board 522 522 * retimer (the one connected directly to the Type-C ··· 527 527 last_idx = i; 528 528 else if (ret < 0) 529 529 break; 530 + 531 + max = i; 530 532 } 531 533 532 - max = i; 533 534 ret = 0; 534 535 535 536 /* Add retimers if they do not exist already */
+42 -6
drivers/thunderbolt/tb.c
··· 288 288 device_for_each_child(&sw->dev, NULL, tb_increase_switch_tmu_accuracy); 289 289 } 290 290 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 + 291 309 static int tb_enable_tmu(struct tb_switch *sw) 292 310 { 293 311 int ret; ··· 320 302 ret = tb_switch_tmu_configure(sw, 321 303 TB_SWITCH_TMU_MODE_MEDRES_ENHANCED_UNI); 322 304 if (ret == -EOPNOTSUPP) { 323 - if (tb_switch_clx_is_enabled(sw, TB_CL1)) 324 - ret = tb_switch_tmu_configure(sw, 325 - TB_SWITCH_TMU_MODE_LOWRES); 326 - else 327 - ret = tb_switch_tmu_configure(sw, 328 - TB_SWITCH_TMU_MODE_HIFI_BI); 305 + if (tb_switch_clx_is_enabled(sw, TB_CL1)) { 306 + /* 307 + * Figure out uni-directional HiFi TMU requirements 308 + * currently in the domain. If there are no 309 + * uni-directional HiFi requirements we can put the TMU 310 + * into LowRes mode. 311 + * 312 + * Deliberately skip bi-directional HiFi links 313 + * as these work independently of other links 314 + * (and they do not allow any CL states anyway). 315 + */ 316 + if (tb_tmu_hifi_uni_required(sw->tb)) 317 + ret = tb_switch_tmu_configure(sw, 318 + TB_SWITCH_TMU_MODE_HIFI_UNI); 319 + else 320 + ret = tb_switch_tmu_configure(sw, 321 + TB_SWITCH_TMU_MODE_LOWRES); 322 + } else { 323 + ret = tb_switch_tmu_configure(sw, TB_SWITCH_TMU_MODE_HIFI_BI); 324 + } 325 + 326 + /* If not supported, fallback to bi-directional HiFi */ 327 + if (ret == -EOPNOTSUPP) 328 + ret = tb_switch_tmu_configure(sw, TB_SWITCH_TMU_MODE_HIFI_BI); 329 329 } 330 330 if (ret) 331 331 return ret;