drm-misc-fixes for v7.2:

- drm/sysfb truncation and alignment fixes.
 - fix edid OOB read.
 - fix error handling paths in nouveau
 - amdxdna get_bo_info fix.
 - increase displayid topology id to correct size.
 - fix leak when error handling in ivpu.
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEuXvWqAysSYEJGuVH/lWMcqZwE8MFAmo85ykACgkQ/lWMcqZw
 E8PkLRAAkGV32MLBhUH8Pcim59wwUr9CgTh8s49m4a/bckBOAWLfc/v1S3lclmAg
 ov9kS4MptrBkg+7HDK6+3EWWaugQ5e18fS1xMtCpgL0Or8BKG+EaSNjLycJc4Xj8
 XDnc9VxRfTBwImN398HWtQhhfXE3cUxgR8pxCnDN2/q+p8C+wG6FxB8d4cSAEzZx
 mAZasLd8sAyTTIRhYJL5Knxhr0Qgylb8zidCTF5TRWz5YSxC0eqgWpwlWrLiwQ+m
 Zr+zCmo3nEWVxGdh+saWjjxcCHxjvaoQaeeYBWc4xc88C30kKYqf1ApTloi59A1O
 D8iHXwU7qTwrUJbKDZv4W3lKd5u+h35qzHIJJldPK79M4LLfEcTMj/tZqYGLz4tP
 4buzdlvFgDP48sc989Uku8IDnQHEEeene0oslNaDuSfTJLqOKf/J7Ru0Jggctwdp
 EGDwWCGrnGS7EPxhThRSEh3DwmAQKlstJ8tfhgLa5jaM0g73sKiM7Ho0oeNwJFnr
 HkDkweIeFD1/CqJiFyvlHA37Wqa5pZoiptRsqrCdFNalTIMN4UGBat2x2zrAlqFI
 88YImrqNKZKHqbJIiAWWcTRc2/8dLh6GU/u4Y0mUl26vj8cD2tkBu9exN3fUraCq
 kQMhVvEBFVDW3fcv3zl7TaeOy28dL54Obgh37p/xcdFYoEVASrg=
 =zErp
 -----END PGP SIGNATURE-----

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

drm-misc-fixes for v7.2:
- drm/sysfb truncation and alignment fixes.
- fix edid OOB read.
- fix error handling paths in nouveau
- amdxdna get_bo_info fix.
- increase displayid topology id to correct size.
- fix leak when error handling in ivpu.

Signed-off-by: Dave Airlie <airlied@redhat.com>

From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: https://patch.msgid.link/2d17f718-43f5-4772-9c04-a975c9ad4bc3@linux.intel.com
This commit is contained in:
Dave Airlie 2026-06-26 08:16:14 +10:00
commit f24ba334af
13 changed files with 48 additions and 30 deletions

View File

@ -1027,6 +1027,7 @@ int amdxdna_drm_get_bo_info_ioctl(struct drm_device *dev, void *data, struct drm
int amdxdna_drm_sync_bo_ioctl(struct drm_device *dev,
void *data, struct drm_file *filp)
{
struct amdxdna_client *client = filp->driver_priv;
struct amdxdna_dev *xdna = to_xdna_dev(dev);
struct amdxdna_drm_sync_bo *args = data;
struct amdxdna_gem_obj *abo;
@ -1061,7 +1062,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

@ -3576,7 +3576,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.
*
@ -3584,14 +3584,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);
@ -3606,7 +3606,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.
@ -3615,7 +3615,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;
@ -3625,7 +3625,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

@ -150,7 +150,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;
@ -204,8 +205,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

@ -400,7 +400,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;
@ -455,8 +455,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);