This function returns an error code. If that code is non-zero, VGA decoding is undefined, and the lock counter has not been increased, so it is not valid to access registers or call vga_put afterwards.
Signed-off-by: Simon Richter <[email protected]> Closes: https://gitlab.freedesktop.org/drm/xe/kernel/-/issues/1824 --- drivers/gpu/drm/i915/display/intel_vga.c | 29 ++++++++++++++++++++---- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_vga.c b/drivers/gpu/drm/i915/display/intel_vga.c index 6fc3e3702cb8..4118c451d53c 100644 --- a/drivers/gpu/drm/i915/display/intel_vga.c +++ b/drivers/gpu/drm/i915/display/intel_vga.c @@ -112,12 +112,17 @@ static bool intel_pci_bridge_set_vga(struct pci_dev *pdev, bool enable) return old & PCI_BRIDGE_CTL_VGA; } -static bool intel_vga_get(struct intel_display *display, bool mmio) +static int __must_check intel_vga_get(struct intel_display *display, + bool mmio, bool *old_io_decode) { struct pci_dev *pdev = to_pci_dev(display->drm->dev); + int err; if (mmio) - return false; + { + *old_io_decode = false; + return 0; + } /* * Bypass the VGA arbiter on the iGPU and just enable @@ -131,9 +136,14 @@ static bool intel_vga_get(struct intel_display *display, bool mmio) * of how any other VGA routing bits are configured. */ if (display->platform.dgfx) - vga_get_uninterruptible(pdev, VGA_RSRC_LEGACY_IO); + { + err = vga_get_uninterruptible(pdev, VGA_RSRC_LEGACY_IO); + if (unlikely(err)) + return err; + } - return intel_pci_set_io_decode(pdev, true); + *old_io_decode = intel_pci_set_io_decode(pdev, true); + return 0; } static void intel_vga_put(struct intel_display *display, bool io_decode, bool mmio) @@ -175,6 +185,7 @@ void intel_vga_disable(struct intel_display *display) bool io_decode; u8 msr, sr1; u32 tmp; + int err; if (!intel_vga_decode_is_enabled(display)) { drm_dbg_kms(display->drm, "VGA decode is disabled\n"); @@ -216,7 +227,15 @@ void intel_vga_disable(struct intel_display *display) goto reset_vgacntr; } - io_decode = intel_vga_get(display, mmio); + /* This should not fail, because vga_get will only report errors for + * dGPUs that are unreachable via the bridge, and cannot be made + * reachable either. We shouldn't even get here for this case, but if + * we do, we assume that the bridge will also refuse future requests + * to forward VGA accesses. + */ + err = intel_vga_get(display, mmio, &io_decode); + if (unlikely(err)) + goto reset_vgacntr; drm_WARN_ON(display->drm, !mmio && !intel_pci_has_vga_io_decode(pdev)); -- 2.47.3
