Skip to content

Commit 4a622d7

Browse files
committed
drm/atomic: Add support for mouse hotspots
jira VULN-136708 cve-bf CVE-2025-38449 commit-author Zack Rusin <zackr@vmware.com> commit 8f7179a Atomic modesetting code lacked support for specifying mouse cursor hotspots. The legacy kms DRM_IOCTL_MODE_CURSOR2 had support for setting the hotspot but the functionality was not implemented in the new atomic paths. Due to the lack of hotspots in the atomic paths userspace compositors completely disable atomic modesetting for drivers that require it (i.e. all paravirtualized drivers). This change adds hotspot properties to the atomic codepaths throughtout the DRM core and will allow enabling atomic modesetting for virtualized drivers in the userspace. Signed-off-by: Zack Rusin <zackr@vmware.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Maxime Ripard <mripard@kernel.org> Cc: Thomas Zimmermann <tzimmermann@suse.de> Cc: David Airlie <airlied@linux.ie> Cc: Daniel Vetter <daniel@ffwll.ch> Reviewed-by: Javier Martinez Canillas <javierm@redhat.com> Signed-off-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20231023074613.41327-3-aesteve@redhat.com (cherry picked from commit 8f7179a) Signed-off-by: Roxana Nicolescu <rnicolescu@ciq.com>
1 parent 0c8ae49 commit 4a622d7

File tree

4 files changed

+98
-0
lines changed

4 files changed

+98
-0
lines changed

drivers/gpu/drm/drm_atomic_state_helper.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,20 @@ void __drm_atomic_helper_plane_state_reset(struct drm_plane_state *plane_state,
275275
plane_state->normalized_zpos = val;
276276
}
277277
}
278+
279+
if (plane->hotspot_x_property) {
280+
if (!drm_object_property_get_default_value(&plane->base,
281+
plane->hotspot_x_property,
282+
&val))
283+
plane_state->hotspot_x = val;
284+
}
285+
286+
if (plane->hotspot_y_property) {
287+
if (!drm_object_property_get_default_value(&plane->base,
288+
plane->hotspot_y_property,
289+
&val))
290+
plane_state->hotspot_y = val;
291+
}
278292
}
279293
EXPORT_SYMBOL(__drm_atomic_helper_plane_state_reset);
280294

