| @@ -1075,15 +1075,34 @@ parse_device_mapping(struct drm_i915_private *dev_priv, · 1074 unmodified lines |
| 1075 | const union child_device_config *p_child; | 1075 | const union child_device_config *p_child; |
| 1076 | union child_device_config *child_dev_ptr; | 1076 | union child_device_config *child_dev_ptr; |
| 1077 | int i, child_device_num, count; | 1077 | int i, child_device_num, count; |
| 1078 | u16 block_size; | 1078 | u8 expected_size; |
| | 1079 | u16 block_size; |
| 1079 | | 1080 | |
| 1080 | p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS); | 1081 | p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS); |
| 1081 | if (!p_defs) { | 1082 | if (!p_defs) { |
| 1082 | DRM_DEBUG_KMS("No general definition block is found, no devices defined.\n"); | 1083 | DRM_DEBUG_KMS("No general definition block is found, no devices defined.\n"); |
| 1083 | return; | 1084 | return; |
| 1084 | } | 1085 | } |
| 1085 | if (p_defs->child_dev_size < sizeof(*p_child)) { | 1086 | if (bdb->version < 195) { |
| 1086 | DRM_ERROR("General definiton block child device size is too small.\n"); | 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 | return; | 1106 | return; |
| 1088 | } | 1107 | } |
| 1089 | /* get the block size of general definitions */ | 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 | child_dev_ptr = dev_priv->vbt.child_dev + count; | 1150 | child_dev_ptr = dev_priv->vbt.child_dev + count; |
| 1132 | count++; | 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 | return; | 1154 | return; |
| 1136 | } | 1155 | } |