drm/i915: Verify the BIOS FB first PTE on non-LMEMBAR systems
authorVille Syrjälä <ville.syrjala@linux.intel.com>
Thu, 13 Mar 2025 14:08:34 +0000 (16:08 +0200)
committerVille Syrjälä <ville.syrjala@linux.intel.com>
Tue, 1 Apr 2025 23:20:00 +0000 (02:20 +0300)
Now that we have intel_ggtt_read_entry() we can easily read out the
first PTE of the BIOS FB and verify that it looks correct. We'll
also use the extracted dma address to figure out where in stolen
the FB lives (so far we've just assumed that it sits at offset 0,
and in practice that does seem to be true, but better safe than
sorry).

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20250313140838.29742-7-ville.syrjala@linux.intel.com
Reviewed-by: Jouni Högander <jouni.hogander@intel.com>
drivers/gpu/drm/i915/display/intel_plane_initial.c

index 2989a5d76c1c7e58ccbf9e0d57df0494a6c54f09..cf7d1a5ab52428fa686a9e9a7e940607ec63d78d 100644 (file)
@@ -115,11 +115,28 @@ initial_plane_phys_smem(struct intel_display *display,
                        struct intel_initial_plane_config *plane_config)
 {
        struct drm_i915_private *i915 = to_i915(display->drm);
+       struct i915_ggtt *ggtt = to_gt(i915)->ggtt;
        struct intel_memory_region *mem;
+       bool is_present, is_local;
+       dma_addr_t dma_addr;
        u32 base;
 
        base = round_down(plane_config->base, I915_GTT_MIN_ALIGNMENT);
 
+       dma_addr = intel_ggtt_read_entry(&ggtt->vm, base, &is_present, &is_local);
+
+       if (!is_present) {
+               drm_err(display->drm,
+                       "Initial plane FB PTE not present\n");
+               return false;
+       }
+
+       if (is_local) {
+               drm_err(display->drm,
+                       "Initial plane FB PTE LMEM\n");
+               return false;
+       }
+
        mem = i915->mm.stolen_region;
        if (!mem) {
                drm_dbg_kms(display->drm,
@@ -127,8 +144,18 @@ initial_plane_phys_smem(struct intel_display *display,
                return false;
        }
 
-       /* FIXME get and validate the dma_addr from the PTE */
-       plane_config->phys_base = base;
+       if (dma_addr < mem->region.start || dma_addr > mem->region.end) {
+               drm_err(display->drm,
+                       "Initial plane programming using invalid range, dma_addr=%pa (%s [%pa-%pa])\n",
+                       &dma_addr, mem->region.name, &mem->region.start, &mem->region.end);
+               return false;
+       }
+
+       drm_dbg(display->drm,
+               "Using dma_addr=%pa, based on initial plane programming\n",
+               &dma_addr);
+
+       plane_config->phys_base = dma_addr - mem->region.start;
        plane_config->mem = mem;
 
        return true;