drm fixes for 7.2-rc1

sysfb
 - drm/sysfb truncation and alignment fixes.
 
 edid:
 - fix edid OOB read in tile parsing
 - increase displayid topology id to correct size.
 
 nouveau:
 - fix error handling paths in nouveau
 
 amdxdna:
 - get_bo_info fix.
 
 ivpu:
 - fix leak when error handling in ivpu.
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEEKbZHaGwW9KfbeusDHTzWXnEhr4FAmo+66wACgkQDHTzWXnE
 hr57fA/+OFujGvUqlbAiYOUMCdkR6MgRnqqYotSXwyjGXdu8hTNjTqKbvXqrgM+6
 XSJZuvQC30BJGyQFDVzGLOjGgMS6EBrMY1/dJfUCmiKn1pyeJbhWR1zMMYAo+R2+
 G/cLSC/xWEx+0EDzk/wpa8cxiP7uQZaXNZOnoYe3V6NZTTMsTRys+oZulxFPJWgm
 /I6fsh94PpEZX//P37RAeFnOsBraoBF4RbWq7eAc3goCMcOrT5Dsl+chefxRWdks
 5QlBKo1ageDG7FOVVA6mdTQ+CW41i0Te18jjn7mSjF6RI8FIS06mU16YKbruYqjh
 3nVe9ZqHIZg1QTj+6qsBh+Doeo6aKTojWjp5idYeL0Plsoa47kk0Ox3KuNjOG8v5
 9rcMa7uBB52QEBHF8QqSaONFB4Cnz16S1aeBznhR2I2uOR3U17s9Q8WVGr0dE1Wc
 vPgfp/NMan1drro1ywB+80vCytcKRm1UT0+FiTHndMXI5YbV5XnF92wbqGIHia9C
 K0bBw67DtDOKtnCXlYv6Mxsi7WV1Dh4kXzeoBJjgqZop0S4bbbAhTN5LtHzoKv5x
 W1LmEHIb6QRXz54GvUwKsIZY2IsZoPBFG6gE5ik1QmXKbAmSiQxvPwff0JPLnt3v
 dnoK9XdnqtKwr6tW5kB/HJh95AkMk/OQGR8jo7Al6tMLiQuityg=
 =eLQl
 -----END PGP SIGNATURE-----

Merge tag 'drm-fixes-2026-06-27' of https://gitlab.freedesktop.org/drm/kernel

Pull drm fixes from Dave Airlie:
 "These are just the fixes from our fixes branch, all pretty small and
  scattered.

  sysfb:
   - drm/sysfb truncation and alignment fixes

  edid:
   - fix edid OOB read in tile parsing
   - increase displayid topology id to correct size

  nouveau:
   - fix error handling paths in nouveau

  amdxdna:
   - get_bo_info fix

  ivpu:
   - fix leak when error handling in ivpu"

* tag 'drm-fixes-2026-06-27' of https://gitlab.freedesktop.org/drm/kernel:
  drm/sysfb: Avoid truncating maximum stride
  drm/sysfb: Return errno code from drm_sysfb_get_visible_size()
  drm/sysfb: Avoid possible truncation with calculating visible size
  drm/sysfb: Do not page-align visible size of the framebuffer
  drm/edid: fix OOB read in drm_parse_tiled_block()
  drm/nouveau: fix reversed error cleanup order in ucopy functions
  drm/nouveau/acr: fix missing nvkm_done() in error path of nvkm_acr_oneinit()
  accel/amdxdna: Use caller client for debug BO sync
  drm/displayid: fix Tiled Display Topology ID size
  accel/ivpu: fix HWS command queue leak on registration failure
This commit is contained in:
Linus Torvalds 2026-06-26 17:03:48 -07:00
commit 5a66900afb
13 changed files with 47 additions and 30 deletions

View File

@ -1300,7 +1300,7 @@ int amdxdna_drm_sync_bo_ioctl(struct drm_device *dev,
args->handle, args->offset, args->size);
if (args->direction == SYNC_DIRECT_FROM_DEVICE)
ret = amdxdna_hwctx_sync_debug_bo(abo->client, args->handle);
ret = amdxdna_hwctx_sync_debug_bo(client, args->handle);
put_obj:
drm_gem_object_put(gobj);

View File

