]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.18-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 7 Aug 2026 12:14:59 +0000 (14:14 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 7 Aug 2026 12:14:59 +0000 (14:14 +0200)
added patches:
drm-amdgpu-fix-context-pstate-override-handling.patch
drm-amdgpu-respect-placement-requirements-in-amdgpu_gtt_mgr-functions.patch
drm-fb-helper-allocate-and-release-fb_info-in-single-place.patch
drm-tegra-fbdev-remove-offset-into-framebuffer-memory.patch
drm-xe-guc-fix-buffer-overflow-in-steered-register-list-allocation.patch

queue-6.18/drm-amdgpu-fix-context-pstate-override-handling.patch [new file with mode: 0644]
queue-6.18/drm-amdgpu-respect-placement-requirements-in-amdgpu_gtt_mgr-functions.patch [new file with mode: 0644]
queue-6.18/drm-fb-helper-allocate-and-release-fb_info-in-single-place.patch [new file with mode: 0644]
queue-6.18/drm-tegra-fbdev-remove-offset-into-framebuffer-memory.patch [new file with mode: 0644]
queue-6.18/drm-xe-guc-fix-buffer-overflow-in-steered-register-list-allocation.patch [new file with mode: 0644]
queue-6.18/series

diff --git a/queue-6.18/drm-amdgpu-fix-context-pstate-override-handling.patch b/queue-6.18/drm-amdgpu-fix-context-pstate-override-handling.patch
new file mode 100644 (file)
index 0000000..da14f53
--- /dev/null
@@ -0,0 +1,165 @@
+From stable+bounces-294132-greg=kroah.com@vger.kernel.org Fri Jul 31 18:07:44 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 31 Jul 2026 12:00:49 -0400
+Subject: drm/amdgpu: Fix context pstate override handling
+To: stable@vger.kernel.org
+Cc: "Tvrtko Ursulin" <tvrtko.ursulin@igalia.com>, "Chengming Gui" <Jack.Gui@amd.com>, "Alex Deucher" <alexander.deucher@amd.com>, "Christian König" <christian.koenig@amd.com>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260731160049.647545-1-sashal@kernel.org>
+
+From: Tvrtko Ursulin <tvrtko.ursulin@igalia.com>
+
+[ Upstream commit c1dc4ccb82c9e56325d8e7514ca4c90bd1efb351 ]
+
+There are several problems in the context pstate handling code.
+
+The most serious ones are potential use-after-free and NULL pointer
+dereferences at context initialization time. Both are due
+amdgpu_ctx_init() not holding the adev->pm.stable_pstate_ctx_lock, which
+is otherwise used from both sysfs and the context code itself for
+modifying and clearing the stored context pointer.
+
+Second issue is that context fini can trample over the pstate
+configuration set via sysfs. This is due the restore state
+(ctx->stable_pstate) being saved at context init time, and not if, or when
+the context actually changes the pstate. As the context exits it will
+therefore incorrectly restore to what was set before the sysfs override
+was requested.
+
+The simplest fix is to drastically simplify how the state is tracked, by
+clearly defining the points at which pstate ownership is taken and
+released, and to handle all transitions under the correct lock.
+
+Instead of at context init time, the previous state is saved only at the
+point the context overrides the current state, and is restored on context
+exit only if the context is still the owner of the current override state.
+
+Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com>
+Fixes: 79610d304133 ("drm/amdgpu: fix pstate setting issue")
+Cc: Chengming Gui <Jack.Gui@amd.com>
+Cc: Alex Deucher <alexander.deucher@amd.com>
+Cc: "Christian König" <christian.koenig@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+(cherry picked from commit 1b5e413713c0a93bc1818394d0ce49aaad21bd27)
+Cc: <stable@vger.kernel.org> # v6.1+
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c |   71 ++++++++++++++++++--------------
+ 1 file changed, 42 insertions(+), 29 deletions(-)
+
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
+@@ -321,7 +321,6 @@ static int amdgpu_ctx_init(struct amdgpu
+                          struct drm_file *filp, struct amdgpu_ctx *ctx)
+ {
+       struct amdgpu_fpriv *fpriv = filp->driver_priv;
+-      u32 current_stable_pstate;
+       int r;
+       r = amdgpu_ctx_priority_permit(filp, priority);
+@@ -339,37 +338,22 @@ static int amdgpu_ctx_init(struct amdgpu
+       ctx->generation = amdgpu_vm_generation(mgr->adev, &fpriv->vm);
+       ctx->init_priority = priority;
+       ctx->override_priority = AMDGPU_CTX_PRIORITY_UNSET;
+-
+-      r = amdgpu_ctx_get_stable_pstate(ctx, &current_stable_pstate);
+-      if (r)
+-              return r;
+-
+-      if (mgr->adev->pm.stable_pstate_ctx)
+-              ctx->stable_pstate = mgr->adev->pm.stable_pstate_ctx->stable_pstate;
+-      else
+-              ctx->stable_pstate = current_stable_pstate;
++      ctx->stable_pstate = AMDGPU_CTX_STABLE_PSTATE_NONE;
+       ctx->ctx_mgr = &(fpriv->ctx_mgr);
+       return 0;
+ }
+-static int amdgpu_ctx_set_stable_pstate(struct amdgpu_ctx *ctx,
+-                                      u32 stable_pstate)
++static int __amdgpu_ctx_set_stable_pstate(struct amdgpu_ctx *ctx,
++                                        u32 stable_pstate)
+ {
+       struct amdgpu_device *adev = ctx->mgr->adev;
+       enum amd_dpm_forced_level level;
++      struct amdgpu_ctx *current_ctx;
+       u32 current_stable_pstate;
+-      int r;
+-
+-      mutex_lock(&adev->pm.stable_pstate_ctx_lock);
+-      if (adev->pm.stable_pstate_ctx && adev->pm.stable_pstate_ctx != ctx) {
+-              r = -EBUSY;
+-              goto done;
+-      }
++      int r = 0;
+-      r = amdgpu_ctx_get_stable_pstate(ctx, &current_stable_pstate);
+-      if (r || (stable_pstate == current_stable_pstate))
+-              goto done;
++      lockdep_assert_held(&adev->pm.stable_pstate_ctx_lock);
+       switch (stable_pstate) {
+       case AMDGPU_CTX_STABLE_PSTATE_NONE:
+@@ -388,17 +372,41 @@ static int amdgpu_ctx_set_stable_pstate(
+               level = AMD_DPM_FORCED_LEVEL_PROFILE_PEAK;
+               break;
+       default:
+-              r = -EINVAL;
+-              goto done;
++              return -EINVAL;
+       }
++      current_ctx = adev->pm.stable_pstate_ctx;
++      if (current_ctx && current_ctx != ctx)
++              return -EBUSY;
++
++      r = amdgpu_ctx_get_stable_pstate(ctx, &current_stable_pstate);
++      if (r || current_stable_pstate == stable_pstate)
++              return r;
++
+       r = amdgpu_dpm_force_performance_level(adev, level);
++      if (r)
++              return r;
+-      if (level == AMD_DPM_FORCED_LEVEL_AUTO)
+-              adev->pm.stable_pstate_ctx = NULL;
+-      else
++      if (!current_ctx) {
+               adev->pm.stable_pstate_ctx = ctx;
+-done:
++              /*
++               * Serialized by context taking ownership for the first time
++               * while holding adev->pm.stable_pstate_ctx_lock).
++               */
++              WRITE_ONCE(ctx->stable_pstate, current_stable_pstate);
++      }
++
++      return 0;
++}
++
++static int amdgpu_ctx_set_stable_pstate(struct amdgpu_ctx *ctx,
++                                      u32 stable_pstate)
++{
++      struct amdgpu_device *adev = ctx->mgr->adev;
++      int r;
++
++      mutex_lock(&adev->pm.stable_pstate_ctx_lock);
++      r = __amdgpu_ctx_set_stable_pstate(ctx, stable_pstate);
+       mutex_unlock(&adev->pm.stable_pstate_ctx_lock);
+       return r;
+@@ -424,7 +432,12 @@ static void amdgpu_ctx_fini(struct kref
+       }
+       if (drm_dev_enter(adev_to_drm(adev), &idx)) {
+-              amdgpu_ctx_set_stable_pstate(ctx, ctx->stable_pstate);
++              mutex_lock(&adev->pm.stable_pstate_ctx_lock);
++              if (adev->pm.stable_pstate_ctx == ctx) {
++                      __amdgpu_ctx_set_stable_pstate(ctx, ctx->stable_pstate);
++                      adev->pm.stable_pstate_ctx = NULL;
++              }
++              mutex_unlock(&adev->pm.stable_pstate_ctx_lock);
+               drm_dev_exit(idx);
+       }
diff --git a/queue-6.18/drm-amdgpu-respect-placement-requirements-in-amdgpu_gtt_mgr-functions.patch b/queue-6.18/drm-amdgpu-respect-placement-requirements-in-amdgpu_gtt_mgr-functions.patch
new file mode 100644 (file)
index 0000000..b098cb0
--- /dev/null
@@ -0,0 +1,75 @@
+From stable+bounces-294145-greg=kroah.com@vger.kernel.org Fri Jul 31 18:46:30 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 31 Jul 2026 12:25:27 -0400
+Subject: drm/amdgpu: Respect placement requirements in amdgpu_gtt_mgr functions
+To: stable@vger.kernel.org
+Cc: "Timur Kristóf" <timur.kristof@gmail.com>, "Christian König" <christian.koenig@amd.com>, "Alex Deucher" <alexander.deucher@amd.com>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260731162527.789626-1-sashal@kernel.org>
+
+From: Timur Kristóf <timur.kristof@gmail.com>
+
+[ Upstream commit 8882f8897e554053af9e72f4c2da8b1e2cce56c7 ]
+
+When testing intersection and compatibility, respect
+the actual placement requirements. This is a pre-requisite
+for ensuring that UVD CS BOs do not cross 256M segments.
+
+Fixes: ded910f368a5 ("drm/amdgpu: Implement intersect/compatible functions")
+Suggested-by: Christian König <christian.koenig@amd.com>
+Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
+Reviewed-by: Christian König <christian.koenig@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+(cherry picked from commit bc06579ca29dee9c245a41b12e39c7bb6938af5d)
+Cc: stable@vger.kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c |   30 ++++++++++++++++++++++++++--
+ 1 file changed, 28 insertions(+), 2 deletions(-)
+
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c
+@@ -217,7 +217,20 @@ static bool amdgpu_gtt_mgr_intersects(st
+                                     const struct ttm_place *place,
+                                     size_t size)
+ {
+-      return !place->lpfn || amdgpu_gtt_mgr_has_gart_addr(res);
++      const struct drm_mm_node *const node = &to_ttm_range_mgr_node(res)->mm_nodes[0];
++      const u32 num_pages = PFN_UP(size);
++
++      if (!place->lpfn)
++              return true;
++
++      if (!amdgpu_gtt_mgr_has_gart_addr(res))
++              return false;
++
++      if (place->fpfn >= (node->start + num_pages) ||
++          (place->lpfn && place->lpfn <= node->start))
++              return false;
++
++      return true;
+ }
+ /**
+@@ -235,7 +248,20 @@ static bool amdgpu_gtt_mgr_compatible(st
+                                     const struct ttm_place *place,
+                                     size_t size)
+ {
+-      return !place->lpfn || amdgpu_gtt_mgr_has_gart_addr(res);
++      const struct drm_mm_node *const node = &to_ttm_range_mgr_node(res)->mm_nodes[0];
++      const u32 num_pages = PFN_UP(size);
++
++      if (!place->lpfn)
++              return true;
++
++      if (!amdgpu_gtt_mgr_has_gart_addr(res))
++              return false;
++
++      if (node->start < place->fpfn ||
++          (place->lpfn && (node->start + num_pages) > place->lpfn))
++              return false;
++
++      return true;
+ }
+ /**
diff --git a/queue-6.18/drm-fb-helper-allocate-and-release-fb_info-in-single-place.patch b/queue-6.18/drm-fb-helper-allocate-and-release-fb_info-in-single-place.patch
new file mode 100644 (file)
index 0000000..b1a2ab0
--- /dev/null
@@ -0,0 +1,526 @@
+From stable+bounces-293912-greg=kroah.com@vger.kernel.org Fri Jul 31 04:41:37 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 30 Jul 2026 22:41:00 -0400
+Subject: drm/fb-helper: Allocate and release fb_info in single place
+To: stable@vger.kernel.org
+Cc: "Thomas Zimmermann" <tzimmermann@suse.de>, "Christian König" <christian.koenig@amd.com>, "Dmitry Baryshkov" <dmitry.baryshkov@oss.qualcomm.com>, "Javier Martinez Canillas" <javierm@redhat.com>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260731024101.3339564-1-sashal@kernel.org>
+
+From: Thomas Zimmermann <tzimmermann@suse.de>
+
+[ Upstream commit 63c971af40365ee706c7e24f6a7900d693518f09 ]
+
+Move the calls to drm_fb_helper_alloc_info() from drivers into a
+single place in fbdev helpers. Allocates struct fb_info for a new
+framebuffer device. Then call drm_fb_helper_single_fb_probe() to
+create an fbdev screen buffer. Also release the instance on errors
+by calling drm_fb_helper_release_info().
+
+Simplifies the code and fixes the error cleanup for some of the
+drivers.
+
+Regular release of the struct fb_info instance still happens in
+drm_fb_helper_fini() as before.
+
+v2:
+- remove error rollback in driver implementations (kernel test robot)
+- initialize info in TTM implementation (kernel test robot)
+
+Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
+Acked-by: Christian König <christian.koenig@amd.com> # radeon
+Acked-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> # msm
+Acked-by: Javier Martinez Canillas <javierm@redhat.com>
+Link: https://patch.msgid.link/20251027081245.80262-1-tzimmermann@suse.de
+Stable-dep-of: a18b6e30ecd6 ("drm/tegra: fbdev: Remove offset into framebuffer memory")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/armada/armada_fbdev.c      |   12 --------
+ drivers/gpu/drm/drm_fb_helper.c            |   39 ++++++++---------------------
+ drivers/gpu/drm/drm_fbdev_dma.c            |   12 +-------
+ drivers/gpu/drm/drm_fbdev_shmem.c          |   12 +-------
+ drivers/gpu/drm/drm_fbdev_ttm.c            |   12 +-------
+ drivers/gpu/drm/exynos/exynos_drm_fbdev.c  |    9 ------
+ drivers/gpu/drm/gma500/fbdev.c             |   12 --------
+ drivers/gpu/drm/i915/display/intel_fbdev.c |    9 ------
+ drivers/gpu/drm/msm/msm_fbdev.c            |    9 ------
+ drivers/gpu/drm/omapdrm/omap_fbdev.c       |    9 ------
+ drivers/gpu/drm/radeon/radeon_fbdev.c      |   13 ---------
+ drivers/gpu/drm/tegra/fbdev.c              |    9 ------
+ include/drm/drm_fb_helper.h                |   12 --------
+ 13 files changed, 26 insertions(+), 143 deletions(-)
+
+--- a/drivers/gpu/drm/armada/armada_fbdev.c
++++ b/drivers/gpu/drm/armada/armada_fbdev.c
+@@ -45,10 +45,10 @@ int armada_fbdev_driver_fbdev_probe(stru
+                                   struct drm_fb_helper_surface_size *sizes)
+ {
+       struct drm_device *dev = fbh->dev;
++      struct fb_info *info = fbh->info;
+       struct drm_mode_fb_cmd2 mode;
+       struct armada_framebuffer *dfb;
+       struct armada_gem_object *obj;
+-      struct fb_info *info;
+       int size, ret;
+       void *ptr;
+@@ -92,12 +92,6 @@ int armada_fbdev_driver_fbdev_probe(stru
+       if (IS_ERR(dfb))
+               return PTR_ERR(dfb);
+-      info = drm_fb_helper_alloc_info(fbh);
+-      if (IS_ERR(info)) {
+-              ret = PTR_ERR(info);
+-              goto err_fballoc;
+-      }
+-
+       info->fbops = &armada_fb_ops;
+       info->fix.smem_start = obj->phys_addr;
+       info->fix.smem_len = obj->obj.size;
+@@ -113,8 +107,4 @@ int armada_fbdev_driver_fbdev_probe(stru
+               (unsigned long long)obj->phys_addr);
+       return 0;
+-
+- err_fballoc:
+-      dfb->fb.funcs->destroy(&dfb->fb);
+-      return ret;
+ }
+--- a/drivers/gpu/drm/drm_fb_helper.c
++++ b/drivers/gpu/drm/drm_fb_helper.c
+@@ -489,20 +489,7 @@ int drm_fb_helper_init(struct drm_device
+ }
+ EXPORT_SYMBOL(drm_fb_helper_init);
+-/**
+- * drm_fb_helper_alloc_info - allocate fb_info and some of its members
+- * @fb_helper: driver-allocated fbdev helper
+- *
+- * A helper to alloc fb_info and the member cmap. Called by the driver
+- * within the struct &drm_driver.fbdev_probe callback function. Drivers do
+- * not need to release the allocated fb_info structure themselves, this is
+- * automatically done when calling drm_fb_helper_fini().
+- *
+- * RETURNS:
+- * fb_info pointer if things went okay, pointer containing error code
+- * otherwise
+- */
+-struct fb_info *drm_fb_helper_alloc_info(struct drm_fb_helper *fb_helper)
++static struct fb_info *drm_fb_helper_alloc_info(struct drm_fb_helper *fb_helper)
+ {
+       struct device *dev = fb_helper->dev->dev;
+       struct fb_info *info;
+@@ -529,17 +516,8 @@ err_release:
+       framebuffer_release(info);
+       return ERR_PTR(ret);
+ }
+-EXPORT_SYMBOL(drm_fb_helper_alloc_info);
+-/**
+- * drm_fb_helper_release_info - release fb_info and its members
+- * @fb_helper: driver-allocated fbdev helper
+- *
+- * A helper to release fb_info and the member cmap.  Drivers do not
+- * need to release the allocated fb_info structure themselves, this is
+- * automatically done when calling drm_fb_helper_fini().
+- */
+-void drm_fb_helper_release_info(struct drm_fb_helper *fb_helper)
++static void drm_fb_helper_release_info(struct drm_fb_helper *fb_helper)
+ {
+       struct fb_info *info = fb_helper->info;
+@@ -552,7 +530,6 @@ void drm_fb_helper_release_info(struct d
+               fb_dealloc_cmap(&info->cmap);
+       framebuffer_release(info);
+ }
+-EXPORT_SYMBOL(drm_fb_helper_release_info);
+ /**
+  * drm_fb_helper_unregister_info - unregister fb_info framebuffer device
+@@ -1813,6 +1790,11 @@ __drm_fb_helper_initial_config_and_unloc
+       height = dev->mode_config.max_height;
+       drm_client_modeset_probe(&fb_helper->client, width, height);
++
++      info = drm_fb_helper_alloc_info(fb_helper);
++      if (IS_ERR(info))
++              return PTR_ERR(info);
++
+       ret = drm_fb_helper_single_fb_probe(fb_helper);
+       if (ret < 0) {
+               if (ret == -EAGAIN) {
+@@ -1821,13 +1803,12 @@ __drm_fb_helper_initial_config_and_unloc
+               }
+               mutex_unlock(&fb_helper->lock);
+-              return ret;
++              goto err_drm_fb_helper_release_info;
+       }
+       drm_setup_crtcs_fb(fb_helper);
+       fb_helper->deferred_setup = false;
+-      info = fb_helper->info;
+       info->var.pixclock = 0;
+       /* Need to drop locks to avoid recursive deadlock in
+@@ -1850,6 +1831,10 @@ __drm_fb_helper_initial_config_and_unloc
+       mutex_unlock(&kernel_fb_helper_lock);
+       return 0;
++
++err_drm_fb_helper_release_info:
++      drm_fb_helper_release_info(fb_helper);
++      return ret;
+ }
+ /**
+--- a/drivers/gpu/drm/drm_fbdev_dma.c
++++ b/drivers/gpu/drm/drm_fbdev_dma.c
+@@ -272,9 +272,9 @@ int drm_fbdev_dma_driver_fbdev_probe(str
+ {
+       struct drm_client_dev *client = &fb_helper->client;
+       struct drm_device *dev = fb_helper->dev;
++      struct fb_info *info = fb_helper->info;
+       struct drm_client_buffer *buffer;
+       struct drm_framebuffer *fb;
+-      struct fb_info *info;
+       u32 format;
+       struct iosys_map map;
+       int ret;
+@@ -304,12 +304,6 @@ int drm_fbdev_dma_driver_fbdev_probe(str
+       fb_helper->buffer = buffer;
+       fb_helper->fb = fb;
+-      info = drm_fb_helper_alloc_info(fb_helper);
+-      if (IS_ERR(info)) {
+-              ret = PTR_ERR(info);
+-              goto err_drm_client_buffer_vunmap;
+-      }
+-
+       drm_fb_helper_fill_info(info, fb_helper, sizes);
+       if (fb->funcs->dirty)
+@@ -317,12 +311,10 @@ int drm_fbdev_dma_driver_fbdev_probe(str
+       else
+               ret = drm_fbdev_dma_driver_fbdev_probe_tail(fb_helper, sizes);
+       if (ret)
+-              goto err_drm_fb_helper_release_info;
++              goto err_drm_client_buffer_vunmap;
+       return 0;
+-err_drm_fb_helper_release_info:
+-      drm_fb_helper_release_info(fb_helper);
+ err_drm_client_buffer_vunmap:
+       fb_helper->fb = NULL;
+       fb_helper->buffer = NULL;
+--- a/drivers/gpu/drm/drm_fbdev_shmem.c
++++ b/drivers/gpu/drm/drm_fbdev_shmem.c
+@@ -136,10 +136,10 @@ int drm_fbdev_shmem_driver_fbdev_probe(s
+ {
+       struct drm_client_dev *client = &fb_helper->client;
+       struct drm_device *dev = fb_helper->dev;
++      struct fb_info *info = fb_helper->info;
+       struct drm_client_buffer *buffer;
+       struct drm_gem_shmem_object *shmem;
+       struct drm_framebuffer *fb;
+-      struct fb_info *info;
+       u32 format;
+       struct iosys_map map;
+       int ret;
+@@ -169,12 +169,6 @@ int drm_fbdev_shmem_driver_fbdev_probe(s
+       fb_helper->buffer = buffer;
+       fb_helper->fb = fb;
+-      info = drm_fb_helper_alloc_info(fb_helper);
+-      if (IS_ERR(info)) {
+-              ret = PTR_ERR(info);
+-              goto err_drm_client_buffer_vunmap;
+-      }
+-
+       drm_fb_helper_fill_info(info, fb_helper, sizes);
+       info->fbops = &drm_fbdev_shmem_fb_ops;
+@@ -195,12 +189,10 @@ int drm_fbdev_shmem_driver_fbdev_probe(s
+       info->fbdefio = &fb_helper->fbdefio;
+       ret = fb_deferred_io_init(info);
+       if (ret)
+-              goto err_drm_fb_helper_release_info;
++              goto err_drm_client_buffer_vunmap;
+       return 0;
+-err_drm_fb_helper_release_info:
+-      drm_fb_helper_release_info(fb_helper);
+ err_drm_client_buffer_vunmap:
+       fb_helper->fb = NULL;
+       fb_helper->buffer = NULL;
+--- a/drivers/gpu/drm/drm_fbdev_ttm.c
++++ b/drivers/gpu/drm/drm_fbdev_ttm.c
+@@ -176,8 +176,8 @@ int drm_fbdev_ttm_driver_fbdev_probe(str
+ {
+       struct drm_client_dev *client = &fb_helper->client;
+       struct drm_device *dev = fb_helper->dev;
++      struct fb_info *info = fb_helper->info;
+       struct drm_client_buffer *buffer;
+-      struct fb_info *info;
+       size_t screen_size;
+       void *screen_buffer;
+       u32 format;
+@@ -205,12 +205,6 @@ int drm_fbdev_ttm_driver_fbdev_probe(str
+               goto err_drm_client_framebuffer_delete;
+       }
+-      info = drm_fb_helper_alloc_info(fb_helper);
+-      if (IS_ERR(info)) {
+-              ret = PTR_ERR(info);
+-              goto err_vfree;
+-      }
+-
+       drm_fb_helper_fill_info(info, fb_helper, sizes);
+       info->fbops = &drm_fbdev_ttm_fb_ops;
+@@ -227,12 +221,10 @@ int drm_fbdev_ttm_driver_fbdev_probe(str
+       info->fbdefio = &fb_helper->fbdefio;
+       ret = fb_deferred_io_init(info);
+       if (ret)
+-              goto err_drm_fb_helper_release_info;
++              goto err_vfree;
+       return 0;
+-err_drm_fb_helper_release_info:
+-      drm_fb_helper_release_info(fb_helper);
+ err_vfree:
+       vfree(screen_buffer);
+ err_drm_client_framebuffer_delete:
+--- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
+@@ -59,18 +59,11 @@ static int exynos_drm_fbdev_update(struc
+                                  struct drm_fb_helper_surface_size *sizes,
+                                  struct exynos_drm_gem *exynos_gem)
+ {
+-      struct fb_info *fbi;
++      struct fb_info *fbi = helper->info;
+       struct drm_framebuffer *fb = helper->fb;
+       unsigned int size = fb->width * fb->height * fb->format->cpp[0];
+       unsigned long offset;
+-      fbi = drm_fb_helper_alloc_info(helper);
+-      if (IS_ERR(fbi)) {
+-              DRM_DEV_ERROR(to_dma_dev(helper->dev),
+-                            "failed to allocate fb info.\n");
+-              return PTR_ERR(fbi);
+-      }
+-
+       fbi->fbops = &exynos_drm_fb_ops;
+       drm_fb_helper_fill_info(fbi, helper, sizes);
+--- a/drivers/gpu/drm/gma500/fbdev.c
++++ b/drivers/gpu/drm/gma500/fbdev.c
+@@ -111,7 +111,7 @@ int psb_fbdev_driver_fbdev_probe(struct
+       struct drm_device *dev = fb_helper->dev;
+       struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
+       struct pci_dev *pdev = to_pci_dev(dev->dev);
+-      struct fb_info *info;
++      struct fb_info *info = fb_helper->info;
+       struct drm_framebuffer *fb;
+       struct drm_mode_fb_cmd2 mode_cmd = { };
+       int size;
+@@ -170,12 +170,6 @@ int psb_fbdev_driver_fbdev_probe(struct
+       fb_helper->funcs = &psb_fbdev_fb_helper_funcs;
+       fb_helper->fb = fb;
+-      info = drm_fb_helper_alloc_info(fb_helper);
+-      if (IS_ERR(info)) {
+-              ret = PTR_ERR(info);
+-              goto err_drm_framebuffer_unregister_private;
+-      }
+-
+       info->fbops = &psb_fbdev_fb_ops;
+       /* Accessed stolen memory directly */
+@@ -199,10 +193,6 @@ int psb_fbdev_driver_fbdev_probe(struct
+       return 0;
+-err_drm_framebuffer_unregister_private:
+-      drm_framebuffer_unregister_private(fb);
+-      drm_framebuffer_cleanup(fb);
+-      kfree(fb);
+ err_drm_gem_object_put:
+       drm_gem_object_put(obj);
+       return ret;
+--- a/drivers/gpu/drm/i915/display/intel_fbdev.c
++++ b/drivers/gpu/drm/i915/display/intel_fbdev.c
+@@ -242,8 +242,8 @@ int intel_fbdev_driver_fbdev_probe(struc
+       struct intel_display *display = to_intel_display(helper->dev);
+       struct intel_fbdev *ifbdev = to_intel_fbdev(helper);
+       struct intel_framebuffer *fb = ifbdev->fb;
++      struct fb_info *info = helper->info;
+       struct ref_tracker *wakeref;
+-      struct fb_info *info;
+       struct i915_vma *vma;
+       unsigned long flags = 0;
+       bool prealloc = false;
+@@ -296,13 +296,6 @@ int intel_fbdev_driver_fbdev_probe(struc
+               goto out_unlock;
+       }
+-      info = drm_fb_helper_alloc_info(helper);
+-      if (IS_ERR(info)) {
+-              drm_err(display->drm, "Failed to allocate fb_info (%pe)\n", info);
+-              ret = PTR_ERR(info);
+-              goto out_unpin;
+-      }
+-
+       helper->funcs = &intel_fb_helper_funcs;
+       helper->fb = &fb->base;
+--- a/drivers/gpu/drm/msm/msm_fbdev.c
++++ b/drivers/gpu/drm/msm/msm_fbdev.c
+@@ -93,9 +93,9 @@ int msm_fbdev_driver_fbdev_probe(struct
+ {
+       struct drm_device *dev = helper->dev;
+       struct msm_drm_private *priv = dev->dev_private;
++      struct fb_info *fbi = helper->info;
+       struct drm_framebuffer *fb = NULL;
+       struct drm_gem_object *bo;
+-      struct fb_info *fbi = NULL;
+       uint64_t paddr;
+       uint32_t format;
+       int ret, pitch;
+@@ -128,13 +128,6 @@ int msm_fbdev_driver_fbdev_probe(struct
+               goto fail;
+       }
+-      fbi = drm_fb_helper_alloc_info(helper);
+-      if (IS_ERR(fbi)) {
+-              DRM_DEV_ERROR(dev->dev, "failed to allocate fb info\n");
+-              ret = PTR_ERR(fbi);
+-              goto fail;
+-      }
+-
+       DBG("fbi=%p, dev=%p", fbi, dev);
+       helper->funcs = &msm_fbdev_helper_funcs;
+--- a/drivers/gpu/drm/omapdrm/omap_fbdev.c
++++ b/drivers/gpu/drm/omapdrm/omap_fbdev.c
+@@ -155,9 +155,9 @@ int omap_fbdev_driver_fbdev_probe(struct
+       struct drm_device *dev = helper->dev;
+       struct omap_drm_private *priv = dev->dev_private;
+       struct omap_fbdev *fbdev = priv->fbdev;
++      struct fb_info *fbi = helper->info;
+       struct drm_framebuffer *fb = NULL;
+       union omap_gem_size gsize;
+-      struct fb_info *fbi = NULL;
+       struct drm_mode_fb_cmd2 mode_cmd = {0};
+       struct drm_gem_object *bo;
+       dma_addr_t dma_addr;
+@@ -226,13 +226,6 @@ int omap_fbdev_driver_fbdev_probe(struct
+               goto fail;
+       }
+-      fbi = drm_fb_helper_alloc_info(helper);
+-      if (IS_ERR(fbi)) {
+-              dev_err(dev->dev, "failed to allocate fb info\n");
+-              ret = PTR_ERR(fbi);
+-              goto fail;
+-      }
+-
+       DBG("fbi=%p, dev=%p", fbi, dev);
+       helper->funcs = &omap_fbdev_helper_funcs;
+--- a/drivers/gpu/drm/radeon/radeon_fbdev.c
++++ b/drivers/gpu/drm/radeon/radeon_fbdev.c
+@@ -206,7 +206,7 @@ int radeon_fbdev_driver_fbdev_probe(stru
+       struct radeon_device *rdev = fb_helper->dev->dev_private;
+       const struct drm_format_info *format_info;
+       struct drm_mode_fb_cmd2 mode_cmd = { };
+-      struct fb_info *info;
++      struct fb_info *info = fb_helper->info;
+       struct drm_gem_object *gobj;
+       struct radeon_bo *rbo;
+       struct drm_framebuffer *fb;
+@@ -247,13 +247,6 @@ int radeon_fbdev_driver_fbdev_probe(stru
+       fb_helper->funcs = &radeon_fbdev_fb_helper_funcs;
+       fb_helper->fb = fb;
+-      /* okay we have an object now allocate the framebuffer */
+-      info = drm_fb_helper_alloc_info(fb_helper);
+-      if (IS_ERR(info)) {
+-              ret = PTR_ERR(info);
+-              goto err_drm_framebuffer_unregister_private;
+-      }
+-
+       info->fbops = &radeon_fbdev_fb_ops;
+       /* radeon resume is fragile and needs a vt switch to help it along */
+@@ -279,10 +272,6 @@ int radeon_fbdev_driver_fbdev_probe(stru
+       return 0;
+-err_drm_framebuffer_unregister_private:
+-      fb_helper->fb = NULL;
+-      drm_framebuffer_unregister_private(fb);
+-      drm_framebuffer_cleanup(fb);
+ err_kfree:
+       kfree(fb);
+ err_radeon_fbdev_destroy_pinned_object:
+--- a/drivers/gpu/drm/tegra/fbdev.c
++++ b/drivers/gpu/drm/tegra/fbdev.c
+@@ -75,10 +75,10 @@ int tegra_fbdev_driver_fbdev_probe(struc
+       struct tegra_drm *tegra = helper->dev->dev_private;
+       struct drm_device *drm = helper->dev;
+       struct drm_mode_fb_cmd2 cmd = { 0 };
++      struct fb_info *info = helper->info;
+       unsigned int bytes_per_pixel;
+       struct drm_framebuffer *fb;
+       unsigned long offset;
+-      struct fb_info *info;
+       struct tegra_bo *bo;
+       size_t size;
+       int err;
+@@ -99,13 +99,6 @@ int tegra_fbdev_driver_fbdev_probe(struc
+       if (IS_ERR(bo))
+               return PTR_ERR(bo);
+-      info = drm_fb_helper_alloc_info(helper);
+-      if (IS_ERR(info)) {
+-              dev_err(drm->dev, "failed to allocate framebuffer info\n");
+-              drm_gem_object_put(&bo->gem);
+-              return PTR_ERR(info);
+-      }
+-
+       fb = tegra_fb_alloc(drm,
+                           drm_get_format_info(drm, cmd.pixel_format, cmd.modifier[0]),
+                           &cmd, &bo, 1);
+--- a/include/drm/drm_fb_helper.h
++++ b/include/drm/drm_fb_helper.h
+@@ -256,8 +256,6 @@ int drm_fb_helper_check_var(struct fb_va
+ int drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper);
+-struct fb_info *drm_fb_helper_alloc_info(struct drm_fb_helper *fb_helper);
+-void drm_fb_helper_release_info(struct drm_fb_helper *fb_helper);
+ void drm_fb_helper_unregister_info(struct drm_fb_helper *fb_helper);
+ void drm_fb_helper_fill_info(struct fb_info *info,
+                            struct drm_fb_helper *fb_helper,
+@@ -340,16 +338,6 @@ drm_fb_helper_restore_fbdev_mode_unlocke
+       return 0;
+ }
+-static inline struct fb_info *
+-drm_fb_helper_alloc_info(struct drm_fb_helper *fb_helper)
+-{
+-      return NULL;
+-}
+-
+-static inline void drm_fb_helper_release_info(struct drm_fb_helper *fb_helper)
+-{
+-}
+-
+ static inline void drm_fb_helper_unregister_info(struct drm_fb_helper *fb_helper)
+ {
+ }
diff --git a/queue-6.18/drm-tegra-fbdev-remove-offset-into-framebuffer-memory.patch b/queue-6.18/drm-tegra-fbdev-remove-offset-into-framebuffer-memory.patch
new file mode 100644 (file)
index 0000000..3d6a1fb
--- /dev/null
@@ -0,0 +1,61 @@
+From stable+bounces-293911-greg=kroah.com@vger.kernel.org Fri Jul 31 04:41:11 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 30 Jul 2026 22:41:01 -0400
+Subject: drm/tegra: fbdev: Remove offset into framebuffer memory
+To: stable@vger.kernel.org
+Cc: Thomas Zimmermann <tzimmermann@suse.de>, dri-devel@lists.freedesktop.org, linux-tegra@vger.kernel.org, Thierry Reding <treding@nvidia.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260731024101.3339564-2-sashal@kernel.org>
+
+From: Thomas Zimmermann <tzimmermann@suse.de>
+
+[ Upstream commit a18b6e30ecd69096beda4a0c96d2570900c3879a ]
+
+The screen_buffer field in struct fb_info contains the kernel address
+of the first byte of framebuffer memory. Do not add the display offset.
+This offset only describes scrolling during scanout.
+
+Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
+Fixes: de2ba664c30f ("gpu: host1x: drm: Add memory manager and fb")
+Cc: dri-devel@lists.freedesktop.org
+Cc: linux-tegra@vger.kernel.org
+Cc: <stable@vger.kernel.org> # v3.10+
+Signed-off-by: Thierry Reding <treding@nvidia.com>
+Link: https://patch.msgid.link/20260421073646.144712-3-tzimmermann@suse.de
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/tegra/fbdev.c |    8 ++------
+ 1 file changed, 2 insertions(+), 6 deletions(-)
+
+--- a/drivers/gpu/drm/tegra/fbdev.c
++++ b/drivers/gpu/drm/tegra/fbdev.c
+@@ -78,7 +78,6 @@ int tegra_fbdev_driver_fbdev_probe(struc
+       struct fb_info *info = helper->info;
+       unsigned int bytes_per_pixel;
+       struct drm_framebuffer *fb;
+-      unsigned long offset;
+       struct tegra_bo *bo;
+       size_t size;
+       int err;
+@@ -118,9 +117,6 @@ int tegra_fbdev_driver_fbdev_probe(struc
+       drm_fb_helper_fill_info(info, helper, sizes);
+-      offset = info->var.xoffset * bytes_per_pixel +
+-               info->var.yoffset * fb->pitches[0];
+-
+       if (bo->pages) {
+               bo->vaddr = vmap(bo->pages, bo->num_pages, VM_MAP,
+                                pgprot_writecombine(PAGE_KERNEL));
+@@ -132,9 +128,9 @@ int tegra_fbdev_driver_fbdev_probe(struc
+       }
+       info->flags |= FBINFO_VIRTFB;
+-      info->screen_buffer = bo->vaddr + offset;
++      info->screen_buffer = bo->vaddr;
+       info->screen_size = size;
+-      info->fix.smem_start = (unsigned long)(bo->iova + offset);
++      info->fix.smem_start = (unsigned long)(bo->iova);
+       info->fix.smem_len = size;
+       return 0;
diff --git a/queue-6.18/drm-xe-guc-fix-buffer-overflow-in-steered-register-list-allocation.patch b/queue-6.18/drm-xe-guc-fix-buffer-overflow-in-steered-register-list-allocation.patch
new file mode 100644 (file)
index 0000000..255a76b
--- /dev/null
@@ -0,0 +1,70 @@
+From stable+bounces-294257-greg=kroah.com@vger.kernel.org Sat Aug  1 02:46:58 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 31 Jul 2026 20:45:07 -0400
+Subject: drm/xe/guc: Fix buffer overflow in steered register list allocation
+To: stable@vger.kernel.org
+Cc: Tejas Upadhyay <tejas.upadhyay@intel.com>, Zhanjun Dong <zhanjun.dong@intel.com>, Matthew Brost <matthew.brost@intel.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260801004507.3661318-1-sashal@kernel.org>
+
+From: Tejas Upadhyay <tejas.upadhyay@intel.com>
+
+[ Upstream commit 632ecc90e1ca5d3b6822bb4d08f84a175b6c42c0 ]
+
+The size calculation for the steered register extarray uses only the
+geometry DSS mask (g_dss_mask) to determine the number of entries to
+allocate:
+
+  total = bitmap_weight(gt->fuse_topo.g_dss_mask, ...) * steer_reg_num;
+
+However, the filling loop uses for_each_dss_steering(), which iterates
+over for_each_dss(), defined as the union of g_dss_mask and c_dss_mask
+(geometry + compute DSS). On platforms with compute-only DSS bits, the
+loop writes past the allocated buffer, corrupting adjacent slab objects.
+
+This manifests as list_del corruption and SLUB redzone overwrites during
+drm_managed_release on device unbind, since the overflow corrupts the
+drmres list_head of neighboring allocations.
+
+Fix by computing the allocation size using the union of both DSS masks,
+matching the iteration pattern of for_each_dss_steering().
+
+--
+v2:
+- use bitmap_weighted_or() (Zhanjun)
+
+Fixes: b170d696c1e2 ("drm/xe/guc: Add XE_LP steered register lists")
+Closes: https://gitlab.freedesktop.org/drm/xe/kernel/-/issues/8049
+Cc: Zhanjun Dong <zhanjun.dong@intel.com>
+Cc: stable@vger.kernel.org
+Assisted-by: GitHub-Copilot:claude-opus-4.6
+Reviewed-by: Zhanjun Dong <zhanjun.dong@intel.com>
+Link: https://patch.msgid.link/20260612070401.543305-2-tejas.upadhyay@intel.com
+Signed-off-by: Tejas Upadhyay <tejas.upadhyay@intel.com>
+(cherry picked from commit 0a78a44f4901aa6c9263e66be7fce02282f1109f)
+Signed-off-by: Matthew Brost <matthew.brost@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/xe/xe_guc_capture.c |   11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+--- a/drivers/gpu/drm/xe/xe_guc_capture.c
++++ b/drivers/gpu/drm/xe/xe_guc_capture.c
+@@ -437,8 +437,15 @@ static void guc_capture_alloc_steered_li
+       if (!list || guc->capture->extlists)
+               return;
+-      total = bitmap_weight(gt->fuse_topo.g_dss_mask, sizeof(gt->fuse_topo.g_dss_mask) * 8) *
+-              guc_capture_get_steer_reg_num(guc_to_xe(guc));
++      {
++              xe_dss_mask_t all_dss;
++
++              bitmap_or(all_dss, gt->fuse_topo.g_dss_mask, gt->fuse_topo.c_dss_mask,
++                        XE_MAX_DSS_FUSE_BITS);
++
++              total = bitmap_weight(all_dss, XE_MAX_DSS_FUSE_BITS) *
++                      guc_capture_get_steer_reg_num(guc_to_xe(guc));
++      }
+       if (!total)
+               return;
index 8ffe76d83c3f169ead386b5c3b2925d5009b21fb..cf76768f2a5e964b609b1d1834256eac097c4f38 100644 (file)
@@ -370,3 +370,8 @@ media-qcom-camss-fix-rdi-streaming-for-csid-340.patch
 media-uapi-rkisp-correct-name-version-enum.patch
 wifi-brcmfmac-drain-bus_reset-work-on-device-removal.patch
 userfaultfd-prevent-registration-of-special-vmas.patch
+drm-fb-helper-allocate-and-release-fb_info-in-single-place.patch
+drm-tegra-fbdev-remove-offset-into-framebuffer-memory.patch
+drm-amdgpu-fix-context-pstate-override-handling.patch
+drm-amdgpu-respect-placement-requirements-in-amdgpu_gtt_mgr-functions.patch
+drm-xe-guc-fix-buffer-overflow-in-steered-register-list-allocation.patch