drivers/gpu/drm/drm_atomic_uapi.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -593,6 +593,22 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane,
593593
} else if (plane->funcs->atomic_set_property) {
594594
return plane->funcs->atomic_set_property(plane, state,
595595
property, val);
596+
} else if (property == plane->hotspot_x_property) {
597+
if (plane->type != DRM_PLANE_TYPE_CURSOR) {
598+
drm_dbg_atomic(plane->dev,
599+
"[PLANE:%d:%s] is not a cursor plane: 0x%llx\n",
600+
plane->base.id, plane->name, val);
601+
return -EINVAL;
602+
}
603+
state->hotspot_x = val;
604+
} else if (property == plane->hotspot_y_property) {
605+
if (plane->type != DRM_PLANE_TYPE_CURSOR) {
606+
drm_dbg_atomic(plane->dev,
607+
"[PLANE:%d:%s] is not a cursor plane: 0x%llx\n",
608+
plane->base.id, plane->name, val);
609+
return -EINVAL;
610+
}
611+
state->hotspot_y = val;
596612
} else {
597613
drm_dbg_atomic(plane->dev,
598614
"[PLANE:%d:%s] unknown property [PROP:%d:%s]\n",
@@ -653,6 +669,10 @@ drm_atomic_plane_get_property(struct drm_plane *plane,
653669
*val = state->scaling_filter;
654670
} else if (plane->funcs->atomic_get_property) {
655671
return plane->funcs->atomic_get_property(plane, state, property, val);
672+
} else if (property == plane->hotspot_x_property) {
673+
*val = state->hotspot_x;
674+
} else if (property == plane->hotspot_y_property) {
675+
*val = state->hotspot_y;
656676
} else {
657677
drm_dbg_atomic(dev,
658678
"[PLANE:%d:%s] unknown property [PROP:%d:%s]\n",

drivers/gpu/drm/drm_plane.c

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,47 @@ static int create_in_format_blob(struct drm_device *dev, struct drm_plane *plane
230230
return 0;
231231
}
232232

233+
/**
234+
* drm_plane_create_hotspot_properties - creates the mouse hotspot
235+
* properties and attaches them to the given cursor plane
236+
*
237+
* @plane: drm cursor plane
238+
*
239+
* This function enables the mouse hotspot property on a given
240+
* cursor plane.
241+
*
242+
* RETURNS:
243+
* Zero for success or -errno
244+
*/
245+
static int drm_plane_create_hotspot_properties(struct drm_plane *plane)
246+
{
247+
struct drm_property *prop_x;
248+
struct drm_property *prop_y;
249+
250+
drm_WARN_ON(plane->dev,
251+
!drm_core_check_feature(plane->dev,
252+
DRIVER_CURSOR_HOTSPOT));
253+
254+
prop_x = drm_property_create_signed_range(plane->dev, 0, "HOTSPOT_X",
255+
INT_MIN, INT_MAX);
256+
if (IS_ERR(prop_x))
257+
return PTR_ERR(prop_x);
258+
259+
prop_y = drm_property_create_signed_range(plane->dev, 0, "HOTSPOT_Y",
260+
INT_MIN, INT_MAX);
261+
if (IS_ERR(prop_y)) {
262+
drm_property_destroy(plane->dev, prop_x);
263+
return PTR_ERR(prop_y);
264+
}
265+
266+
drm_object_attach_property(&plane->base, prop_x, 0);
267+
drm_object_attach_property(&plane->base, prop_y, 0);
268+
plane->hotspot_x_property = prop_x;
269+
plane->hotspot_y_property = prop_y;
270+
271+
return 0;
272+
}
273+
233274
__printf(9, 0)
234275
static int __drm_universal_plane_init(struct drm_device *dev,
235276
struct drm_plane *plane,
@@ -348,6 +389,10 @@ static int __drm_universal_plane_init(struct drm_device *dev,
348389
drm_object_attach_property(&plane->base, config->prop_src_w, 0);
349390
drm_object_attach_property(&plane->base, config->prop_src_h, 0);
350391
}
392+
if (drm_core_check_feature(dev, DRIVER_CURSOR_HOTSPOT) &&
393+
type == DRM_PLANE_TYPE_CURSOR) {
394+
drm_plane_create_hotspot_properties(plane);
395+
}
351396

352397
if (format_modifier_count)
353398
create_in_format_blob(dev, plane);
@@ -1067,6 +1112,11 @@ static int drm_mode_cursor_universal(struct drm_crtc *crtc,
10671112

10681113
fb->hot_x = req->hot_x;
10691114
fb->hot_y = req->hot_y;
1115+
1116+
if (plane->hotspot_x_property && plane->state)
1117+
plane->state->hotspot_x = req->hot_x;
1118+
if (plane->hotspot_y_property && plane->state)
1119+
plane->state->hotspot_y = req->hot_y;
10701120
} else {
10711121
fb = NULL;
10721122
}

include/drm/drm_plane.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,10 @@ struct drm_plane_state {
116116
/** @src_h: height of visible portion of plane (in 16.16) */
117117
uint32_t src_h, src_w;
118118

119+
/** @hotspot_x: x offset to mouse cursor hotspot */
120+
/** @hotspot_y: y offset to mouse cursor hotspot */
121+
int32_t hotspot_x, hotspot_y;
122+
119123
/**
120124
* @alpha:
121125
* Opacity of the plane with 0 as completely transparent and 0xffff as
@@ -758,6 +762,16 @@ struct drm_plane {
758762
* scaling.
759763
*/
760764
struct drm_property *scaling_filter_property;
765+
766+
/**
767+
* @hotspot_x_property: property to set mouse hotspot x offset.
768+
*/
769+
struct drm_property *hotspot_x_property;
770+
771+
/**
772+
* @hotspot_y_property: property to set mouse hotspot y offset.
773+
*/
774+
struct drm_property *hotspot_y_property;
761775
};
762776

763777
#define obj_to_plane(x) container_of(x, struct drm_plane, base)

0 commit comments

Comments
 (0)