@ -208,9 +208,9 @@ static int ivpu_hws_cmdq_init(struct ivpu_file_priv *file_priv, struct ivpu_cmdq
ret = ivpu_jsm_hws_set_context_sched_properties(vdev, file_priv->ctx.id, cmdq->id,
priority);
if (ret)
return ret;
ivpu_jsm_hws_destroy_cmdq(vdev, file_priv->ctx.id, cmdq->id);
return 0;
return ret;
}
static int ivpu_register_db(struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cmdq)
@ -281,10 +281,10 @@ static int ivpu_cmdq_register(struct ivpu_file_priv *file_priv, struct ivpu_cmdq
}
ret = ivpu_register_db(file_priv, cmdq);
if (ret)
return ret;
if (ret && vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW)
ivpu_jsm_hws_destroy_cmdq(vdev, file_priv->ctx.id, cmdq->id);
return 0;
return ret;
}
static int ivpu_cmdq_unregister(struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cmdq)

View File

@ -3571,7 +3571,7 @@ EXPORT_SYMBOL(drm_mode_put_tile_group);
/**
* drm_mode_get_tile_group - get a reference to an existing tile group
* @dev: DRM device
* @topology: 8-bytes unique per monitor.
* @topology_id: 9-byte unique ID per monitor.
*
* Use the unique bytes to get a reference to an existing tile group.
*
@ -3579,14 +3579,14 @@ EXPORT_SYMBOL(drm_mode_put_tile_group);
* tile group or NULL if not found.
*/
struct drm_tile_group *drm_mode_get_tile_group(struct drm_device *dev,
const char topology[8])
const char topology_id[9])
{
struct drm_tile_group *tg;
int id;
mutex_lock(&dev->mode_config.idr_mutex);
idr_for_each_entry(&dev->mode_config.tile_idr, tg, id) {
if (!memcmp(tg->group_data, topology, 8)) {
if (!memcmp(tg->group_data, topology_id, sizeof(tg->group_data))) {
if (!kref_get_unless_zero(&tg->refcount))
tg = NULL;
mutex_unlock(&dev->mode_config.idr_mutex);
@ -3601,7 +3601,7 @@ EXPORT_SYMBOL(drm_mode_get_tile_group);
/**
* drm_mode_create_tile_group - create a tile group from a displayid description
* @dev: DRM device
* @topology: 8-bytes unique per monitor.
* @topology_id: 9-byte unique ID per monitor.
*
* Create a tile group for the unique monitor, and get a unique
* identifier for the tile group.
@ -3610,7 +3610,7 @@ EXPORT_SYMBOL(drm_mode_get_tile_group);
* new tile group or NULL.
*/
struct drm_tile_group *drm_mode_create_tile_group(struct drm_device *dev,
const char topology[8])
const char topology_id[9])
{
struct drm_tile_group *tg;
int ret;
@ -3620,7 +3620,7 @@ struct drm_tile_group *drm_mode_create_tile_group(struct drm_device *dev,
return NULL;
kref_init(&tg->refcount);
memcpy(tg->group_data, topology, 8);
memcpy(tg->group_data, topology_id, sizeof(tg->group_data));
tg->dev = dev;
mutex_lock(&dev->mode_config.idr_mutex);

View File

@ -109,7 +109,7 @@ struct displayid_tiled_block {
u8 topo[3];
u8 tile_size[4];
u8 tile_pixel_bezel[5];
u8 topology_id[8];
u8 topology_id[9];
} __packed;
struct displayid_detailed_timings_1 {

View File

@ -7575,6 +7575,14 @@ static void drm_parse_tiled_block(struct drm_connector *connector,
u8 num_v_tile, num_h_tile;
struct drm_tile_group *tg;
/* tiled block payload per spec: cap 1 + topo 3 + size 4 + bezel 5 + id 9 = 22 */
if (block->num_bytes < 22) {
drm_dbg_kms(connector->dev,
"[CONNECTOR:%d:%s] Unexpected tiled block size %u\n",
connector->base.id, connector->name, block->num_bytes);
return;
}
w = tile->tile_size[0] | tile->tile_size[1] << 8;
h = tile->tile_size[2] | tile->tile_size[3] << 8;

View File

@ -331,10 +331,10 @@ nouveau_exec_ucopy(struct nouveau_exec_job_args *args,
return 0;
err_free_pushs:
u_free(args->push.s);
err_free_ins:
u_free(args->in_sync.s);
err_free_pushs:
u_free(args->push.s);
return ret;
}

View File

@ -1779,10 +1779,10 @@ nouveau_uvmm_vm_bind_ucopy(struct nouveau_uvmm_bind_job_args *args,
return 0;
err_free_ops:
u_free(args->op.s);
err_free_ins:
u_free(args->in_sync.s);
err_free_ops:
u_free(args->op.s);
return ret;
}

View File

@ -315,6 +315,7 @@ nvkm_acr_oneinit(struct nvkm_subdev *subdev)
i, us, fw);
}
}
nvkm_done(acr->wpr);
return -EINVAL;
}
nvkm_done(acr->wpr);

View File

@ -50,7 +50,7 @@ struct resource *drm_sysfb_get_memory_si(struct drm_device *dev,
int drm_sysfb_get_stride_si(struct drm_device *dev, const struct screen_info *si,
const struct drm_format_info *format,
unsigned int width, unsigned int height, u64 size);
u64 drm_sysfb_get_visible_size_si(struct drm_device *dev, const struct screen_info *si,
s64 drm_sysfb_get_visible_size_si(struct drm_device *dev, const struct screen_info *si,
unsigned int height, unsigned int stride, u64 size);
#endif

View File

@ -2,6 +2,7 @@
#include <linux/export.h>
#include <linux/limits.h>
#include <linux/math64.h>
#include <linux/minmax.h>
#include <linux/screen_info.h>
@ -56,18 +57,24 @@ int drm_sysfb_get_stride_si(struct drm_device *dev, const struct screen_info *si
unsigned int width, unsigned int height, u64 size)
{
u64 lfb_linelength = si->lfb_linelength;
s64 stride;
if (!lfb_linelength)
lfb_linelength = drm_format_info_min_pitch(format, 0, width);
return drm_sysfb_get_validated_int0(dev, "stride", lfb_linelength, div64_u64(size, height));
stride = drm_sysfb_get_validated_size0(dev, "stride", lfb_linelength,
div64_u64(size, height));
if (stride < INT_MIN || stride > INT_MAX)
return -EINVAL;
return (int)stride; /* stride or negative errno code */
}
EXPORT_SYMBOL(drm_sysfb_get_stride_si);
u64 drm_sysfb_get_visible_size_si(struct drm_device *dev, const struct screen_info *si,
s64 drm_sysfb_get_visible_size_si(struct drm_device *dev, const struct screen_info *si,
unsigned int height, unsigned int stride, u64 size)
{
u64 vsize = PAGE_ALIGN(height * stride);
u64 vsize = mul_u32_u32(height, stride);
return drm_sysfb_get_validated_size0(dev, "visible size", vsize, size);
}

View File

@ -152,7 +152,8 @@ static struct efidrm_device *efidrm_device_create(struct drm_driver *drv,
const struct screen_info *si;
const struct drm_format_info *format;
int width, height, stride;
u64 vsize, mem_flags;
s64 vsize;
u64 mem_flags;
struct resource resbuf;
struct resource *res;
struct efidrm_device *efi;
@ -206,8 +207,8 @@ static struct efidrm_device *efidrm_device_create(struct drm_driver *drv,
if (stride < 0)
return ERR_PTR(stride);
vsize = drm_sysfb_get_visible_size_si(dev, si, height, stride, resource_size(res));
if (!vsize)
return ERR_PTR(-EINVAL);
if (vsize < 0)
return ERR_PTR(vsize);
drm_dbg(dev, "framebuffer format=%p4cc, size=%dx%d, stride=%d bytes\n",
&format->format, width, height, stride);

View File

@ -402,7 +402,7 @@ static struct vesadrm_device *vesadrm_device_create(struct drm_driver *drv,
const struct screen_info *si;
const struct drm_format_info *format;
int width, height, stride;
u64 vsize;
s64 vsize;
struct resource resbuf;
struct resource *res;
struct vesadrm_device *vesa;
@ -457,8 +457,8 @@ static struct vesadrm_device *vesadrm_device_create(struct drm_driver *drv,
if (stride < 0)
return ERR_PTR(stride);
vsize = drm_sysfb_get_visible_size_si(dev, si, height, stride, resource_size(res));
if (!vsize)
return ERR_PTR(-EINVAL);
if (vsize < 0)
return ERR_PTR(vsize);
drm_dbg(dev, "framebuffer format=%p4cc, size=%dx%d, stride=%d bytes\n",
&format->format, width, height, stride);

View File

@ -2608,13 +2608,13 @@ struct drm_tile_group {
struct kref refcount;
struct drm_device *dev;
int id;
u8 group_data[8];
u8 group_data[9];
};
struct drm_tile_group *drm_mode_create_tile_group(struct drm_device *dev,
const char topology[8]);
const char topology_id[9]);
struct drm_tile_group *drm_mode_get_tile_group(struct drm_device *dev,
const char topology[8]);
const char topology_id[9]);
void drm_mode_put_tile_group(struct drm_device *dev,
struct drm_tile_group *tg);