--- a/sys/dev/drm/amd/amdgpu/amdgpu_atombios.c +++ b/sys/dev/drm/amd/amdgpu/amdgpu_atombios.c @@ -1415,9 +1415,13 @@ static ATOM_VOLTAGE_OBJECT_V3 *amdgpu_atombios_lookup_voltage_object_v3(ATOM_VOL u8 voltage_type, u8 voltage_mode) { u32 size = le16_to_cpu(v3->sHeader.usStructureSize); u32 offset = offsetof(ATOM_VOLTAGE_OBJECT_INFO_V3_1, asVoltageObj[0]); u8 *start = (u8*)v3; + u32 obj_size; while (offset < size) { ATOM_VOLTAGE_OBJECT_V3 *vo = (ATOM_VOLTAGE_OBJECT_V3 *)(start + offset); if ((vo->asGpioVoltageObj.sHeader.ucVoltageType == voltage_type) && (vo->asGpioVoltageObj.sHeader.ucVoltageMode == voltage_mode)) return vo; - offset += le16_to_cpu(vo->asGpioVoltageObj.sHeader.usSize); + /* DF-4155: a zero-size object would loop forever */ + obj_size = le16_to_cpu(vo->asGpioVoltageObj.sHeader.usSize); + if (obj_size < sizeof(ATOM_VOLTAGE_OBJECT_V3)) + break; + offset += obj_size; } return NULL; }