| @@ -1075,15 +1075,34 @@ parse_device_mapping(struct drm_i915_private *dev_priv, · 1074 unmodified lines |
| 1075 | 1075 | const union child_device_config *p_child; |
| 1076 | 1076 | union child_device_config *child_dev_ptr; |
| 1077 | 1077 | int i, child_device_num, count; |
| 1078 | | − u16 block_size; |
| 1078 | + u8 expected_size; |
| 1079 | + u16 block_size; |
| 1079 | 1080 | |
| 1080 | 1081 | p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS); |
| 1081 | 1082 | if (!p_defs) { |
| 1082 | 1083 | DRM_DEBUG_KMS("No general definition block is found, no devices defined.\n"); |
| 1083 | 1084 | return; |
| 1084 | 1085 | } |
| 1085 | | − if (p_defs->child_dev_size < sizeof(*p_child)) { |
| 1086 | | − DRM_ERROR("General definiton block child device size is too small.\n"); |
| 1086 | + if (bdb->version < 195) { |
| 1087 | + expected_size = 33; |
| 1088 | + } else if (bdb->version == 195) { |
| 1089 | + expected_size = 37; |
| 1090 | + } else if (bdb->version <= 197) { |
| 1091 | + expected_size = 38; |
| 1092 | + } else { |
| 1093 | + expected_size = 38; |
| 1094 | + DRM_DEBUG_DRIVER("Expected child_device_config size for BDB version %u not known; assuming %u\n", |
| 1095 | + expected_size, bdb->version); |
| 1096 | + } |
| 1097 | + |
| 1098 | + if (expected_size > sizeof(*p_child)) { |
| 1099 | + DRM_ERROR("child_device_config cannot fit in p_child\n"); |
| 1100 | + return; |
| 1101 | + } |
| 1102 | + |
| 1103 | + if (p_defs->child_dev_size != expected_size) { |
| 1104 | + DRM_ERROR("Size mismatch; child_device_config size=%u (expected %u); bdb->version: %u\n", |
| 1105 | + p_defs->child_dev_size, expected_size, bdb->version); |
| 1087 | 1106 | return; |
| 1088 | 1107 | } |
| 1089 | 1108 | /* get the block size of general definitions */ |
| @@ -1130,7 +1149,7 @@ parse_device_mapping(struct drm_i915_private *dev_priv, · 40 unmodified lines |
| 1130 | 1149 | |
| 1131 | 1150 | child_dev_ptr = dev_priv->vbt.child_dev + count; |
| 1132 | 1151 | count++; |
| 1133 | | − memcpy(child_dev_ptr, p_child, sizeof(*p_child)); |
| 1152 | + memcpy(child_dev_ptr, p_child, p_defs->child_dev_size); |
| 1134 | 1153 | } |
| 1135 | 1154 | return; |
| 1136 | 1155 | } |