static u64 intel_fbc_stolen_end(struct intel_display *display)
{
- u64 end;
+ u64 end = intel_fbc_cfb_base_max(display);
- /* The FBC hardware for BDW/SKL doesn't have access to the stolen
+ /*
+ * The FBC hardware for BDW/SKL doesn't have access to the stolen
* reserved range size, so it always assumes the maximum (8mb) is used.
* If we enable FBC using a CFB on that memory range we'll get FIFO
- * underruns, even if that range is not reserved by the BIOS. */
+ * underruns, even if that range is not reserved by the BIOS.
+ */
if (display->platform.broadwell ||
- (DISPLAY_VER(display) == 9 && !display->platform.broxton))
- end = intel_parent_stolen_area_size(display) - 8 * 1024 * 1024;
- else
- end = U64_MAX;
+ (DISPLAY_VER(display) == 9 && !display->platform.broxton)) {
+ u64 stolen_area_size = intel_parent_stolen_area_size(display);
+
+ /*
+ * If stolen_area_size is less than SZ_8M, use
+ * intel_fbc_cfb_base_max instead. This should not happen,
+ * so warn if it does.
+ */
+ if (drm_WARN_ON(display->drm,
+ check_sub_overflow(stolen_area_size,
+ SZ_8M, &stolen_area_size)))
+ return end;
+
+ return min(end, stolen_area_size);
+ }
- return min(end, intel_fbc_cfb_base_max(display));
+ return end;
}
static int intel_fbc_min_limit(const struct intel_plane_state *plane_state)