DF-2203 / fix.diff
diff --git a/sys/dev/drm/amd/amdgpu/amdgpu_xgmi.c b/sys/dev/drm/amd/amdgpu/amdgpu_xgmi.c index 0000000..1111111 100644 --- a/sys/dev/drm/amd/amdgpu/amdgpu_xgmi.c +++ b/sys/dev/drm/amd/amdgpu/amdgpu_xgmi.c @@ -83,8 +83,27 @@ goto exit; list_add_tail(&adev->gmc.xgmi.head, &hive->device_list); - list_for_each_entry(entry, &hive->device_list, head) + list_for_each_entry(entry, &hive->device_list, head) { + /* + * DF-2203: tmp_topology is fixed-size + * (AMDGPU_MAX_XGMI_DEVICE_PER_HIVE entries). Without this + * bound the write at tmp_topology[count++] smashes the + * stack once the hive aggregates more devices than the + * array holds (the stub psp_v11_0_xgmi_get_hive_id returns + * the same constant id for every Vega20 GPU, so all of them + * land in one hive). + */ + if (count >= AMDGPU_MAX_XGMI_DEVICE_PER_HIVE) { + dev_err(adev->dev, + "XGMI: hive %llx holds more than %d devices; " + "refusing to overflow tmp_topology", + adev->gmc.xgmi.hive_id, + AMDGPU_MAX_XGMI_DEVICE_PER_HIVE); + ret = -ENOSPC; + goto exit; + } tmp_topology[count++].device_id = entry->device_id; + } ret = psp_xgmi_get_topology_info(&adev->psp, count, tmp_topology); if (ret) { |