Skip to content

Commit ad3ebcc

Browse files
Jonathan-Cavittjlahtine-intel
authored andcommitted
drm/i915/display: Prevent u64 underflow in intel_fbc_stolen_end
Static analysis reveals a potential integer underflow in intel_fbc_stolen_end. This can apparently occur if intel_parent_stolen_area_size returns zero (or, theoretically, any value less than 2^23), as 2^23 is subtracted from the return value and stored in a u64. While this doesn't appear to cause any issues due to the use of the min() function to clamp the return values from the intel_fbc_stolen_end function, it would be best practice to avoid undeflowing values like this on principle. So, rework the function to prevent the underflow from occurring. Note that the underflow at present would result in the value of intel_fbc_cfb_base_max being returned at the end of intel_fbc_stolen_end, so just return that if the value of intel_parent_stolen_area_size is too small. While we're here, fix the other comments here and modify the execution path for readability. v2: (Jani) - Fix the comments in intel_fbc_stolen_end - Use check_sub_overflow - Remove macro that mirrors SZ_8M, as it is now only referenced once - Misc. formatting fixes Fixes: a9da512 ("drm/i915: avoid the last 8mb of stolen on BDW/SKL") Signed-off-by: Jonathan Cavitt <[email protected]> Cc: Paulo Zanoni <[email protected]> Cc: Ville Syrjälä <[email protected]> Cc: Daniel Vetter <[email protected]> Reviewed-by: Jani Nikula <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Matt Roper <[email protected]> (cherry picked from commit 6695dc2) Signed-off-by: Joonas Lahtinen <[email protected]>
1 parent 69f83f1 commit ad3ebcc

1 file changed

Lines changed: 21 additions & 8 deletions

File tree

drivers/gpu/drm/i915/display/intel_fbc.c

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -809,19 +809,32 @@ static u64 intel_fbc_cfb_base_max(struct intel_display *display)
809809

810810
static u64 intel_fbc_stolen_end(struct intel_display *display)
811811
{
812-
u64 end;
812+
u64 end = intel_fbc_cfb_base_max(display);
813813

814-
/* The FBC hardware for BDW/SKL doesn't have access to the stolen
814+
/*
815+
* The FBC hardware for BDW/SKL doesn't have access to the stolen
815816
* reserved range size, so it always assumes the maximum (8mb) is used.
816817
* If we enable FBC using a CFB on that memory range we'll get FIFO
817-
* underruns, even if that range is not reserved by the BIOS. */
818+
* underruns, even if that range is not reserved by the BIOS.
819+
*/
818820
if (display->platform.broadwell ||
819-
(DISPLAY_VER(display) == 9 && !display->platform.broxton))
820-
end = intel_parent_stolen_area_size(display) - 8 * 1024 * 1024;
821-
else
822-
end = U64_MAX;
821+
(DISPLAY_VER(display) == 9 && !display->platform.broxton)) {
822+
u64 stolen_area_size = intel_parent_stolen_area_size(display);
823+
824+
/*
825+
* If stolen_area_size is less than SZ_8M, use
826+
* intel_fbc_cfb_base_max instead. This should not happen,
827+
* so warn if it does.
828+
*/
829+
if (drm_WARN_ON(display->drm,
830+
check_sub_overflow(stolen_area_size,
831+
SZ_8M, &stolen_area_size)))
832+
return end;
833+
834+
return min(end, stolen_area_size);
835+
}
823836

824-
return min(end, intel_fbc_cfb_base_max(display));
837+
return end;
825838
}
826839

827840
static int intel_fbc_min_limit(const struct intel_plane_state *plane_state)

0 commit comments

Comments
 (0)