@@ -367,6 +367,44 @@ static void dmc_set_fw_offset(struct intel_dmc *dmc,
367367 }
368368}
369369
370+ static bool dmc_mmio_addr_sanity_check (struct intel_dmc * dmc ,
371+ const u32 * mmioaddr , u32 mmio_count ,
372+ int header_ver , u8 dmc_id )
373+ {
374+ struct drm_i915_private * i915 = container_of (dmc , typeof (* i915 ), dmc );
375+ u32 start_range , end_range ;
376+ int i ;
377+
378+ if (dmc_id >= DMC_FW_MAX ) {
379+ drm_warn (& i915 -> drm , "Unsupported firmware id %u\n" , dmc_id );
380+ return false;
381+ }
382+
383+ if (header_ver == 1 ) {
384+ start_range = DMC_MMIO_START_RANGE ;
385+ end_range = DMC_MMIO_END_RANGE ;
386+ } else if (dmc_id == DMC_FW_MAIN ) {
387+ start_range = TGL_MAIN_MMIO_START ;
388+ end_range = TGL_MAIN_MMIO_END ;
389+ } else if (DISPLAY_VER (i915 ) >= 13 ) {
390+ start_range = ADLP_PIPE_MMIO_START ;
391+ end_range = ADLP_PIPE_MMIO_END ;
392+ } else if (DISPLAY_VER (i915 ) >= 12 ) {
393+ start_range = TGL_PIPE_MMIO_START (dmc_id );
394+ end_range = TGL_PIPE_MMIO_END (dmc_id );
395+ } else {
396+ drm_warn (& i915 -> drm , "Unknown mmio range for sanity check" );
397+ return false;
398+ }
399+
400+ for (i = 0 ; i < mmio_count ; i ++ ) {
401+ if (mmioaddr [i ] < start_range || mmioaddr [i ] > end_range )
402+ return false;
403+ }
404+
405+ return true;
406+ }
407+
370408static u32 parse_dmc_fw_header (struct intel_dmc * dmc ,
371409 const struct intel_dmc_header_base * dmc_header ,
372410 size_t rem_size , u8 dmc_id )
@@ -436,6 +474,12 @@ static u32 parse_dmc_fw_header(struct intel_dmc *dmc,
436474 return 0 ;
437475 }
438476
477+ if (!dmc_mmio_addr_sanity_check (dmc , mmioaddr , mmio_count ,
478+ dmc_header -> header_ver , dmc_id )) {
479+ drm_err (& i915 -> drm , "DMC firmware has Wrong MMIO Addresses\n" );
480+ return 0 ;
481+ }
482+
439483 for (i = 0 ; i < mmio_count ; i ++ ) {
440484 dmc_info -> mmioaddr [i ] = _MMIO (mmioaddr [i ]);
441485 dmc_info -> mmiodata [i ] = mmiodata [i ];
0 commit comments