* [PATCH 0/6] drm: Add drm mode object leases
@ 2017-10-11 0:48 ` Keith Packard
0 siblings, 0 replies; 21+ messages in thread
From: Keith Packard @ 2017-10-11 0:48 UTC (permalink / raw)
To: linux-kernel, Dave Airlie, Daniel Vetter; +Cc: Keith Packard, dri-devel
New since last time:
* Fix vboxvideo driver in staging
* Fixed some formatting and whitespace errors (Dave Airlie)
* Explain the odd use of the idr interface for leases (Dave Airlie)
* Disallow negative object_id in lease creation (Dave Airlie)
It's also been rebased on top of the drm-sequence-64 sequence just
sent out so that merging one and then the other will be simplified.
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 1/6] drm: Pass struct drm_file * to __drm_mode_object_find [v2]
2017-10-11 0:48 ` Keith Packard
@ 2017-10-11 0:48 ` Keith Packard
-1 siblings, 0 replies; 21+ messages in thread
From: Keith Packard @ 2017-10-11 0:48 UTC (permalink / raw)
To: linux-kernel, Dave Airlie, Daniel Vetter; +Cc: Keith Packard, dri-devel
This will allow __drm_mode_object_file to be extended to perform
access control checks based on the file in use.
v2: Also fix up vboxvideo driver in staging
Suggested-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Keith Packard <keithp@keithp.com>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c | 16 ++++++++--------
drivers/gpu/drm/amd/amdgpu/dce_virtual.c | 4 ++--
drivers/gpu/drm/ast/ast_mode.c | 2 +-
drivers/gpu/drm/bochs/bochs_kms.c | 2 +-
drivers/gpu/drm/cirrus/cirrus_mode.c | 2 +-
drivers/gpu/drm/drm_atomic.c | 8 ++++----
drivers/gpu/drm/drm_atomic_helper.c | 2 +-
drivers/gpu/drm/drm_color_mgmt.c | 4 ++--
drivers/gpu/drm/drm_connector.c | 2 +-
drivers/gpu/drm/drm_crtc.c | 8 ++++----
drivers/gpu/drm/drm_crtc_internal.h | 1 +
drivers/gpu/drm/drm_encoder.c | 2 +-
drivers/gpu/drm/drm_framebuffer.c | 9 +++++----
drivers/gpu/drm/drm_mode_object.c | 10 ++++++----
drivers/gpu/drm/drm_plane.c | 14 +++++++-------
drivers/gpu/drm/drm_probe_helper.c | 2 +-
drivers/gpu/drm/drm_property.c | 6 +++---
drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c | 2 +-
drivers/gpu/drm/i915/intel_display.c | 2 +-
drivers/gpu/drm/i915/intel_overlay.c | 2 +-
drivers/gpu/drm/i915/intel_sprite.c | 2 +-
drivers/gpu/drm/mgag200/mgag200_mode.c | 2 +-
drivers/gpu/drm/nouveau/nouveau_connector.c | 4 ++--
drivers/gpu/drm/radeon/r100.c | 2 +-
drivers/gpu/drm/radeon/r600_cs.c | 2 +-
drivers/gpu/drm/radeon/radeon_connectors.c | 16 ++++++++--------
drivers/gpu/drm/udl/udl_connector.c | 2 +-
drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c | 4 ++--
drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 2 +-
drivers/staging/vboxvideo/vbox_mode.c | 2 +-
include/drm/drm_connector.h | 3 ++-
include/drm/drm_crtc.h | 5 +++--
include/drm/drm_encoder.h | 3 ++-
include/drm/drm_framebuffer.h | 1 +
include/drm/drm_mode_object.h | 2 ++
include/drm/drm_plane.h | 3 ++-
include/drm/drm_property.h | 3 ++-
37 files changed, 85 insertions(+), 73 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
index f51b41f094ef..df9cbc78e168 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
@@ -231,7 +231,7 @@ amdgpu_connector_update_scratch_regs(struct drm_connector *connector,
if (connector->encoder_ids[i] == 0)
break;
- encoder = drm_encoder_find(connector->dev,
+ encoder = drm_encoder_find(connector->dev, NULL,
connector->encoder_ids[i]);
if (!encoder)
continue;
@@ -256,7 +256,7 @@ amdgpu_connector_find_encoder(struct drm_connector *connector,
for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
if (connector->encoder_ids[i] == 0)
break;
- encoder = drm_encoder_find(connector->dev,
+ encoder = drm_encoder_find(connector->dev, NULL,
connector->encoder_ids[i]);
if (!encoder)
continue;
@@ -372,7 +372,7 @@ amdgpu_connector_best_single_encoder(struct drm_connector *connector)
/* pick the encoder ids */
if (enc_id)
- return drm_encoder_find(connector->dev, enc_id);
+ return drm_encoder_find(connector->dev, NULL, enc_id);
return NULL;
}
@@ -1077,7 +1077,7 @@ amdgpu_connector_dvi_detect(struct drm_connector *connector, bool force)
if (connector->encoder_ids[i] == 0)
break;
- encoder = drm_encoder_find(connector->dev, connector->encoder_ids[i]);
+ encoder = drm_encoder_find(connector->dev, NULL, connector->encoder_ids[i]);
if (!encoder)
continue;
@@ -1134,7 +1134,7 @@ amdgpu_connector_dvi_encoder(struct drm_connector *connector)
if (connector->encoder_ids[i] == 0)
break;
- encoder = drm_encoder_find(connector->dev, connector->encoder_ids[i]);
+ encoder = drm_encoder_find(connector->dev, NULL, connector->encoder_ids[i]);
if (!encoder)
continue;
@@ -1153,7 +1153,7 @@ amdgpu_connector_dvi_encoder(struct drm_connector *connector)
/* then check use digitial */
/* pick the first one */
if (enc_id)
- return drm_encoder_find(connector->dev, enc_id);
+ return drm_encoder_find(connector->dev, NULL, enc_id);
return NULL;
}
@@ -1294,7 +1294,7 @@ u16 amdgpu_connector_encoder_get_dp_bridge_encoder_id(struct drm_connector *conn
if (connector->encoder_ids[i] == 0)
break;
- encoder = drm_encoder_find(connector->dev,
+ encoder = drm_encoder_find(connector->dev, NULL,
connector->encoder_ids[i]);
if (!encoder)
continue;
@@ -1323,7 +1323,7 @@ static bool amdgpu_connector_encoder_is_hbr2(struct drm_connector *connector)
for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
if (connector->encoder_ids[i] == 0)
break;
- encoder = drm_encoder_find(connector->dev,
+ encoder = drm_encoder_find(connector->dev, NULL,
connector->encoder_ids[i]);
if (!encoder)
continue;
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
index b9ee9073cb0d..a8829af120c1 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
@@ -288,7 +288,7 @@ dce_virtual_encoder(struct drm_connector *connector)
if (connector->encoder_ids[i] == 0)
break;
- encoder = drm_encoder_find(connector->dev, connector->encoder_ids[i]);
+ encoder = drm_encoder_find(connector->dev, NULL, connector->encoder_ids[i]);
if (!encoder)
continue;
@@ -298,7 +298,7 @@ dce_virtual_encoder(struct drm_connector *connector)
/* pick the first one */
if (enc_id)
- return drm_encoder_find(connector->dev, enc_id);
+ return drm_encoder_find(connector->dev, NULL, enc_id);
return NULL;
}
diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c
index 6f3849ec0c1d..9555a3542022 100644
--- a/drivers/gpu/drm/ast/ast_mode.c
+++ b/drivers/gpu/drm/ast/ast_mode.c
@@ -713,7 +713,7 @@ static struct drm_encoder *ast_best_single_encoder(struct drm_connector *connect
int enc_id = connector->encoder_ids[0];
/* pick the encoder ids */
if (enc_id)
- return drm_encoder_find(connector->dev, enc_id);
+ return drm_encoder_find(connector->dev, NULL, enc_id);
return NULL;
}
diff --git a/drivers/gpu/drm/bochs/bochs_kms.c b/drivers/gpu/drm/bochs/bochs_kms.c
index 6a91e62da2f4..a24a18fbd65a 100644
--- a/drivers/gpu/drm/bochs/bochs_kms.c
+++ b/drivers/gpu/drm/bochs/bochs_kms.c
@@ -213,7 +213,7 @@ bochs_connector_best_encoder(struct drm_connector *connector)
int enc_id = connector->encoder_ids[0];
/* pick the encoder ids */
if (enc_id)
- return drm_encoder_find(connector->dev, enc_id);
+ return drm_encoder_find(connector->dev, NULL, enc_id);
return NULL;
}
diff --git a/drivers/gpu/drm/cirrus/cirrus_mode.c b/drivers/gpu/drm/cirrus/cirrus_mode.c
index a4c4a465b385..cd23b1b28259 100644
--- a/drivers/gpu/drm/cirrus/cirrus_mode.c
+++ b/drivers/gpu/drm/cirrus/cirrus_mode.c
@@ -457,7 +457,7 @@ static struct drm_encoder *cirrus_connector_best_encoder(struct drm_connector
int enc_id = connector->encoder_ids[0];
/* pick the encoder ids */
if (enc_id)
- return drm_encoder_find(connector->dev, enc_id);
+ return drm_encoder_find(connector->dev, NULL, enc_id);
return NULL;
}
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 08ff1b023f7b..1e2021bed265 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -718,7 +718,7 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane,
struct drm_mode_config *config = &dev->mode_config;
if (property == config->prop_fb_id) {
- struct drm_framebuffer *fb = drm_framebuffer_lookup(dev, val);
+ struct drm_framebuffer *fb = drm_framebuffer_lookup(dev, NULL, val);
drm_atomic_set_fb_for_plane(state, fb);
if (fb)
drm_framebuffer_put(fb);
@@ -734,7 +734,7 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane,
return -EINVAL;
} else if (property == config->prop_crtc_id) {
- struct drm_crtc *crtc = drm_crtc_find(dev, val);
+ struct drm_crtc *crtc = drm_crtc_find(dev, NULL, val);
return drm_atomic_set_crtc_for_plane(state, crtc);
} else if (property == config->prop_crtc_x) {
state->crtc_x = U642I64(val);
@@ -1149,7 +1149,7 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector,
struct drm_mode_config *config = &dev->mode_config;
if (property == config->prop_crtc_id) {
- struct drm_crtc *crtc = drm_crtc_find(dev, val);
+ struct drm_crtc *crtc = drm_crtc_find(dev, NULL, val);
return drm_atomic_set_crtc_for_connector(state, crtc);
} else if (property == config->dpms_property) {
/* setting DPMS property requires special handling, which
@@ -2260,7 +2260,7 @@ int drm_mode_atomic_ioctl(struct drm_device *dev,
goto out;
}
- obj = drm_mode_object_find(dev, obj_id, DRM_MODE_OBJECT_ANY);
+ obj = drm_mode_object_find(dev, file_priv, obj_id, DRM_MODE_OBJECT_ANY);
if (!obj) {
ret = -ENOENT;
goto out;
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 01c34bc5b5b0..c49fbc4db3b5 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -3206,7 +3206,7 @@ struct drm_encoder *
drm_atomic_helper_best_encoder(struct drm_connector *connector)
{
WARN_ON(connector->encoder_ids[1]);
- return drm_encoder_find(connector->dev, connector->encoder_ids[0]);
+ return drm_encoder_find(connector->dev, NULL, connector->encoder_ids[0]);
}
EXPORT_SYMBOL(drm_atomic_helper_best_encoder);
diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c
index fe0982708e95..0d002b045bd2 100644
--- a/drivers/gpu/drm/drm_color_mgmt.c
+++ b/drivers/gpu/drm/drm_color_mgmt.c
@@ -230,7 +230,7 @@ int drm_mode_gamma_set_ioctl(struct drm_device *dev,
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
- crtc = drm_crtc_find(dev, crtc_lut->crtc_id);
+ crtc = drm_crtc_find(dev, file_priv, crtc_lut->crtc_id);
if (!crtc)
return -ENOENT;
@@ -308,7 +308,7 @@ int drm_mode_gamma_get_ioctl(struct drm_device *dev,
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
- crtc = drm_crtc_find(dev, crtc_lut->crtc_id);
+ crtc = drm_crtc_find(dev, file_priv, crtc_lut->crtc_id);
if (!crtc)
return -ENOENT;
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index d8ca526ca4ee..704fc8934616 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -1310,7 +1310,7 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
memset(&u_mode, 0, sizeof(struct drm_mode_modeinfo));
- connector = drm_connector_lookup(dev, out_resp->connector_id);
+ connector = drm_connector_lookup(dev, file_priv, out_resp->connector_id);
if (!connector)
return -ENOENT;
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 68b4e976d5e0..f0556e654116 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -402,7 +402,7 @@ int drm_mode_getcrtc(struct drm_device *dev,
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
- crtc = drm_crtc_find(dev, crtc_resp->crtc_id);
+ crtc = drm_crtc_find(dev, file_priv, crtc_resp->crtc_id);
if (!crtc)
return -ENOENT;
@@ -569,7 +569,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
if (crtc_req->x & 0xffff0000 || crtc_req->y & 0xffff0000)
return -ERANGE;
- crtc = drm_crtc_find(dev, crtc_req->crtc_id);
+ crtc = drm_crtc_find(dev, file_priv, crtc_req->crtc_id);
if (!crtc) {
DRM_DEBUG_KMS("Unknown CRTC ID %d\n", crtc_req->crtc_id);
return -ENOENT;
@@ -595,7 +595,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
/* Make refcounting symmetric with the lookup path. */
drm_framebuffer_get(fb);
} else {
- fb = drm_framebuffer_lookup(dev, crtc_req->fb_id);
+ fb = drm_framebuffer_lookup(dev, file_priv, crtc_req->fb_id);
if (!fb) {
DRM_DEBUG_KMS("Unknown FB ID%d\n",
crtc_req->fb_id);
@@ -680,7 +680,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
goto out;
}
- connector = drm_connector_lookup(dev, out_id);
+ connector = drm_connector_lookup(dev, file_priv, out_id);
if (!connector) {
DRM_DEBUG_KMS("Connector id %d unknown\n",
out_id);
diff --git a/drivers/gpu/drm/drm_crtc_internal.h b/drivers/gpu/drm/drm_crtc_internal.h
index a43582076b20..9ebb8841778c 100644
--- a/drivers/gpu/drm/drm_crtc_internal.h
+++ b/drivers/gpu/drm/drm_crtc_internal.h
@@ -106,6 +106,7 @@ int drm_mode_object_add(struct drm_device *dev, struct drm_mode_object *obj,
void drm_mode_object_register(struct drm_device *dev,
struct drm_mode_object *obj);
struct drm_mode_object *__drm_mode_object_find(struct drm_device *dev,
+ struct drm_file *file_priv,
uint32_t id, uint32_t type);
void drm_mode_object_unregister(struct drm_device *dev,
struct drm_mode_object *object);
diff --git a/drivers/gpu/drm/drm_encoder.c b/drivers/gpu/drm/drm_encoder.c
index 0708779840d2..43f644844b83 100644
--- a/drivers/gpu/drm/drm_encoder.c
+++ b/drivers/gpu/drm/drm_encoder.c
@@ -220,7 +220,7 @@ int drm_mode_getencoder(struct drm_device *dev, void *data,
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
- encoder = drm_encoder_find(dev, enc_resp->encoder_id);
+ encoder = drm_encoder_find(dev, file_priv, enc_resp->encoder_id);
if (!encoder)
return -ENOENT;
diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c
index af279844d7ce..2affe53f3fda 100644
--- a/drivers/gpu/drm/drm_framebuffer.c
+++ b/drivers/gpu/drm/drm_framebuffer.c
@@ -381,7 +381,7 @@ int drm_mode_rmfb(struct drm_device *dev,
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
- fb = drm_framebuffer_lookup(dev, *id);
+ fb = drm_framebuffer_lookup(dev, file_priv, *id);
if (!fb)
return -ENOENT;
@@ -450,7 +450,7 @@ int drm_mode_getfb(struct drm_device *dev,
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
- fb = drm_framebuffer_lookup(dev, r->fb_id);
+ fb = drm_framebuffer_lookup(dev, file_priv, r->fb_id);
if (!fb)
return -ENOENT;
@@ -515,7 +515,7 @@ int drm_mode_dirtyfb_ioctl(struct drm_device *dev,
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
- fb = drm_framebuffer_lookup(dev, r->fb_id);
+ fb = drm_framebuffer_lookup(dev, file_priv, r->fb_id);
if (!fb)
return -ENOENT;
@@ -688,12 +688,13 @@ EXPORT_SYMBOL(drm_framebuffer_init);
* again, using drm_framebuffer_put().
*/
struct drm_framebuffer *drm_framebuffer_lookup(struct drm_device *dev,
+ struct drm_file *file_priv,
uint32_t id)
{
struct drm_mode_object *obj;
struct drm_framebuffer *fb = NULL;
- obj = __drm_mode_object_find(dev, id, DRM_MODE_OBJECT_FB);
+ obj = __drm_mode_object_find(dev, file_priv, id, DRM_MODE_OBJECT_FB);
if (obj)
fb = obj_to_fb(obj);
return fb;
diff --git a/drivers/gpu/drm/drm_mode_object.c b/drivers/gpu/drm/drm_mode_object.c
index 7a1ea91d3343..240a05d91a53 100644
--- a/drivers/gpu/drm/drm_mode_object.c
+++ b/drivers/gpu/drm/drm_mode_object.c
@@ -105,6 +105,7 @@ void drm_mode_object_unregister(struct drm_device *dev,
}
struct drm_mode_object *__drm_mode_object_find(struct drm_device *dev,
+ struct drm_file *file_priv,
uint32_t id, uint32_t type)
{
struct drm_mode_object *obj = NULL;
@@ -127,7 +128,7 @@ struct drm_mode_object *__drm_mode_object_find(struct drm_device *dev,
/**
* drm_mode_object_find - look up a drm object with static lifetime
- * @dev: drm device
+ * @file_priv: drm file
* @id: id of the mode object
* @type: type of the mode object
*
@@ -136,11 +137,12 @@ struct drm_mode_object *__drm_mode_object_find(struct drm_device *dev,
* by callind drm_mode_object_put().
*/
struct drm_mode_object *drm_mode_object_find(struct drm_device *dev,
+ struct drm_file *file_priv,
uint32_t id, uint32_t type)
{
struct drm_mode_object *obj = NULL;
- obj = __drm_mode_object_find(dev, id, type);
+ obj = __drm_mode_object_find(dev, file_priv, id, type);
return obj;
}
EXPORT_SYMBOL(drm_mode_object_find);
@@ -359,7 +361,7 @@ int drm_mode_obj_get_properties_ioctl(struct drm_device *dev, void *data,
drm_modeset_lock_all(dev);
- obj = drm_mode_object_find(dev, arg->obj_id, arg->obj_type);
+ obj = drm_mode_object_find(dev, file_priv, arg->obj_id, arg->obj_type);
if (!obj) {
ret = -ENOENT;
goto out;
@@ -481,7 +483,7 @@ int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
- arg_obj = drm_mode_object_find(dev, arg->obj_id, arg->obj_type);
+ arg_obj = drm_mode_object_find(dev, file_priv, arg->obj_id, arg->obj_type);
if (!arg_obj)
return -ENOENT;
diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c
index 192071209baa..574fd1475214 100644
--- a/drivers/gpu/drm/drm_plane.c
+++ b/drivers/gpu/drm/drm_plane.c
@@ -513,7 +513,7 @@ int drm_mode_getplane(struct drm_device *dev, void *data,
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
- plane = drm_plane_find(dev, plane_resp->plane_id);
+ plane = drm_plane_find(dev, file_priv, plane_resp->plane_id);
if (!plane)
return -ENOENT;
@@ -703,7 +703,7 @@ int drm_mode_setplane(struct drm_device *dev, void *data,
* First, find the plane, crtc, and fb objects. If not available,
* we don't bother to call the driver.
*/
- plane = drm_plane_find(dev, plane_req->plane_id);
+ plane = drm_plane_find(dev, file_priv, plane_req->plane_id);
if (!plane) {
DRM_DEBUG_KMS("Unknown plane ID %d\n",
plane_req->plane_id);
@@ -711,14 +711,14 @@ int drm_mode_setplane(struct drm_device *dev, void *data,
}
if (plane_req->fb_id) {
- fb = drm_framebuffer_lookup(dev, plane_req->fb_id);
+ fb = drm_framebuffer_lookup(dev, file_priv, plane_req->fb_id);
if (!fb) {
DRM_DEBUG_KMS("Unknown framebuffer ID %d\n",
plane_req->fb_id);
return -ENOENT;
}
- crtc = drm_crtc_find(dev, plane_req->crtc_id);
+ crtc = drm_crtc_find(dev, file_priv, plane_req->crtc_id);
if (!crtc) {
drm_framebuffer_put(fb);
DRM_DEBUG_KMS("Unknown crtc ID %d\n",
@@ -829,7 +829,7 @@ static int drm_mode_cursor_common(struct drm_device *dev,
if (!req->flags || (~DRM_MODE_CURSOR_FLAGS & req->flags))
return -EINVAL;
- crtc = drm_crtc_find(dev, req->crtc_id);
+ crtc = drm_crtc_find(dev, file_priv, req->crtc_id);
if (!crtc) {
DRM_DEBUG_KMS("Unknown CRTC ID %d\n", req->crtc_id);
return -ENOENT;
@@ -944,7 +944,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
if ((page_flip->flags & DRM_MODE_PAGE_FLIP_ASYNC) && !dev->mode_config.async_page_flip)
return -EINVAL;
- crtc = drm_crtc_find(dev, page_flip->crtc_id);
+ crtc = drm_crtc_find(dev, file_priv, page_flip->crtc_id);
if (!crtc)
return -ENOENT;
@@ -1005,7 +1005,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
goto out;
}
- fb = drm_framebuffer_lookup(dev, page_flip->fb_id);
+ fb = drm_framebuffer_lookup(dev, file_priv, page_flip->fb_id);
if (!fb) {
ret = -ENOENT;
goto out;
diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c
index 5840aabbf24e..6dc2dde5b672 100644
--- a/drivers/gpu/drm/drm_probe_helper.c
+++ b/drivers/gpu/drm/drm_probe_helper.c
@@ -99,7 +99,7 @@ drm_mode_validate_pipeline(struct drm_display_mode *mode,
/* Step 2: Validate against encoders and crtcs */
for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
- struct drm_encoder *encoder = drm_encoder_find(dev, ids[i]);
+ struct drm_encoder *encoder = drm_encoder_find(dev, NULL, ids[i]);
struct drm_crtc *crtc;
if (!encoder)
diff --git a/drivers/gpu/drm/drm_property.c b/drivers/gpu/drm/drm_property.c
index bc5128203056..bae50e6b819d 100644
--- a/drivers/gpu/drm/drm_property.c
+++ b/drivers/gpu/drm/drm_property.c
@@ -450,7 +450,7 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev,
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
- property = drm_property_find(dev, out_resp->prop_id);
+ property = drm_property_find(dev, file_priv, out_resp->prop_id);
if (!property)
return -ENOENT;
@@ -634,7 +634,7 @@ struct drm_property_blob *drm_property_lookup_blob(struct drm_device *dev,
struct drm_mode_object *obj;
struct drm_property_blob *blob = NULL;
- obj = __drm_mode_object_find(dev, id, DRM_MODE_OBJECT_BLOB);
+ obj = __drm_mode_object_find(dev, NULL, id, DRM_MODE_OBJECT_BLOB);
if (obj)
blob = obj_to_blob(obj);
return blob;
@@ -897,7 +897,7 @@ bool drm_property_change_valid_get(struct drm_property *property,
if (value == 0)
return true;
- *ref = __drm_mode_object_find(property->dev, value,
+ *ref = __drm_mode_object_find(property->dev, NULL, value,
property->values[0]);
return *ref != NULL;
}
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
index ec4dd9df9150..f4eba87c96f3 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
@@ -36,7 +36,7 @@ static int hibmc_connector_mode_valid(struct drm_connector *connector,
static struct drm_encoder *
hibmc_connector_best_encoder(struct drm_connector *connector)
{
- return drm_encoder_find(connector->dev, connector->encoder_ids[0]);
+ return drm_encoder_find(connector->dev, NULL, connector->encoder_ids[0]);
}
static const struct drm_connector_helper_funcs
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index f780f39e0758..0bec6deaae4f 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -13511,7 +13511,7 @@ int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
struct drm_crtc *drmmode_crtc;
struct intel_crtc *crtc;
- drmmode_crtc = drm_crtc_find(dev, pipe_from_crtc_id->crtc_id);
+ drmmode_crtc = drm_crtc_find(dev, file, pipe_from_crtc_id->crtc_id);
if (!drmmode_crtc)
return -ENOENT;
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c
index aace22e7ccac..1b397b41cb4f 100644
--- a/drivers/gpu/drm/i915/intel_overlay.c
+++ b/drivers/gpu/drm/i915/intel_overlay.c
@@ -1134,7 +1134,7 @@ int intel_overlay_put_image_ioctl(struct drm_device *dev, void *data,
if (!params)
return -ENOMEM;
- drmmode_crtc = drm_crtc_find(dev, put_image_rec->crtc_id);
+ drmmode_crtc = drm_crtc_find(dev, file_priv, put_image_rec->crtc_id);
if (!drmmode_crtc) {
ret = -ENOENT;
goto out_free;
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index b0d6e3e28d07..28a1209d87e2 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -994,7 +994,7 @@ int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
set->flags & I915_SET_COLORKEY_DESTINATION)
return -EINVAL;
- plane = drm_plane_find(dev, set->plane_id);
+ plane = drm_plane_find(dev, file_priv, set->plane_id);
if (!plane || plane->type != DRM_PLANE_TYPE_OVERLAY)
return -ENOENT;
diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c
index 5e9cd4c0e8b6..68e5d9c94475 100644
--- a/drivers/gpu/drm/mgag200/mgag200_mode.c
+++ b/drivers/gpu/drm/mgag200/mgag200_mode.c
@@ -1670,7 +1670,7 @@ static struct drm_encoder *mga_connector_best_encoder(struct drm_connector
int enc_id = connector->encoder_ids[0];
/* pick the encoder ids */
if (enc_id)
- return drm_encoder_find(connector->dev, enc_id);
+ return drm_encoder_find(connector->dev, NULL, enc_id);
return NULL;
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c
index 70d8e0d69ad5..69d6e61a01ec 100644
--- a/drivers/gpu/drm/nouveau/nouveau_connector.c
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
@@ -373,7 +373,7 @@ find_encoder(struct drm_connector *connector, int type)
if (!id)
break;
- enc = drm_encoder_find(dev, id);
+ enc = drm_encoder_find(dev, NULL, id);
if (!enc)
continue;
nv_encoder = nouveau_encoder(enc);
@@ -441,7 +441,7 @@ nouveau_connector_ddc_detect(struct drm_connector *connector)
if (id == 0)
break;
- encoder = drm_encoder_find(dev, id);
+ encoder = drm_encoder_find(dev, NULL, id);
if (!encoder)
continue;
nv_encoder = nouveau_encoder(encoder);
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index c31e660e35db..7d39ed63e5be 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -1456,7 +1456,7 @@ int r100_cs_packet_parse_vline(struct radeon_cs_parser *p)
header = radeon_get_ib_value(p, h_idx);
crtc_id = radeon_get_ib_value(p, h_idx + 5);
reg = R100_CP_PACKET0_GET_REG(header);
- crtc = drm_crtc_find(p->rdev->ddev, crtc_id);
+ crtc = drm_crtc_find(p->rdev->ddev, p->filp, crtc_id);
if (!crtc) {
DRM_ERROR("cannot find crtc %d\n", crtc_id);
return -ENOENT;
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c
index 97fd58e97043..c96b31950ca7 100644
--- a/drivers/gpu/drm/radeon/r600_cs.c
+++ b/drivers/gpu/drm/radeon/r600_cs.c
@@ -887,7 +887,7 @@ int r600_cs_common_vline_parse(struct radeon_cs_parser *p,
crtc_id = radeon_get_ib_value(p, h_idx + 2 + 7 + 1);
reg = R600_CP_PACKET0_GET_REG(header);
- crtc = drm_crtc_find(p->rdev->ddev, crtc_id);
+ crtc = drm_crtc_find(p->rdev->ddev, p->filp, crtc_id);
if (!crtc) {
DRM_ERROR("cannot find crtc %d\n", crtc_id);
return -ENOENT;
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
index 2f642cbefd8e..59dcefb2df3b 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -263,7 +263,7 @@ radeon_connector_update_scratch_regs(struct drm_connector *connector, enum drm_c
if (connector->encoder_ids[i] == 0)
break;
- encoder = drm_encoder_find(connector->dev,
+ encoder = drm_encoder_find(connector->dev, NULL,
connector->encoder_ids[i]);
if (!encoder)
continue;
@@ -290,7 +290,7 @@ static struct drm_encoder *radeon_find_encoder(struct drm_connector *connector,
if (connector->encoder_ids[i] == 0)
break;
- encoder = drm_encoder_find(connector->dev, connector->encoder_ids[i]);
+ encoder = drm_encoder_find(connector->dev, NULL, connector->encoder_ids[i]);
if (!encoder)
continue;
@@ -404,7 +404,7 @@ static struct drm_encoder *radeon_best_single_encoder(struct drm_connector *conn
int enc_id = connector->encoder_ids[0];
/* pick the encoder ids */
if (enc_id)
- return drm_encoder_find(connector->dev, enc_id);
+ return drm_encoder_find(connector->dev, NULL, enc_id);
return NULL;
}
@@ -1368,7 +1368,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)
if (connector->encoder_ids[i] == 0)
break;
- encoder = drm_encoder_find(connector->dev,
+ encoder = drm_encoder_find(connector->dev, NULL,
connector->encoder_ids[i]);
if (!encoder)
continue;
@@ -1454,7 +1454,7 @@ static struct drm_encoder *radeon_dvi_encoder(struct drm_connector *connector)
if (connector->encoder_ids[i] == 0)
break;
- encoder = drm_encoder_find(connector->dev, connector->encoder_ids[i]);
+ encoder = drm_encoder_find(connector->dev, NULL, connector->encoder_ids[i]);
if (!encoder)
continue;
@@ -1473,7 +1473,7 @@ static struct drm_encoder *radeon_dvi_encoder(struct drm_connector *connector)
/* then check use digitial */
/* pick the first one */
if (enc_id)
- return drm_encoder_find(connector->dev, enc_id);
+ return drm_encoder_find(connector->dev, NULL, enc_id);
return NULL;
}
@@ -1620,7 +1620,7 @@ u16 radeon_connector_encoder_get_dp_bridge_encoder_id(struct drm_connector *conn
if (connector->encoder_ids[i] == 0)
break;
- encoder = drm_encoder_find(connector->dev, connector->encoder_ids[i]);
+ encoder = drm_encoder_find(connector->dev, NULL, connector->encoder_ids[i]);
if (!encoder)
continue;
@@ -1649,7 +1649,7 @@ static bool radeon_connector_encoder_is_hbr2(struct drm_connector *connector)
if (connector->encoder_ids[i] == 0)
break;
- encoder = drm_encoder_find(connector->dev, connector->encoder_ids[i]);
+ encoder = drm_encoder_find(connector->dev, NULL, connector->encoder_ids[i]);
if (!encoder)
continue;
diff --git a/drivers/gpu/drm/udl/udl_connector.c b/drivers/gpu/drm/udl/udl_connector.c
index 9f9a49748d17..091ca81658eb 100644
--- a/drivers/gpu/drm/udl/udl_connector.c
+++ b/drivers/gpu/drm/udl/udl_connector.c
@@ -105,7 +105,7 @@ static struct drm_encoder*
udl_best_single_encoder(struct drm_connector *connector)
{
int enc_id = connector->encoder_ids[0];
- return drm_encoder_find(connector->dev, enc_id);
+ return drm_encoder_find(connector->dev, NULL, enc_id);
}
static int udl_connector_set_property(struct drm_connector *connector,
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
index 5ec24fd801cd..01be355525e4 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
@@ -286,7 +286,7 @@ int vmw_present_ioctl(struct drm_device *dev, void *data,
drm_modeset_lock_all(dev);
- fb = drm_framebuffer_lookup(dev, arg->fb_id);
+ fb = drm_framebuffer_lookup(dev, file_priv, arg->fb_id);
if (!fb) {
DRM_ERROR("Invalid framebuffer id.\n");
ret = -ENOENT;
@@ -369,7 +369,7 @@ int vmw_present_readback_ioctl(struct drm_device *dev, void *data,
drm_modeset_lock_all(dev);
- fb = drm_framebuffer_lookup(dev, arg->fb_id);
+ fb = drm_framebuffer_lookup(dev, file_priv, arg->fb_id);
if (!fb) {
DRM_ERROR("Invalid framebuffer id.\n");
ret = -ENOENT;
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index b850562fbdd6..0545740b3724 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -1726,7 +1726,7 @@ int vmw_kms_cursor_bypass_ioctl(struct drm_device *dev, void *data,
return 0;
}
- crtc = drm_crtc_find(dev, arg->crtc_id);
+ crtc = drm_crtc_find(dev, file_priv, arg->crtc_id);
if (!crtc) {
ret = -ENOENT;
goto out;
diff --git a/drivers/staging/vboxvideo/vbox_mode.c b/drivers/staging/vboxvideo/vbox_mode.c
index 257a77830410..c745a0402c68 100644
--- a/drivers/staging/vboxvideo/vbox_mode.c
+++ b/drivers/staging/vboxvideo/vbox_mode.c
@@ -377,7 +377,7 @@ static struct drm_encoder *vbox_best_single_encoder(struct drm_connector
/* pick the encoder ids */
if (enc_id)
- return drm_encoder_find(connector->dev, enc_id);
+ return drm_encoder_find(connector->dev, NULL, enc_id);
return NULL;
}
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index b34904dc8b9b..b4285c40e1e4 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -939,10 +939,11 @@ static inline unsigned drm_connector_index(struct drm_connector *connector)
* add takes a reference to it.
*/
static inline struct drm_connector *drm_connector_lookup(struct drm_device *dev,
+ struct drm_file *file_priv,
uint32_t id)
{
struct drm_mode_object *mo;
- mo = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_CONNECTOR);
+ mo = drm_mode_object_find(dev, file_priv, id, DRM_MODE_OBJECT_CONNECTOR);
return mo ? obj_to_connector(mo) : NULL;
}
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 80c97210eda5..f7fcceef46d9 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -959,10 +959,11 @@ struct drm_crtc *drm_crtc_from_index(struct drm_device *dev, int idx);
* userspace interface should be done using &drm_property.
*/
static inline struct drm_crtc *drm_crtc_find(struct drm_device *dev,
- uint32_t id)
+ struct drm_file *file_priv,
+ uint32_t id)
{
struct drm_mode_object *mo;
- mo = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_CRTC);
+ mo = drm_mode_object_find(dev, file_priv, id, DRM_MODE_OBJECT_CRTC);
return mo ? obj_to_crtc(mo) : NULL;
}
diff --git a/include/drm/drm_encoder.h b/include/drm/drm_encoder.h
index 8d8245ec0181..86db0da8bdcb 100644
--- a/include/drm/drm_encoder.h
+++ b/include/drm/drm_encoder.h
@@ -214,11 +214,12 @@ static inline bool drm_encoder_crtc_ok(struct drm_encoder *encoder,
* drm_mode_object_find().
*/
static inline struct drm_encoder *drm_encoder_find(struct drm_device *dev,
+ struct drm_file *file_priv,
uint32_t id)
{
struct drm_mode_object *mo;
- mo = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_ENCODER);
+ mo = drm_mode_object_find(dev, file_priv, id, DRM_MODE_OBJECT_ENCODER);
return mo ? obj_to_encoder(mo) : NULL;
}
diff --git a/include/drm/drm_framebuffer.h b/include/drm/drm_framebuffer.h
index b6996ddb19d6..4c5ee4ae54df 100644
--- a/include/drm/drm_framebuffer.h
+++ b/include/drm/drm_framebuffer.h
@@ -205,6 +205,7 @@ int drm_framebuffer_init(struct drm_device *dev,
struct drm_framebuffer *fb,
const struct drm_framebuffer_funcs *funcs);
struct drm_framebuffer *drm_framebuffer_lookup(struct drm_device *dev,
+ struct drm_file *file_priv,
uint32_t id);
void drm_framebuffer_remove(struct drm_framebuffer *fb);
void drm_framebuffer_cleanup(struct drm_framebuffer *fb);
diff --git a/include/drm/drm_mode_object.h b/include/drm/drm_mode_object.h
index a767b4a30a6d..b2f920b518e3 100644
--- a/include/drm/drm_mode_object.h
+++ b/include/drm/drm_mode_object.h
@@ -27,6 +27,7 @@
struct drm_object_properties;
struct drm_property;
struct drm_device;
+struct drm_file;
/**
* struct drm_mode_object - base structure for modeset objects
@@ -113,6 +114,7 @@ struct drm_object_properties {
}
struct drm_mode_object *drm_mode_object_find(struct drm_device *dev,
+ struct drm_file *file_priv,
uint32_t id, uint32_t type);
void drm_mode_object_get(struct drm_mode_object *obj);
void drm_mode_object_put(struct drm_mode_object *obj);
diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h
index 82a217bd77f0..069c4c8ce360 100644
--- a/include/drm/drm_plane.h
+++ b/include/drm/drm_plane.h
@@ -597,10 +597,11 @@ int drm_mode_plane_set_obj_prop(struct drm_plane *plane,
* drm_mode_object_find().
*/
static inline struct drm_plane *drm_plane_find(struct drm_device *dev,
+ struct drm_file *file_priv,
uint32_t id)
{
struct drm_mode_object *mo;
- mo = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_PLANE);
+ mo = drm_mode_object_find(dev, file_priv, id, DRM_MODE_OBJECT_PLANE);
return mo ? obj_to_plane(mo) : NULL;
}
diff --git a/include/drm/drm_property.h b/include/drm/drm_property.h
index 37355c623e6c..429d8218f740 100644
--- a/include/drm/drm_property.h
+++ b/include/drm/drm_property.h
@@ -312,10 +312,11 @@ drm_property_unreference_blob(struct drm_property_blob *blob)
* This function looks up the property object specified by id and returns it.
*/
static inline struct drm_property *drm_property_find(struct drm_device *dev,
+ struct drm_file *file_priv,
uint32_t id)
{
struct drm_mode_object *mo;
- mo = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_PROPERTY);
+ mo = drm_mode_object_find(dev, file_priv, id, DRM_MODE_OBJECT_PROPERTY);
return mo ? obj_to_property(mo) : NULL;
}
--
2.13.3
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 1/6] drm: Pass struct drm_file * to __drm_mode_object_find [v2]
@ 2017-10-11 0:48 ` Keith Packard
0 siblings, 0 replies; 21+ messages in thread
From: Keith Packard @ 2017-10-11 0:48 UTC (permalink / raw)
To: linux-kernel, Dave Airlie, Daniel Vetter; +Cc: Keith Packard, dri-devel
This will allow __drm_mode_object_file to be extended to perform
access control checks based on the file in use.
v2: Also fix up vboxvideo driver in staging
Suggested-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Keith Packard <keithp@keithp.com>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c | 16 ++++++++--------
drivers/gpu/drm/amd/amdgpu/dce_virtual.c | 4 ++--
drivers/gpu/drm/ast/ast_mode.c | 2 +-
drivers/gpu/drm/bochs/bochs_kms.c | 2 +-
drivers/gpu/drm/cirrus/cirrus_mode.c | 2 +-
drivers/gpu/drm/drm_atomic.c | 8 ++++----
drivers/gpu/drm/drm_atomic_helper.c | 2 +-
drivers/gpu/drm/drm_color_mgmt.c | 4 ++--
drivers/gpu/drm/drm_connector.c | 2 +-
drivers/gpu/drm/drm_crtc.c | 8 ++++----
drivers/gpu/drm/drm_crtc_internal.h | 1 +
drivers/gpu/drm/drm_encoder.c | 2 +-
drivers/gpu/drm/drm_framebuffer.c | 9 +++++----
drivers/gpu/drm/drm_mode_object.c | 10 ++++++----
drivers/gpu/drm/drm_plane.c | 14 +++++++-------
drivers/gpu/drm/drm_probe_helper.c | 2 +-
drivers/gpu/drm/drm_property.c | 6 +++---
drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c | 2 +-
drivers/gpu/drm/i915/intel_display.c | 2 +-
drivers/gpu/drm/i915/intel_overlay.c | 2 +-
drivers/gpu/drm/i915/intel_sprite.c | 2 +-
drivers/gpu/drm/mgag200/mgag200_mode.c | 2 +-
drivers/gpu/drm/nouveau/nouveau_connector.c | 4 ++--
drivers/gpu/drm/radeon/r100.c | 2 +-
drivers/gpu/drm/radeon/r600_cs.c | 2 +-
drivers/gpu/drm/radeon/radeon_connectors.c | 16 ++++++++--------
drivers/gpu/drm/udl/udl_connector.c | 2 +-
drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c | 4 ++--
drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 2 +-
drivers/staging/vboxvideo/vbox_mode.c | 2 +-
include/drm/drm_connector.h | 3 ++-
include/drm/drm_crtc.h | 5 +++--
include/drm/drm_encoder.h | 3 ++-
include/drm/drm_framebuffer.h | 1 +
include/drm/drm_mode_object.h | 2 ++
include/drm/drm_plane.h | 3 ++-
include/drm/drm_property.h | 3 ++-
37 files changed, 85 insertions(+), 73 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
index f51b41f094ef..df9cbc78e168 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
@@ -231,7 +231,7 @@ amdgpu_connector_update_scratch_regs(struct drm_connector *connector,
if (connector->encoder_ids[i] == 0)
break;
- encoder = drm_encoder_find(connector->dev,
+ encoder = drm_encoder_find(connector->dev, NULL,
connector->encoder_ids[i]);
if (!encoder)
continue;
@@ -256,7 +256,7 @@ amdgpu_connector_find_encoder(struct drm_connector *connector,
for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
if (connector->encoder_ids[i] == 0)
break;
- encoder = drm_encoder_find(connector->dev,
+ encoder = drm_encoder_find(connector->dev, NULL,
connector->encoder_ids[i]);
if (!encoder)
continue;
@@ -372,7 +372,7 @@ amdgpu_connector_best_single_encoder(struct drm_connector *connector)
/* pick the encoder ids */
if (enc_id)
- return drm_encoder_find(connector->dev, enc_id);
+ return drm_encoder_find(connector->dev, NULL, enc_id);
return NULL;
}
@@ -1077,7 +1077,7 @@ amdgpu_connector_dvi_detect(struct drm_connector *connector, bool force)
if (connector->encoder_ids[i] == 0)
break;
- encoder = drm_encoder_find(connector->dev, connector->encoder_ids[i]);
+ encoder = drm_encoder_find(connector->dev, NULL, connector->encoder_ids[i]);
if (!encoder)
continue;
@@ -1134,7 +1134,7 @@ amdgpu_connector_dvi_encoder(struct drm_connector *connector)
if (connector->encoder_ids[i] == 0)
break;
- encoder = drm_encoder_find(connector->dev, connector->encoder_ids[i]);
+ encoder = drm_encoder_find(connector->dev, NULL, connector->encoder_ids[i]);
if (!encoder)
continue;
@@ -1153,7 +1153,7 @@ amdgpu_connector_dvi_encoder(struct drm_connector *connector)
/* then check use digitial */
/* pick the first one */
if (enc_id)
- return drm_encoder_find(connector->dev, enc_id);
+ return drm_encoder_find(connector->dev, NULL, enc_id);
return NULL;
}
@@ -1294,7 +1294,7 @@ u16 amdgpu_connector_encoder_get_dp_bridge_encoder_id(struct drm_connector *conn
if (connector->encoder_ids[i] == 0)
break;
- encoder = drm_encoder_find(connector->dev,
+ encoder = drm_encoder_find(connector->dev, NULL,
connector->encoder_ids[i]);
if (!encoder)
continue;
@@ -1323,7 +1323,7 @@ static bool amdgpu_connector_encoder_is_hbr2(struct drm_connector *connector)
for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
if (connector->encoder_ids[i] == 0)
break;
- encoder = drm_encoder_find(connector->dev,
+ encoder = drm_encoder_find(connector->dev, NULL,
connector->encoder_ids[i]);
if (!encoder)
continue;
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
index b9ee9073cb0d..a8829af120c1 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
@@ -288,7 +288,7 @@ dce_virtual_encoder(struct drm_connector *connector)
if (connector->encoder_ids[i] == 0)
break;
- encoder = drm_encoder_find(connector->dev, connector->encoder_ids[i]);
+ encoder = drm_encoder_find(connector->dev, NULL, connector->encoder_ids[i]);
if (!encoder)
continue;
@@ -298,7 +298,7 @@ dce_virtual_encoder(struct drm_connector *connector)
/* pick the first one */
if (enc_id)
- return drm_encoder_find(connector->dev, enc_id);
+ return drm_encoder_find(connector->dev, NULL, enc_id);
return NULL;
}
diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c
index 6f3849ec0c1d..9555a3542022 100644
--- a/drivers/gpu/drm/ast/ast_mode.c
+++ b/drivers/gpu/drm/ast/ast_mode.c
@@ -713,7 +713,7 @@ static struct drm_encoder *ast_best_single_encoder(struct drm_connector *connect
int enc_id = connector->encoder_ids[0];
/* pick the encoder ids */
if (enc_id)
- return drm_encoder_find(connector->dev, enc_id);
+ return drm_encoder_find(connector->dev, NULL, enc_id);
return NULL;
}
diff --git a/drivers/gpu/drm/bochs/bochs_kms.c b/drivers/gpu/drm/bochs/bochs_kms.c
index 6a91e62da2f4..a24a18fbd65a 100644
--- a/drivers/gpu/drm/bochs/bochs_kms.c
+++ b/drivers/gpu/drm/bochs/bochs_kms.c
@@ -213,7 +213,7 @@ bochs_connector_best_encoder(struct drm_connector *connector)
int enc_id = connector->encoder_ids[0];
/* pick the encoder ids */
if (enc_id)
- return drm_encoder_find(connector->dev, enc_id);
+ return drm_encoder_find(connector->dev, NULL, enc_id);
return NULL;
}
diff --git a/drivers/gpu/drm/cirrus/cirrus_mode.c b/drivers/gpu/drm/cirrus/cirrus_mode.c
index a4c4a465b385..cd23b1b28259 100644
--- a/drivers/gpu/drm/cirrus/cirrus_mode.c
+++ b/drivers/gpu/drm/cirrus/cirrus_mode.c
@@ -457,7 +457,7 @@ static struct drm_encoder *cirrus_connector_best_encoder(struct drm_connector
int enc_id = connector->encoder_ids[0];
/* pick the encoder ids */
if (enc_id)
- return drm_encoder_find(connector->dev, enc_id);
+ return drm_encoder_find(connector->dev, NULL, enc_id);
return NULL;
}
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 08ff1b023f7b..1e2021bed265 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -718,7 +718,7 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane,
struct drm_mode_config *config = &dev->mode_config;
if (property == config->prop_fb_id) {
- struct drm_framebuffer *fb = drm_framebuffer_lookup(dev, val);
+ struct drm_framebuffer *fb = drm_framebuffer_lookup(dev, NULL, val);
drm_atomic_set_fb_for_plane(state, fb);
if (fb)
drm_framebuffer_put(fb);
@@ -734,7 +734,7 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane,
return -EINVAL;
} else if (property == config->prop_crtc_id) {
- struct drm_crtc *crtc = drm_crtc_find(dev, val);
+ struct drm_crtc *crtc = drm_crtc_find(dev, NULL, val);
return drm_atomic_set_crtc_for_plane(state, crtc);
} else if (property == config->prop_crtc_x) {
state->crtc_x = U642I64(val);
@@ -1149,7 +1149,7 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector,
struct drm_mode_config *config = &dev->mode_config;
if (property == config->prop_crtc_id) {
- struct drm_crtc *crtc = drm_crtc_find(dev, val);
+ struct drm_crtc *crtc = drm_crtc_find(dev, NULL, val);
return drm_atomic_set_crtc_for_connector(state, crtc);
} else if (property == config->dpms_property) {
/* setting DPMS property requires special handling, which
@@ -2260,7 +2260,7 @@ int drm_mode_atomic_ioctl(struct drm_device *dev,
goto out;
}
- obj = drm_mode_object_find(dev, obj_id, DRM_MODE_OBJECT_ANY);
+ obj = drm_mode_object_find(dev, file_priv, obj_id, DRM_MODE_OBJECT_ANY);
if (!obj) {
ret = -ENOENT;
goto out;
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 01c34bc5b5b0..c49fbc4db3b5 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -3206,7 +3206,7 @@ struct drm_encoder *
drm_atomic_helper_best_encoder(struct drm_connector *connector)
{
WARN_ON(connector->encoder_ids[1]);
- return drm_encoder_find(connector->dev, connector->encoder_ids[0]);
+ return drm_encoder_find(connector->dev, NULL, connector->encoder_ids[0]);
}
EXPORT_SYMBOL(drm_atomic_helper_best_encoder);
diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c
index fe0982708e95..0d002b045bd2 100644
--- a/drivers/gpu/drm/drm_color_mgmt.c
+++ b/drivers/gpu/drm/drm_color_mgmt.c
@@ -230,7 +230,7 @@ int drm_mode_gamma_set_ioctl(struct drm_device *dev,
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
- crtc = drm_crtc_find(dev, crtc_lut->crtc_id);
+ crtc = drm_crtc_find(dev, file_priv, crtc_lut->crtc_id);
if (!crtc)
return -ENOENT;
@@ -308,7 +308,7 @@ int drm_mode_gamma_get_ioctl(struct drm_device *dev,
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
- crtc = drm_crtc_find(dev, crtc_lut->crtc_id);
+ crtc = drm_crtc_find(dev, file_priv, crtc_lut->crtc_id);
if (!crtc)
return -ENOENT;
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index d8ca526ca4ee..704fc8934616 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -1310,7 +1310,7 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
memset(&u_mode, 0, sizeof(struct drm_mode_modeinfo));
- connector = drm_connector_lookup(dev, out_resp->connector_id);
+ connector = drm_connector_lookup(dev, file_priv, out_resp->connector_id);
if (!connector)
return -ENOENT;
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 68b4e976d5e0..f0556e654116 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -402,7 +402,7 @@ int drm_mode_getcrtc(struct drm_device *dev,
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
- crtc = drm_crtc_find(dev, crtc_resp->crtc_id);
+ crtc = drm_crtc_find(dev, file_priv, crtc_resp->crtc_id);
if (!crtc)
return -ENOENT;
@@ -569,7 +569,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
if (crtc_req->x & 0xffff0000 || crtc_req->y & 0xffff0000)
return -ERANGE;
- crtc = drm_crtc_find(dev, crtc_req->crtc_id);
+ crtc = drm_crtc_find(dev, file_priv, crtc_req->crtc_id);
if (!crtc) {
DRM_DEBUG_KMS("Unknown CRTC ID %d\n", crtc_req->crtc_id);
return -ENOENT;
@@ -595,7 +595,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
/* Make refcounting symmetric with the lookup path. */
drm_framebuffer_get(fb);
} else {
- fb = drm_framebuffer_lookup(dev, crtc_req->fb_id);
+ fb = drm_framebuffer_lookup(dev, file_priv, crtc_req->fb_id);
if (!fb) {
DRM_DEBUG_KMS("Unknown FB ID%d\n",
crtc_req->fb_id);
@@ -680,7 +680,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
goto out;
}
- connector = drm_connector_lookup(dev, out_id);
+ connector = drm_connector_lookup(dev, file_priv, out_id);
if (!connector) {
DRM_DEBUG_KMS("Connector id %d unknown\n",
out_id);
diff --git a/drivers/gpu/drm/drm_crtc_internal.h b/drivers/gpu/drm/drm_crtc_internal.h
index a43582076b20..9ebb8841778c 100644
--- a/drivers/gpu/drm/drm_crtc_internal.h
+++ b/drivers/gpu/drm/drm_crtc_internal.h
@@ -106,6 +106,7 @@ int drm_mode_object_add(struct drm_device *dev, struct drm_mode_object *obj,
void drm_mode_object_register(struct drm_device *dev,
struct drm_mode_object *obj);
struct drm_mode_object *__drm_mode_object_find(struct drm_device *dev,
+ struct drm_file *file_priv,
uint32_t id, uint32_t type);
void drm_mode_object_unregister(struct drm_device *dev,
struct drm_mode_object *object);
diff --git a/drivers/gpu/drm/drm_encoder.c b/drivers/gpu/drm/drm_encoder.c
index 0708779840d2..43f644844b83 100644
--- a/drivers/gpu/drm/drm_encoder.c
+++ b/drivers/gpu/drm/drm_encoder.c
@@ -220,7 +220,7 @@ int drm_mode_getencoder(struct drm_device *dev, void *data,
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
- encoder = drm_encoder_find(dev, enc_resp->encoder_id);
+ encoder = drm_encoder_find(dev, file_priv, enc_resp->encoder_id);
if (!encoder)
return -ENOENT;
diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c
index af279844d7ce..2affe53f3fda 100644
--- a/drivers/gpu/drm/drm_framebuffer.c
+++ b/drivers/gpu/drm/drm_framebuffer.c
@@ -381,7 +381,7 @@ int drm_mode_rmfb(struct drm_device *dev,
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
- fb = drm_framebuffer_lookup(dev, *id);
+ fb = drm_framebuffer_lookup(dev, file_priv, *id);
if (!fb)
return -ENOENT;
@@ -450,7 +450,7 @@ int drm_mode_getfb(struct drm_device *dev,
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
- fb = drm_framebuffer_lookup(dev, r->fb_id);
+ fb = drm_framebuffer_lookup(dev, file_priv, r->fb_id);
if (!fb)
return -ENOENT;
@@ -515,7 +515,7 @@ int drm_mode_dirtyfb_ioctl(struct drm_device *dev,
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
- fb = drm_framebuffer_lookup(dev, r->fb_id);
+ fb = drm_framebuffer_lookup(dev, file_priv, r->fb_id);
if (!fb)
return -ENOENT;
@@ -688,12 +688,13 @@ EXPORT_SYMBOL(drm_framebuffer_init);
* again, using drm_framebuffer_put().
*/
struct drm_framebuffer *drm_framebuffer_lookup(struct drm_device *dev,
+ struct drm_file *file_priv,
uint32_t id)
{
struct drm_mode_object *obj;
struct drm_framebuffer *fb = NULL;
- obj = __drm_mode_object_find(dev, id, DRM_MODE_OBJECT_FB);
+ obj = __drm_mode_object_find(dev, file_priv, id, DRM_MODE_OBJECT_FB);
if (obj)
fb = obj_to_fb(obj);
return fb;
diff --git a/drivers/gpu/drm/drm_mode_object.c b/drivers/gpu/drm/drm_mode_object.c
index 7a1ea91d3343..240a05d91a53 100644
--- a/drivers/gpu/drm/drm_mode_object.c
+++ b/drivers/gpu/drm/drm_mode_object.c
@@ -105,6 +105,7 @@ void drm_mode_object_unregister(struct drm_device *dev,
}
struct drm_mode_object *__drm_mode_object_find(struct drm_device *dev,
+ struct drm_file *file_priv,
uint32_t id, uint32_t type)
{
struct drm_mode_object *obj = NULL;
@@ -127,7 +128,7 @@ struct drm_mode_object *__drm_mode_object_find(struct drm_device *dev,
/**
* drm_mode_object_find - look up a drm object with static lifetime
- * @dev: drm device
+ * @file_priv: drm file
* @id: id of the mode object
* @type: type of the mode object
*
@@ -136,11 +137,12 @@ struct drm_mode_object *__drm_mode_object_find(struct drm_device *dev,
* by callind drm_mode_object_put().
*/
struct drm_mode_object *drm_mode_object_find(struct drm_device *dev,
+ struct drm_file *file_priv,
uint32_t id, uint32_t type)
{
struct drm_mode_object *obj = NULL;
- obj = __drm_mode_object_find(dev, id, type);
+ obj = __drm_mode_object_find(dev, file_priv, id, type);
return obj;
}
EXPORT_SYMBOL(drm_mode_object_find);
@@ -359,7 +361,7 @@ int drm_mode_obj_get_properties_ioctl(struct drm_device *dev, void *data,
drm_modeset_lock_all(dev);
- obj = drm_mode_object_find(dev, arg->obj_id, arg->obj_type);
+ obj = drm_mode_object_find(dev, file_priv, arg->obj_id, arg->obj_type);
if (!obj) {
ret = -ENOENT;
goto out;
@@ -481,7 +483,7 @@ int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
- arg_obj = drm_mode_object_find(dev, arg->obj_id, arg->obj_type);
+ arg_obj = drm_mode_object_find(dev, file_priv, arg->obj_id, arg->obj_type);
if (!arg_obj)
return -ENOENT;
diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c
index 192071209baa..574fd1475214 100644
--- a/drivers/gpu/drm/drm_plane.c
+++ b/drivers/gpu/drm/drm_plane.c
@@ -513,7 +513,7 @@ int drm_mode_getplane(struct drm_device *dev, void *data,
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
- plane = drm_plane_find(dev, plane_resp->plane_id);
+ plane = drm_plane_find(dev, file_priv, plane_resp->plane_id);
if (!plane)
return -ENOENT;
@@ -703,7 +703,7 @@ int drm_mode_setplane(struct drm_device *dev, void *data,
* First, find the plane, crtc, and fb objects. If not available,
* we don't bother to call the driver.
*/
- plane = drm_plane_find(dev, plane_req->plane_id);
+ plane = drm_plane_find(dev, file_priv, plane_req->plane_id);
if (!plane) {
DRM_DEBUG_KMS("Unknown plane ID %d\n",
plane_req->plane_id);
@@ -711,14 +711,14 @@ int drm_mode_setplane(struct drm_device *dev, void *data,
}
if (plane_req->fb_id) {
- fb = drm_framebuffer_lookup(dev, plane_req->fb_id);
+ fb = drm_framebuffer_lookup(dev, file_priv, plane_req->fb_id);
if (!fb) {
DRM_DEBUG_KMS("Unknown framebuffer ID %d\n",
plane_req->fb_id);
return -ENOENT;
}
- crtc = drm_crtc_find(dev, plane_req->crtc_id);
+ crtc = drm_crtc_find(dev, file_priv, plane_req->crtc_id);
if (!crtc) {
drm_framebuffer_put(fb);
DRM_DEBUG_KMS("Unknown crtc ID %d\n",
@@ -829,7 +829,7 @@ static int drm_mode_cursor_common(struct drm_device *dev,
if (!req->flags || (~DRM_MODE_CURSOR_FLAGS & req->flags))
return -EINVAL;
- crtc = drm_crtc_find(dev, req->crtc_id);
+ crtc = drm_crtc_find(dev, file_priv, req->crtc_id);
if (!crtc) {
DRM_DEBUG_KMS("Unknown CRTC ID %d\n", req->crtc_id);
return -ENOENT;
@@ -944,7 +944,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
if ((page_flip->flags & DRM_MODE_PAGE_FLIP_ASYNC) && !dev->mode_config.async_page_flip)
return -EINVAL;
- crtc = drm_crtc_find(dev, page_flip->crtc_id);
+ crtc = drm_crtc_find(dev, file_priv, page_flip->crtc_id);
if (!crtc)
return -ENOENT;
@@ -1005,7 +1005,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
goto out;
}
- fb = drm_framebuffer_lookup(dev, page_flip->fb_id);
+ fb = drm_framebuffer_lookup(dev, file_priv, page_flip->fb_id);
if (!fb) {
ret = -ENOENT;
goto out;
diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c
index 5840aabbf24e..6dc2dde5b672 100644
--- a/drivers/gpu/drm/drm_probe_helper.c
+++ b/drivers/gpu/drm/drm_probe_helper.c
@@ -99,7 +99,7 @@ drm_mode_validate_pipeline(struct drm_display_mode *mode,
/* Step 2: Validate against encoders and crtcs */
for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
- struct drm_encoder *encoder = drm_encoder_find(dev, ids[i]);
+ struct drm_encoder *encoder = drm_encoder_find(dev, NULL, ids[i]);
struct drm_crtc *crtc;
if (!encoder)
diff --git a/drivers/gpu/drm/drm_property.c b/drivers/gpu/drm/drm_property.c
index bc5128203056..bae50e6b819d 100644
--- a/drivers/gpu/drm/drm_property.c
+++ b/drivers/gpu/drm/drm_property.c
@@ -450,7 +450,7 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev,
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
- property = drm_property_find(dev, out_resp->prop_id);
+ property = drm_property_find(dev, file_priv, out_resp->prop_id);
if (!property)
return -ENOENT;
@@ -634,7 +634,7 @@ struct drm_property_blob *drm_property_lookup_blob(struct drm_device *dev,
struct drm_mode_object *obj;
struct drm_property_blob *blob = NULL;
- obj = __drm_mode_object_find(dev, id, DRM_MODE_OBJECT_BLOB);
+ obj = __drm_mode_object_find(dev, NULL, id, DRM_MODE_OBJECT_BLOB);
if (obj)
blob = obj_to_blob(obj);
return blob;
@@ -897,7 +897,7 @@ bool drm_property_change_valid_get(struct drm_property *property,
if (value == 0)
return true;
- *ref = __drm_mode_object_find(property->dev, value,
+ *ref = __drm_mode_object_find(property->dev, NULL, value,
property->values[0]);
return *ref != NULL;
}
diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
index ec4dd9df9150..f4eba87c96f3 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
@@ -36,7 +36,7 @@ static int hibmc_connector_mode_valid(struct drm_connector *connector,
static struct drm_encoder *
hibmc_connector_best_encoder(struct drm_connector *connector)
{
- return drm_encoder_find(connector->dev, connector->encoder_ids[0]);
+ return drm_encoder_find(connector->dev, NULL, connector->encoder_ids[0]);
}
static const struct drm_connector_helper_funcs
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index f780f39e0758..0bec6deaae4f 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -13511,7 +13511,7 @@ int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
struct drm_crtc *drmmode_crtc;
struct intel_crtc *crtc;
- drmmode_crtc = drm_crtc_find(dev, pipe_from_crtc_id->crtc_id);
+ drmmode_crtc = drm_crtc_find(dev, file, pipe_from_crtc_id->crtc_id);
if (!drmmode_crtc)
return -ENOENT;
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c
index aace22e7ccac..1b397b41cb4f 100644
--- a/drivers/gpu/drm/i915/intel_overlay.c
+++ b/drivers/gpu/drm/i915/intel_overlay.c
@@ -1134,7 +1134,7 @@ int intel_overlay_put_image_ioctl(struct drm_device *dev, void *data,
if (!params)
return -ENOMEM;
- drmmode_crtc = drm_crtc_find(dev, put_image_rec->crtc_id);
+ drmmode_crtc = drm_crtc_find(dev, file_priv, put_image_rec->crtc_id);
if (!drmmode_crtc) {
ret = -ENOENT;
goto out_free;
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index b0d6e3e28d07..28a1209d87e2 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -994,7 +994,7 @@ int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
set->flags & I915_SET_COLORKEY_DESTINATION)
return -EINVAL;
- plane = drm_plane_find(dev, set->plane_id);
+ plane = drm_plane_find(dev, file_priv, set->plane_id);
if (!plane || plane->type != DRM_PLANE_TYPE_OVERLAY)
return -ENOENT;
diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c
index 5e9cd4c0e8b6..68e5d9c94475 100644
--- a/drivers/gpu/drm/mgag200/mgag200_mode.c
+++ b/drivers/gpu/drm/mgag200/mgag200_mode.c
@@ -1670,7 +1670,7 @@ static struct drm_encoder *mga_connector_best_encoder(struct drm_connector
int enc_id = connector->encoder_ids[0];
/* pick the encoder ids */
if (enc_id)
- return drm_encoder_find(connector->dev, enc_id);
+ return drm_encoder_find(connector->dev, NULL, enc_id);
return NULL;
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c
index 70d8e0d69ad5..69d6e61a01ec 100644
--- a/drivers/gpu/drm/nouveau/nouveau_connector.c
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
@@ -373,7 +373,7 @@ find_encoder(struct drm_connector *connector, int type)
if (!id)
break;
- enc = drm_encoder_find(dev, id);
+ enc = drm_encoder_find(dev, NULL, id);
if (!enc)
continue;
nv_encoder = nouveau_encoder(enc);
@@ -441,7 +441,7 @@ nouveau_connector_ddc_detect(struct drm_connector *connector)
if (id == 0)
break;
- encoder = drm_encoder_find(dev, id);
+ encoder = drm_encoder_find(dev, NULL, id);
if (!encoder)
continue;
nv_encoder = nouveau_encoder(encoder);
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index c31e660e35db..7d39ed63e5be 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -1456,7 +1456,7 @@ int r100_cs_packet_parse_vline(struct radeon_cs_parser *p)
header = radeon_get_ib_value(p, h_idx);
crtc_id = radeon_get_ib_value(p, h_idx + 5);
reg = R100_CP_PACKET0_GET_REG(header);
- crtc = drm_crtc_find(p->rdev->ddev, crtc_id);
+ crtc = drm_crtc_find(p->rdev->ddev, p->filp, crtc_id);
if (!crtc) {
DRM_ERROR("cannot find crtc %d\n", crtc_id);
return -ENOENT;
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c
index 97fd58e97043..c96b31950ca7 100644
--- a/drivers/gpu/drm/radeon/r600_cs.c
+++ b/drivers/gpu/drm/radeon/r600_cs.c
@@ -887,7 +887,7 @@ int r600_cs_common_vline_parse(struct radeon_cs_parser *p,
crtc_id = radeon_get_ib_value(p, h_idx + 2 + 7 + 1);
reg = R600_CP_PACKET0_GET_REG(header);
- crtc = drm_crtc_find(p->rdev->ddev, crtc_id);
+ crtc = drm_crtc_find(p->rdev->ddev, p->filp, crtc_id);
if (!crtc) {
DRM_ERROR("cannot find crtc %d\n", crtc_id);
return -ENOENT;
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
index 2f642cbefd8e..59dcefb2df3b 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -263,7 +263,7 @@ radeon_connector_update_scratch_regs(struct drm_connector *connector, enum drm_c
if (connector->encoder_ids[i] == 0)
break;
- encoder = drm_encoder_find(connector->dev,
+ encoder = drm_encoder_find(connector->dev, NULL,
connector->encoder_ids[i]);
if (!encoder)
continue;
@@ -290,7 +290,7 @@ static struct drm_encoder *radeon_find_encoder(struct drm_connector *connector,
if (connector->encoder_ids[i] == 0)
break;
- encoder = drm_encoder_find(connector->dev, connector->encoder_ids[i]);
+ encoder = drm_encoder_find(connector->dev, NULL, connector->encoder_ids[i]);
if (!encoder)
continue;
@@ -404,7 +404,7 @@ static struct drm_encoder *radeon_best_single_encoder(struct drm_connector *conn
int enc_id = connector->encoder_ids[0];
/* pick the encoder ids */
if (enc_id)
- return drm_encoder_find(connector->dev, enc_id);
+ return drm_encoder_find(connector->dev, NULL, enc_id);
return NULL;
}
@@ -1368,7 +1368,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)
if (connector->encoder_ids[i] == 0)
break;
- encoder = drm_encoder_find(connector->dev,
+ encoder = drm_encoder_find(connector->dev, NULL,
connector->encoder_ids[i]);
if (!encoder)
continue;
@@ -1454,7 +1454,7 @@ static struct drm_encoder *radeon_dvi_encoder(struct drm_connector *connector)
if (connector->encoder_ids[i] == 0)
break;
- encoder = drm_encoder_find(connector->dev, connector->encoder_ids[i]);
+ encoder = drm_encoder_find(connector->dev, NULL, connector->encoder_ids[i]);
if (!encoder)
continue;
@@ -1473,7 +1473,7 @@ static struct drm_encoder *radeon_dvi_encoder(struct drm_connector *connector)
/* then check use digitial */
/* pick the first one */
if (enc_id)
- return drm_encoder_find(connector->dev, enc_id);
+ return drm_encoder_find(connector->dev, NULL, enc_id);
return NULL;
}
@@ -1620,7 +1620,7 @@ u16 radeon_connector_encoder_get_dp_bridge_encoder_id(struct drm_connector *conn
if (connector->encoder_ids[i] == 0)
break;
- encoder = drm_encoder_find(connector->dev, connector->encoder_ids[i]);
+ encoder = drm_encoder_find(connector->dev, NULL, connector->encoder_ids[i]);
if (!encoder)
continue;
@@ -1649,7 +1649,7 @@ static bool radeon_connector_encoder_is_hbr2(struct drm_connector *connector)
if (connector->encoder_ids[i] == 0)
break;
- encoder = drm_encoder_find(connector->dev, connector->encoder_ids[i]);
+ encoder = drm_encoder_find(connector->dev, NULL, connector->encoder_ids[i]);
if (!encoder)
continue;
diff --git a/drivers/gpu/drm/udl/udl_connector.c b/drivers/gpu/drm/udl/udl_connector.c
index 9f9a49748d17..091ca81658eb 100644
--- a/drivers/gpu/drm/udl/udl_connector.c
+++ b/drivers/gpu/drm/udl/udl_connector.c
@@ -105,7 +105,7 @@ static struct drm_encoder*
udl_best_single_encoder(struct drm_connector *connector)
{
int enc_id = connector->encoder_ids[0];
- return drm_encoder_find(connector->dev, enc_id);
+ return drm_encoder_find(connector->dev, NULL, enc_id);
}
static int udl_connector_set_property(struct drm_connector *connector,
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
index 5ec24fd801cd..01be355525e4 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
@@ -286,7 +286,7 @@ int vmw_present_ioctl(struct drm_device *dev, void *data,
drm_modeset_lock_all(dev);
- fb = drm_framebuffer_lookup(dev, arg->fb_id);
+ fb = drm_framebuffer_lookup(dev, file_priv, arg->fb_id);
if (!fb) {
DRM_ERROR("Invalid framebuffer id.\n");
ret = -ENOENT;
@@ -369,7 +369,7 @@ int vmw_present_readback_ioctl(struct drm_device *dev, void *data,
drm_modeset_lock_all(dev);
- fb = drm_framebuffer_lookup(dev, arg->fb_id);
+ fb = drm_framebuffer_lookup(dev, file_priv, arg->fb_id);
if (!fb) {
DRM_ERROR("Invalid framebuffer id.\n");
ret = -ENOENT;
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index b850562fbdd6..0545740b3724 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -1726,7 +1726,7 @@ int vmw_kms_cursor_bypass_ioctl(struct drm_device *dev, void *data,
return 0;
}
- crtc = drm_crtc_find(dev, arg->crtc_id);
+ crtc = drm_crtc_find(dev, file_priv, arg->crtc_id);
if (!crtc) {
ret = -ENOENT;
goto out;
diff --git a/drivers/staging/vboxvideo/vbox_mode.c b/drivers/staging/vboxvideo/vbox_mode.c
index 257a77830410..c745a0402c68 100644
--- a/drivers/staging/vboxvideo/vbox_mode.c
+++ b/drivers/staging/vboxvideo/vbox_mode.c
@@ -377,7 +377,7 @@ static struct drm_encoder *vbox_best_single_encoder(struct drm_connector
/* pick the encoder ids */
if (enc_id)
- return drm_encoder_find(connector->dev, enc_id);
+ return drm_encoder_find(connector->dev, NULL, enc_id);
return NULL;
}
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index b34904dc8b9b..b4285c40e1e4 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -939,10 +939,11 @@ static inline unsigned drm_connector_index(struct drm_connector *connector)
* add takes a reference to it.
*/
static inline struct drm_connector *drm_connector_lookup(struct drm_device *dev,
+ struct drm_file *file_priv,
uint32_t id)
{
struct drm_mode_object *mo;
- mo = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_CONNECTOR);
+ mo = drm_mode_object_find(dev, file_priv, id, DRM_MODE_OBJECT_CONNECTOR);
return mo ? obj_to_connector(mo) : NULL;
}
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 80c97210eda5..f7fcceef46d9 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -959,10 +959,11 @@ struct drm_crtc *drm_crtc_from_index(struct drm_device *dev, int idx);
* userspace interface should be done using &drm_property.
*/
static inline struct drm_crtc *drm_crtc_find(struct drm_device *dev,
- uint32_t id)
+ struct drm_file *file_priv,
+ uint32_t id)
{
struct drm_mode_object *mo;
- mo = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_CRTC);
+ mo = drm_mode_object_find(dev, file_priv, id, DRM_MODE_OBJECT_CRTC);
return mo ? obj_to_crtc(mo) : NULL;
}
diff --git a/include/drm/drm_encoder.h b/include/drm/drm_encoder.h
index 8d8245ec0181..86db0da8bdcb 100644
--- a/include/drm/drm_encoder.h
+++ b/include/drm/drm_encoder.h
@@ -214,11 +214,12 @@ static inline bool drm_encoder_crtc_ok(struct drm_encoder *encoder,
* drm_mode_object_find().
*/
static inline struct drm_encoder *drm_encoder_find(struct drm_device *dev,
+ struct drm_file *file_priv,
uint32_t id)
{
struct drm_mode_object *mo;
- mo = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_ENCODER);
+ mo = drm_mode_object_find(dev, file_priv, id, DRM_MODE_OBJECT_ENCODER);
return mo ? obj_to_encoder(mo) : NULL;
}
diff --git a/include/drm/drm_framebuffer.h b/include/drm/drm_framebuffer.h
index b6996ddb19d6..4c5ee4ae54df 100644
--- a/include/drm/drm_framebuffer.h
+++ b/include/drm/drm_framebuffer.h
@@ -205,6 +205,7 @@ int drm_framebuffer_init(struct drm_device *dev,
struct drm_framebuffer *fb,
const struct drm_framebuffer_funcs *funcs);
struct drm_framebuffer *drm_framebuffer_lookup(struct drm_device *dev,
+ struct drm_file *file_priv,
uint32_t id);
void drm_framebuffer_remove(struct drm_framebuffer *fb);
void drm_framebuffer_cleanup(struct drm_framebuffer *fb);
diff --git a/include/drm/drm_mode_object.h b/include/drm/drm_mode_object.h
index a767b4a30a6d..b2f920b518e3 100644
--- a/include/drm/drm_mode_object.h
+++ b/include/drm/drm_mode_object.h
@@ -27,6 +27,7 @@
struct drm_object_properties;
struct drm_property;
struct drm_device;
+struct drm_file;
/**
* struct drm_mode_object - base structure for modeset objects
@@ -113,6 +114,7 @@ struct drm_object_properties {
}
struct drm_mode_object *drm_mode_object_find(struct drm_device *dev,
+ struct drm_file *file_priv,
uint32_t id, uint32_t type);
void drm_mode_object_get(struct drm_mode_object *obj);
void drm_mode_object_put(struct drm_mode_object *obj);
diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h
index 82a217bd77f0..069c4c8ce360 100644
--- a/include/drm/drm_plane.h
+++ b/include/drm/drm_plane.h
@@ -597,10 +597,11 @@ int drm_mode_plane_set_obj_prop(struct drm_plane *plane,
* drm_mode_object_find().
*/
static inline struct drm_plane *drm_plane_find(struct drm_device *dev,
+ struct drm_file *file_priv,
uint32_t id)
{
struct drm_mode_object *mo;
- mo = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_PLANE);
+ mo = drm_mode_object_find(dev, file_priv, id, DRM_MODE_OBJECT_PLANE);
return mo ? obj_to_plane(mo) : NULL;
}
diff --git a/include/drm/drm_property.h b/include/drm/drm_property.h
index 37355c623e6c..429d8218f740 100644
--- a/include/drm/drm_property.h
+++ b/include/drm/drm_property.h
@@ -312,10 +312,11 @@ drm_property_unreference_blob(struct drm_property_blob *blob)
* This function looks up the property object specified by id and returns it.
*/
static inline struct drm_property *drm_property_find(struct drm_device *dev,
+ struct drm_file *file_priv,
uint32_t id)
{
struct drm_mode_object *mo;
- mo = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_PROPERTY);
+ mo = drm_mode_object_find(dev, file_priv, id, DRM_MODE_OBJECT_PROPERTY);
return mo ? obj_to_property(mo) : NULL;
}
--
2.13.3
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 2/6] drm: Allow render nodes to query display objects
2017-10-11 0:48 ` Keith Packard
(?)
(?)
@ 2017-10-11 0:48 ` Keith Packard
2017-10-12 18:41 ` Daniel Vetter
-1 siblings, 1 reply; 21+ messages in thread
From: Keith Packard @ 2017-10-11 0:48 UTC (permalink / raw)
To: linux-kernel, Dave Airlie, Daniel Vetter; +Cc: Keith Packard, dri-devel
This allows an application to discover what display resources are
available before requesting a lease from the X server.
Signed-off-by: Keith Packard <keithp@keithp.com>
---
drivers/gpu/drm/drm_ioctl.c | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index 25559aa4c65b..78a0d6996e12 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -613,27 +613,27 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
DRM_IOCTL_DEF(DRM_IOCTL_GEM_FLINK, drm_gem_flink_ioctl, DRM_AUTH|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, DRM_AUTH|DRM_UNLOCKED),
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_RENDER_ALLOW|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_PRIME_HANDLE_TO_FD, drm_prime_handle_to_fd_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW),
DRM_IOCTL_DEF(DRM_IOCTL_PRIME_FD_TO_HANDLE, drm_prime_fd_to_handle_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW),
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANERESOURCES, drm_mode_getplane_res, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANERESOURCES, drm_mode_getplane_res, DRM_RENDER_ALLOW|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_RENDER_ALLOW|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETCRTC, drm_mode_setcrtc, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANE, drm_mode_getplane, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANE, drm_mode_getplane, DRM_RENDER_ALLOW|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPLANE, drm_mode_setplane, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR, drm_mode_cursor_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETGAMMA, drm_mode_gamma_get_ioctl, DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETGAMMA, drm_mode_gamma_set_ioctl, DRM_MASTER|DRM_UNLOCKED),
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETENCODER, drm_mode_getencoder, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCONNECTOR, drm_mode_getconnector, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETENCODER, drm_mode_getencoder, DRM_RENDER_ALLOW|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCONNECTOR, drm_mode_getconnector, DRM_RENDER_ALLOW|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATTACHMODE, drm_noop, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_DETACHMODE, drm_noop, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPERTY, drm_mode_getproperty_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPERTY, drm_mode_getproperty_ioctl, DRM_RENDER_ALLOW|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPROPERTY, drm_mode_connector_property_set_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPBLOB, drm_mode_getblob_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPBLOB, drm_mode_getblob_ioctl, DRM_RENDER_ALLOW|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_RENDER_ALLOW|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB2, drm_mode_addfb2, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
@@ -642,7 +642,7 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
DRM_IOCTL_DEF(DRM_IOCTL_MODE_CREATE_DUMB, drm_mode_create_dumb_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_MAP_DUMB, drm_mode_mmap_dumb_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_DESTROY_DUMB, drm_mode_destroy_dumb_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_OBJ_GETPROPERTIES, drm_mode_obj_get_properties_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_OBJ_GETPROPERTIES, drm_mode_obj_get_properties_ioctl, DRM_RENDER_ALLOW|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_OBJ_SETPROPERTY, drm_mode_obj_set_property_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR2, drm_mode_cursor2_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATOMIC, drm_mode_atomic_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
--
2.13.3
^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH 2/6] drm: Allow render nodes to query display objects
2017-10-11 0:48 ` [PATCH 2/6] drm: Allow render nodes to query display objects Keith Packard
@ 2017-10-12 18:41 ` Daniel Vetter
2017-10-12 19:45 ` Daniel Vetter
2017-10-12 21:02 ` Keith Packard
0 siblings, 2 replies; 21+ messages in thread
From: Daniel Vetter @ 2017-10-12 18:41 UTC (permalink / raw)
To: Keith Packard; +Cc: linux-kernel, Dave Airlie, Daniel Vetter, dri-devel
Hi Keith,
On Tue, Oct 10, 2017 at 05:48:27PM -0700, Keith Packard wrote:
> This allows an application to discover what display resources are
> available before requesting a lease from the X server.
>
> Signed-off-by: Keith Packard <keithp@keithp.com>
For reasons I've kidna stopped reviewing these patches. I don't really
agree with the details of the lease uapi as implemented. But that's
nothing that can't be fixed with a few flags, and leases always need an
explicit opt-in from the compositor now, so still possible to do
reasonable architecture on top in the future. Worst case we fake just the
parts that X needs from this version of leases, we've done that kind of
stuff in the past.
This here otoh is an uapi change that we can't ever undo or contain,
because as soon as we allow anyone to read kms state they will do so. And
do so in lots of very interesting and abusive ways. E.g. there's already
apps who try to second-guess the vblank timings with the vblank ioctl
(which accidentally works everywhere, not just on the master), and ofc get
it wrong, except for the case the developer tested on. Or without
uevent/udev events you can't do efficient output probing, which means
we'll see endless amounts of polling (we had to stop giving accurate data
in the sysfs interface already, for exactly this reasons, because someone
thought polling outputs once per second was a smart idea).
So given the huge possibilities of abuse, do we really, really need all
this, and is there not any way to create a bit of protocol to pass the
relevant data from X to clients? From your presentation is sounded like
current xrandr is (almost) there ...
Thanks, Daniel
> ---
> drivers/gpu/drm/drm_ioctl.c | 20 ++++++++++----------
> 1 file changed, 10 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
> index 25559aa4c65b..78a0d6996e12 100644
> --- a/drivers/gpu/drm/drm_ioctl.c
> +++ b/drivers/gpu/drm/drm_ioctl.c
> @@ -613,27 +613,27 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
> DRM_IOCTL_DEF(DRM_IOCTL_GEM_FLINK, drm_gem_flink_ioctl, DRM_AUTH|DRM_UNLOCKED),
> DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, DRM_AUTH|DRM_UNLOCKED),
>
> - DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
> + DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_RENDER_ALLOW|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
>
> DRM_IOCTL_DEF(DRM_IOCTL_PRIME_HANDLE_TO_FD, drm_prime_handle_to_fd_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW),
> DRM_IOCTL_DEF(DRM_IOCTL_PRIME_FD_TO_HANDLE, drm_prime_fd_to_handle_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW),
>
> - DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANERESOURCES, drm_mode_getplane_res, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
> - DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
> + DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANERESOURCES, drm_mode_getplane_res, DRM_RENDER_ALLOW|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
> + DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_RENDER_ALLOW|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
> DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETCRTC, drm_mode_setcrtc, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
> - DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANE, drm_mode_getplane, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
> + DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANE, drm_mode_getplane, DRM_RENDER_ALLOW|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
> DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPLANE, drm_mode_setplane, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
> DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR, drm_mode_cursor_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
> DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETGAMMA, drm_mode_gamma_get_ioctl, DRM_UNLOCKED),
> DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETGAMMA, drm_mode_gamma_set_ioctl, DRM_MASTER|DRM_UNLOCKED),
> - DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETENCODER, drm_mode_getencoder, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
> - DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCONNECTOR, drm_mode_getconnector, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
> + DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETENCODER, drm_mode_getencoder, DRM_RENDER_ALLOW|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
> + DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCONNECTOR, drm_mode_getconnector, DRM_RENDER_ALLOW|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
> DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATTACHMODE, drm_noop, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
> DRM_IOCTL_DEF(DRM_IOCTL_MODE_DETACHMODE, drm_noop, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
> - DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPERTY, drm_mode_getproperty_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
> + DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPERTY, drm_mode_getproperty_ioctl, DRM_RENDER_ALLOW|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
> DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPROPERTY, drm_mode_connector_property_set_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
> - DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPBLOB, drm_mode_getblob_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
> - DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
> + DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPBLOB, drm_mode_getblob_ioctl, DRM_RENDER_ALLOW|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
> + DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_RENDER_ALLOW|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
> DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
> DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB2, drm_mode_addfb2, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
> DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
> @@ -642,7 +642,7 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
> DRM_IOCTL_DEF(DRM_IOCTL_MODE_CREATE_DUMB, drm_mode_create_dumb_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
> DRM_IOCTL_DEF(DRM_IOCTL_MODE_MAP_DUMB, drm_mode_mmap_dumb_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
> DRM_IOCTL_DEF(DRM_IOCTL_MODE_DESTROY_DUMB, drm_mode_destroy_dumb_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
> - DRM_IOCTL_DEF(DRM_IOCTL_MODE_OBJ_GETPROPERTIES, drm_mode_obj_get_properties_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
> + DRM_IOCTL_DEF(DRM_IOCTL_MODE_OBJ_GETPROPERTIES, drm_mode_obj_get_properties_ioctl, DRM_RENDER_ALLOW|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
> DRM_IOCTL_DEF(DRM_IOCTL_MODE_OBJ_SETPROPERTY, drm_mode_obj_set_property_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
> DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR2, drm_mode_cursor2_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
> DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATOMIC, drm_mode_atomic_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
> --
> 2.13.3
>
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 2/6] drm: Allow render nodes to query display objects
2017-10-12 18:41 ` Daniel Vetter
@ 2017-10-12 19:45 ` Daniel Vetter
2017-10-12 21:02 ` Keith Packard
1 sibling, 0 replies; 21+ messages in thread
From: Daniel Vetter @ 2017-10-12 19:45 UTC (permalink / raw)
To: Keith Packard, linux-kernel, Dave Airlie, dri-devel
On Thu, Oct 12, 2017 at 08:41:17PM +0200, Daniel Vetter wrote:
> Hi Keith,
>
> On Tue, Oct 10, 2017 at 05:48:27PM -0700, Keith Packard wrote:
> > This allows an application to discover what display resources are
> > available before requesting a lease from the X server.
> >
> > Signed-off-by: Keith Packard <keithp@keithp.com>
>
> For reasons I've kidna stopped reviewing these patches. I don't really
> agree with the details of the lease uapi as implemented. But that's
> nothing that can't be fixed with a few flags, and leases always need an
> explicit opt-in from the compositor now, so still possible to do
> reasonable architecture on top in the future. Worst case we fake just the
> parts that X needs from this version of leases, we've done that kind of
> stuff in the past.
>
> This here otoh is an uapi change that we can't ever undo or contain,
> because as soon as we allow anyone to read kms state they will do so. And
> do so in lots of very interesting and abusive ways. E.g. there's already
> apps who try to second-guess the vblank timings with the vblank ioctl
> (which accidentally works everywhere, not just on the master), and ofc get
> it wrong, except for the case the developer tested on. Or without
> uevent/udev events you can't do efficient output probing, which means
> we'll see endless amounts of polling (we had to stop giving accurate data
> in the sysfs interface already, for exactly this reasons, because someone
> thought polling outputs once per second was a smart idea).
>
> So given the huge possibilities of abuse, do we really, really need all
> this, and is there not any way to create a bit of protocol to pass the
> relevant data from X to clients? From your presentation is sounded like
> current xrandr is (almost) there ...
One more that came up on irc after discussion why this is needed: The
userspace side using this won't work on split gpus where the render node
has 0 displays, and hence where you really need to query the compositor
anyway.
Like I predicted, we expose this, everyone will abuse it in slightly
broken ways :-)
-Daniel
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 2/6] drm: Allow render nodes to query display objects
@ 2017-10-12 19:45 ` Daniel Vetter
0 siblings, 0 replies; 21+ messages in thread
From: Daniel Vetter @ 2017-10-12 19:45 UTC (permalink / raw)
To: Keith Packard, linux-kernel, Dave Airlie, dri-devel
On Thu, Oct 12, 2017 at 08:41:17PM +0200, Daniel Vetter wrote:
> Hi Keith,
>
> On Tue, Oct 10, 2017 at 05:48:27PM -0700, Keith Packard wrote:
> > This allows an application to discover what display resources are
> > available before requesting a lease from the X server.
> >
> > Signed-off-by: Keith Packard <keithp@keithp.com>
>
> For reasons I've kidna stopped reviewing these patches. I don't really
> agree with the details of the lease uapi as implemented. But that's
> nothing that can't be fixed with a few flags, and leases always need an
> explicit opt-in from the compositor now, so still possible to do
> reasonable architecture on top in the future. Worst case we fake just the
> parts that X needs from this version of leases, we've done that kind of
> stuff in the past.
>
> This here otoh is an uapi change that we can't ever undo or contain,
> because as soon as we allow anyone to read kms state they will do so. And
> do so in lots of very interesting and abusive ways. E.g. there's already
> apps who try to second-guess the vblank timings with the vblank ioctl
> (which accidentally works everywhere, not just on the master), and ofc get
> it wrong, except for the case the developer tested on. Or without
> uevent/udev events you can't do efficient output probing, which means
> we'll see endless amounts of polling (we had to stop giving accurate data
> in the sysfs interface already, for exactly this reasons, because someone
> thought polling outputs once per second was a smart idea).
>
> So given the huge possibilities of abuse, do we really, really need all
> this, and is there not any way to create a bit of protocol to pass the
> relevant data from X to clients? From your presentation is sounded like
> current xrandr is (almost) there ...
One more that came up on irc after discussion why this is needed: The
userspace side using this won't work on split gpus where the render node
has 0 displays, and hence where you really need to query the compositor
anyway.
Like I predicted, we expose this, everyone will abuse it in slightly
broken ways :-)
-Daniel
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 2/6] drm: Allow render nodes to query display objects
2017-10-12 19:45 ` Daniel Vetter
(?)
@ 2017-10-12 21:04 ` Keith Packard
-1 siblings, 0 replies; 21+ messages in thread
From: Keith Packard @ 2017-10-12 21:04 UTC (permalink / raw)
To: Daniel Vetter, linux-kernel, Dave Airlie, dri-devel
[-- Attachment #1: Type: text/plain, Size: 706 bytes --]
Daniel Vetter <daniel@ffwll.ch> writes:
> One more that came up on irc after discussion why this is needed: The
> userspace side using this won't work on split gpus where the render node
> has 0 displays, and hence where you really need to query the compositor
> anyway.
Agreed -- using the X connection to get the information should let this
work on split systems. Within the Vulkan code, I already have to move
objects from the render node to the display node. Hrm. That exposes a
weakness in the kms_display extension I've proposed; that only allows
you to pass a single fd. Passing separate display and render fds through
that interface seems like a pretty useful change.
--
-keith
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 2/6] drm: Allow render nodes to query display objects
2017-10-12 18:41 ` Daniel Vetter
@ 2017-10-12 21:02 ` Keith Packard
2017-10-12 21:02 ` Keith Packard
1 sibling, 0 replies; 21+ messages in thread
From: Keith Packard @ 2017-10-12 21:02 UTC (permalink / raw)
To: Daniel Vetter; +Cc: linux-kernel, Dave Airlie, Daniel Vetter, dri-devel
[-- Attachment #1: Type: text/plain, Size: 793 bytes --]
Daniel Vetter <daniel@ffwll.ch> writes:
> So given the huge possibilities of abuse, do we really, really need all
> this, and is there not any way to create a bit of protocol to pass the
> relevant data from X to clients? From your presentation is sounded like
> current xrandr is (almost) there ...
Yeah, it's the Vulkan EXT_acquire_xlib_display API which is using this
access to discover the set of resources available via the render fd in
preparation for accessing them over the lease fd once the lease has been
created.
I *think* I can get enough information to make a good guess as to what
kernel resources there are from the RandR info. I'll go give that a try
and see if I get stuck.
Thanks for the feedback; the fewer kernel API changes the better.
--
-keith
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 2/6] drm: Allow render nodes to query display objects
@ 2017-10-12 21:02 ` Keith Packard
0 siblings, 0 replies; 21+ messages in thread
From: Keith Packard @ 2017-10-12 21:02 UTC (permalink / raw)
Cc: linux-kernel, Dave Airlie, Daniel Vetter, dri-devel
[-- Attachment #1: Type: text/plain, Size: 793 bytes --]
Daniel Vetter <daniel@ffwll.ch> writes:
> So given the huge possibilities of abuse, do we really, really need all
> this, and is there not any way to create a bit of protocol to pass the
> relevant data from X to clients? From your presentation is sounded like
> current xrandr is (almost) there ...
Yeah, it's the Vulkan EXT_acquire_xlib_display API which is using this
access to discover the set of resources available via the render fd in
preparation for accessing them over the lease fd once the lease has been
created.
I *think* I can get enough information to make a good guess as to what
kernel resources there are from the RandR info. I'll go give that a try
and see if I get stuck.
Thanks for the feedback; the fewer kernel API changes the better.
--
-keith
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 3/6] drm: Add new LEASE debug level
2017-10-11 0:48 ` Keith Packard
@ 2017-10-11 0:48 ` Keith Packard
-1 siblings, 0 replies; 21+ messages in thread
From: Keith Packard @ 2017-10-11 0:48 UTC (permalink / raw)
To: linux-kernel, Dave Airlie, Daniel Vetter; +Cc: Keith Packard, dri-devel
Separate out lease debugging from the core.
Signed-off-by: Keith Packard <keithp@keithp.com>
---
drivers/gpu/drm/drm_drv.c | 3 ++-
include/drm/drmP.h | 4 ++++
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index c0292e5d7281..a934fd5e7e55 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -57,7 +57,8 @@ MODULE_PARM_DESC(debug, "Enable debug output, where each bit enables a debug cat
"\t\tBit 2 (0x04) will enable KMS messages (modesetting code)\n"
"\t\tBit 3 (0x08) will enable PRIME messages (prime code)\n"
"\t\tBit 4 (0x10) will enable ATOMIC messages (atomic code)\n"
-"\t\tBit 5 (0x20) will enable VBL messages (vblank code)");
+"\t\tBit 5 (0x20) will enable VBL messages (vblank code)\n"
+"\t\tBit 7 (0x80) will enable LEASE messages (leasing code)");
module_param_named(debug, drm_debug, int, 0600);
static DEFINE_SPINLOCK(drm_minor_lock);
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index 7277783a4ff0..59be1232d005 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -136,6 +136,7 @@ struct pci_controller;
#define DRM_UT_ATOMIC 0x10
#define DRM_UT_VBL 0x20
#define DRM_UT_STATE 0x40
+#define DRM_UT_LEASE 0x80
/***********************************************************************/
/** \name DRM template customization defaults */
@@ -250,6 +251,9 @@ struct pci_controller;
#define DRM_DEBUG_VBL(fmt, ...) \
drm_printk(KERN_DEBUG, DRM_UT_VBL, fmt, ##__VA_ARGS__)
+#define DRM_DEBUG_LEASE(fmt, ...) \
+ drm_printk(KERN_DEBUG, DRM_UT_LEASE, fmt, ##__VA_ARGS__)
+
#define _DRM_DEV_DEFINE_DEBUG_RATELIMITED(dev, level, fmt, args...) \
({ \
static DEFINE_RATELIMIT_STATE(_rs, \
--
2.13.3
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 3/6] drm: Add new LEASE debug level
@ 2017-10-11 0:48 ` Keith Packard
0 siblings, 0 replies; 21+ messages in thread
From: Keith Packard @ 2017-10-11 0:48 UTC (permalink / raw)
To: linux-kernel, Dave Airlie, Daniel Vetter; +Cc: Keith Packard, dri-devel
Separate out lease debugging from the core.
Signed-off-by: Keith Packard <keithp@keithp.com>
---
drivers/gpu/drm/drm_drv.c | 3 ++-
include/drm/drmP.h | 4 ++++
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index c0292e5d7281..a934fd5e7e55 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -57,7 +57,8 @@ MODULE_PARM_DESC(debug, "Enable debug output, where each bit enables a debug cat
"\t\tBit 2 (0x04) will enable KMS messages (modesetting code)\n"
"\t\tBit 3 (0x08) will enable PRIME messages (prime code)\n"
"\t\tBit 4 (0x10) will enable ATOMIC messages (atomic code)\n"
-"\t\tBit 5 (0x20) will enable VBL messages (vblank code)");
+"\t\tBit 5 (0x20) will enable VBL messages (vblank code)\n"
+"\t\tBit 7 (0x80) will enable LEASE messages (leasing code)");
module_param_named(debug, drm_debug, int, 0600);
static DEFINE_SPINLOCK(drm_minor_lock);
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index 7277783a4ff0..59be1232d005 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -136,6 +136,7 @@ struct pci_controller;
#define DRM_UT_ATOMIC 0x10
#define DRM_UT_VBL 0x20
#define DRM_UT_STATE 0x40
+#define DRM_UT_LEASE 0x80
/***********************************************************************/
/** \name DRM template customization defaults */
@@ -250,6 +251,9 @@ struct pci_controller;
#define DRM_DEBUG_VBL(fmt, ...) \
drm_printk(KERN_DEBUG, DRM_UT_VBL, fmt, ##__VA_ARGS__)
+#define DRM_DEBUG_LEASE(fmt, ...) \
+ drm_printk(KERN_DEBUG, DRM_UT_LEASE, fmt, ##__VA_ARGS__)
+
#define _DRM_DEV_DEFINE_DEBUG_RATELIMITED(dev, level, fmt, args...) \
({ \
static DEFINE_RATELIMIT_STATE(_rs, \
--
2.13.3
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 4/6] drm: Add drm_object lease infrastructure [v4]
2017-10-11 0:48 ` Keith Packard
@ 2017-10-11 0:48 ` Keith Packard
-1 siblings, 0 replies; 21+ messages in thread
From: Keith Packard @ 2017-10-11 0:48 UTC (permalink / raw)
To: linux-kernel, Dave Airlie, Daniel Vetter; +Cc: Keith Packard, dri-devel
This provides new data structures to hold "lease" information about
drm mode setting objects, and provides for creating new drm_masters
which have access to a subset of the available drm resources.
An 'owner' is a drm_master which is not leasing the objects from
another drm_master, and hence 'owns' them.
A 'lessee' is a drm_master which is leasing objects from some other
drm_master. Each lessee holds the set of objects which it is leasing
from the lessor.
A 'lessor' is a drm_master which is leasing objects to another
drm_master. This is the same as the owner in the current code.
The set of objects any drm_master 'controls' is limited to the set of
objects it leases (for lessees) or all objects (for owners).
Objects not controlled by a drm_master cannot be modified through the
various state manipulating ioctls, and any state reported back to user
space will be edited to make them appear idle and/or unusable. For
instance, connectors always report 'disconnected', while encoders
report no possible crtcs or clones.
The full list of lessees leasing objects from an owner (either
directly, or indirectly through another lessee), can be searched from
an idr in the drm_master of the owner.
Changes for v2 as suggested by Daniel Vetter <daniel.vetter@ffwll.ch>:
* Sub-leasing has been disabled.
* BUG_ON for lock checking replaced with lockdep_assert_held
* 'change' ioctl has been removed.
* Leased objects can always be controlled by the lessor; the
'mask_lease' flag has been removed
* Checking for leased status has been simplified, replacing
the drm_lease_check function with drm_lease_held.
Changes in v3, some suggested by Dave Airlie <airlied@gmail.com>
* Add revocation. This allows leases to be effectively revoked by
removing all of the objects they have access to. The lease itself
hangs around as it's hanging off a file.
* Free the leases IDR when the master is destroyed
* _drm_lease_held should look at lessees, not lessor
* Allow non-master files to check for lease status
Changes in v4, suggested by Dave Airlie <airlied@gmail.com>
* Formatting and whitespace changes
Signed-off-by: Keith Packard <keithp@keithp.com>
---
drivers/gpu/drm/Makefile | 2 +-
drivers/gpu/drm/drm_auth.c | 29 +++-
drivers/gpu/drm/drm_lease.c | 379 ++++++++++++++++++++++++++++++++++++++++++
include/drm/drm_auth.h | 20 +++
include/drm/drm_lease.h | 36 ++++
include/drm/drm_mode_object.h | 1 +
6 files changed, 465 insertions(+), 2 deletions(-)
create mode 100644 drivers/gpu/drm/drm_lease.c
create mode 100644 include/drm/drm_lease.h
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index a3fdc5a68dff..81ff79336623 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -17,7 +17,7 @@ drm-y := drm_auth.o drm_bufs.o drm_cache.o \
drm_encoder.o drm_mode_object.o drm_property.o \
drm_plane.o drm_color_mgmt.o drm_print.o \
drm_dumb_buffers.o drm_mode_config.o drm_vblank.o \
- drm_syncobj.o
+ drm_syncobj.o drm_lease.o
drm-$(CONFIG_DRM_LIB_RANDOM) += lib/drm_random.o
drm-$(CONFIG_DRM_VM) += drm_vm.o
diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c
index 7ff697389d74..541177c71d51 100644
--- a/drivers/gpu/drm/drm_auth.c
+++ b/drivers/gpu/drm/drm_auth.c
@@ -31,6 +31,7 @@
#include <drm/drmP.h>
#include "drm_internal.h"
#include "drm_legacy.h"
+#include <drm/drm_lease.h>
/**
* DOC: master and authentication
@@ -93,7 +94,7 @@ int drm_authmagic(struct drm_device *dev, void *data,
return file ? 0 : -EINVAL;
}
-static struct drm_master *drm_master_create(struct drm_device *dev)
+struct drm_master *drm_master_create(struct drm_device *dev)
{
struct drm_master *master;
@@ -107,6 +108,14 @@ static struct drm_master *drm_master_create(struct drm_device *dev)
idr_init(&master->magic_map);
master->dev = dev;
+ /* initialize the tree of output resource lessees */
+ master->lessor = NULL;
+ master->lessee_id = 0;
+ INIT_LIST_HEAD(&master->lessees);
+ INIT_LIST_HEAD(&master->lessee_list);
+ idr_init(&master->leases);
+ idr_init(&master->lessee_idr);
+
return master;
}
@@ -189,6 +198,12 @@ int drm_setmaster_ioctl(struct drm_device *dev, void *data,
goto out_unlock;
}
+ if (file_priv->master->lessor != NULL) {
+ DRM_DEBUG_LEASE("Attempt to set lessee %d as master\n", file_priv->master->lessee_id);
+ ret = -EINVAL;
+ goto out_unlock;
+ }
+
ret = drm_set_master(dev, file_priv, false);
out_unlock:
mutex_unlock(&dev->master_mutex);
@@ -270,6 +285,13 @@ void drm_master_release(struct drm_file *file_priv)
if (dev->master == file_priv->master)
drm_drop_master(dev, file_priv);
out:
+ if (file_priv->is_master) {
+ /* Revoke any leases held by this or lessees, but only if
+ * this is the "real" master
+ */
+ _drm_lease_revoke(master);
+ }
+
/* drop the master reference held by the file priv */
if (file_priv->master)
drm_master_put(&file_priv->master);
@@ -310,12 +332,17 @@ static void drm_master_destroy(struct kref *kref)
struct drm_master *master = container_of(kref, struct drm_master, refcount);
struct drm_device *dev = master->dev;
+ drm_lease_destroy(master);
+
if (dev->driver->master_destroy)
dev->driver->master_destroy(dev, master);
drm_legacy_master_rmmaps(dev, master);
idr_destroy(&master->magic_map);
+ idr_destroy(&master->leases);
+ idr_destroy(&master->lessee_idr);
+
kfree(master->unique);
kfree(master);
}
diff --git a/drivers/gpu/drm/drm_lease.c b/drivers/gpu/drm/drm_lease.c
new file mode 100644
index 000000000000..2ac404264d75
--- /dev/null
+++ b/drivers/gpu/drm/drm_lease.c
@@ -0,0 +1,379 @@
+/*
+ * Copyright © 2017 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+#include <drm/drmP.h>
+#include "drm_internal.h"
+#include "drm_legacy.h"
+#include "drm_crtc_internal.h"
+#include <drm/drm_lease.h>
+#include <drm/drm_auth.h>
+#include <drm/drm_crtc_helper.h>
+
+#define drm_for_each_lessee(lessee, lessor) \
+ list_for_each_entry((lessee), &(lessor)->lessees, lessee_list)
+
+/**
+ * drm_lease_owner - return ancestor owner drm_master
+ * @master: drm_master somewhere within tree of lessees and lessors
+ *
+ * RETURN:
+ *
+ * drm_master at the top of the tree (i.e, with lessor NULL
+ */
+struct drm_master *drm_lease_owner(struct drm_master *master)
+{
+ while (master->lessor != NULL)
+ master = master->lessor;
+ return master;
+}
+EXPORT_SYMBOL(drm_lease_owner);
+
+/**
+ * _drm_find_lessee - find lessee by id
+ * @master: drm_master of lessor
+ * @id: lessee_id
+ *
+ * RETURN:
+ *
+ * drm_master of the lessee if valid, NULL otherwise
+ */
+
+static struct drm_master*
+_drm_find_lessee(struct drm_master *master, int lessee_id)
+{
+ return idr_find(&drm_lease_owner(master)->lessee_idr, lessee_id);
+}
+
+/**
+ * _drm_lease_held_master - check to see if an object is leased (or owned) by master
+ * @master: the master to check the lease status of
+ * @id: the id to check
+ *
+ * Checks if the specified master holds a lease on the object. Return
+ * value:
+ *
+ * true 'master' holds a lease on (or owns) the object
+ * false 'master' does not hold a lease.
+ */
+static int _drm_lease_held_master(struct drm_master *master, int id)
+{
+ lockdep_assert_held(&master->dev->mode_config.idr_mutex);
+ if (master->lessor)
+ return idr_find(&master->leases, id) != NULL;
+ return true;
+}
+
+/**
+ * _drm_has_leased - check to see if an object has been leased
+ * @master: the master to check the lease status of
+ * @id: the id to check
+ *
+ * Checks if any lessee of 'master' holds a lease on 'id'. Return
+ * value:
+ *
+ * true Some lessee holds a lease on the object.
+ * false No lessee has a lease on the object.
+ */
+static bool _drm_has_leased(struct drm_master *master, int id)
+{
+ struct drm_master *lessee;
+
+ drm_for_each_lessee(lessee, master)
+ if (_drm_lease_held_master(lessee, id))
+ return true;
+ return false;
+}
+
+/**
+ * _drm_lease_held - check drm_mode_object lease status (idr_mutex held)
+ * @master: the drm_master
+ * @id: the object id
+ *
+ * Checks if the specified master holds a lease on the object. Return
+ * value:
+ *
+ * true 'master' holds a lease on (or owns) the object
+ * false 'master' does not hold a lease.
+ */
+bool _drm_lease_held(struct drm_file *file_priv, int id)
+{
+ if (file_priv == NULL || file_priv->master == NULL)
+ return true;
+
+ return _drm_lease_held_master(file_priv->master, id);
+}
+EXPORT_SYMBOL(_drm_lease_held);
+
+/**
+ * drm_lease_held - check drm_mode_object lease status (idr_mutex not held)
+ * @master: the drm_master
+ * @id: the object id
+ *
+ * Checks if the specified master holds a lease on the object. Return
+ * value:
+ *
+ * true 'master' holds a lease on (or owns) the object
+ * false 'master' does not hold a lease.
+ */
+bool drm_lease_held(struct drm_file *file_priv, int id)
+{
+ struct drm_master *master;
+ bool ret;
+
+ if (file_priv == NULL || file_priv->master == NULL)
+ return true;
+
+ master = file_priv->master;
+ mutex_lock(&master->dev->mode_config.idr_mutex);
+ ret = _drm_lease_held_master(master, id);
+ mutex_unlock(&master->dev->mode_config.idr_mutex);
+ return ret;
+}
+EXPORT_SYMBOL(drm_lease_held);
+
+/**
+ * drm_lease_filter_crtcs - restricted crtc set to leased values
+ * @file_priv: requestor file
+ * @crtcs: bitmask of crtcs to check
+ *
+ * Reconstructs a crtc mask based on the crtcs which are visible
+ * through the specified file.
+ */
+uint32_t drm_lease_filter_crtcs(struct drm_file *file_priv, uint32_t crtcs_in)
+{
+ struct drm_master *master;
+ struct drm_device *dev;
+ struct drm_crtc *crtc;
+ int count_in, count_out;
+ uint32_t crtcs_out = 0;
+
+ if (file_priv == NULL || file_priv->master == NULL)
+ return crtcs_in;
+
+ master = file_priv->master;
+ dev = master->dev;
+
+ count_in = count_out = 0;
+ mutex_lock(&master->dev->mode_config.idr_mutex);
+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+ if (_drm_lease_held_master(master, crtc->base.id)) {
+ uint32_t mask_in = 1ul << count_in;
+ if ((crtcs_in & mask_in) != 0) {
+ uint32_t mask_out = 1ul << count_out;
+ crtcs_out |= mask_out;
+ }
+ count_out++;
+ }
+ count_in++;
+ }
+ mutex_unlock(&master->dev->mode_config.idr_mutex);
+ return crtcs_out;
+}
+EXPORT_SYMBOL(drm_lease_filter_crtcs);
+
+/**
+ * drm_lease_filter_encoders - restrict encoder set to leased values
+ * @file_priv: requestor file
+ * @encoders: bitmask of encoders to check
+ *
+ * Reconstructs an encoder mask based on the encoders which are
+ * visible through the specified file.
+ */
+uint32_t drm_lease_filter_encoders(struct drm_file *file_priv, uint32_t encoders_in)
+{
+ struct drm_master *master;
+ struct drm_device *dev;
+ struct drm_encoder *encoder;
+ int count_in, count_out;
+ uint32_t encoders_out = 0;
+
+ count_in = count_out = 0;
+ if (file_priv == NULL || file_priv->master == NULL)
+ return encoders_in;
+
+ master = file_priv->master;
+ dev = master->dev;
+
+ mutex_lock(&master->dev->mode_config.idr_mutex);
+ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+ if (_drm_lease_held_master(master, encoder->base.id)) {
+ uint32_t mask_in = 1ul << count_in;
+ if ((encoders_in & mask_in) != 0) {
+ uint32_t mask_out = 1ul << count_out;
+ encoders_out |= mask_out;
+ }
+ count_out++;
+ }
+ count_in++;
+ }
+ mutex_unlock(&master->dev->mode_config.idr_mutex);
+ return encoders_out;
+}
+EXPORT_SYMBOL(drm_lease_filter_encoders);
+
+/*
+ * drm_lease_create - create a new drm_master with leased objects
+ * @lessor: lease holder (or owner) of objects
+ * @leases: objects to lease to the new drm_master
+ *
+ * Uses drm_master_create to allocate a new drm_master, then checks to
+ * make sure all of the desired objects can be leased, atomically
+ * leasing them to the new drmmaster.
+ *
+ * ERR_PTR(-EACCESS) some other master holds the title to any object
+ * ERR_PTR(-ENOENT) some object is not a valid DRM object for this device
+ * ERR_PTR(-EBUSY) some other lessee holds title to this object
+ * ERR_PTR(-EEXIST) same object specified more than once in the provided list
+ * ERR_PTR(-ENOMEM) allocation failed
+ */
+static struct drm_master *drm_lease_create(struct drm_master *lessor, struct idr *leases)
+{
+ struct drm_device *dev = lessor->dev;
+ int error;
+ struct drm_master *lessee;
+ int object;
+ int id;
+ void *entry;
+
+ DRM_DEBUG_LEASE("lessor %d\n", lessor->lessee_id);
+
+ lockdep_assert_held(&lessor->dev->master_mutex);
+
+ lessee = drm_master_create(lessor->dev);
+ if (!lessee) {
+ DRM_DEBUG_LEASE("drm_master_create failed\n");
+ return ERR_PTR(-ENOMEM);
+ }
+
+ /* Insert the new lessee into the tree */
+ id = idr_alloc(&(drm_lease_owner(lessor)->lessee_idr), lessee, 1, 0, GFP_KERNEL);
+ if (id < 0) {
+ error = id;
+ goto out_lessee;
+ }
+
+ lessee->lessee_id = id;
+ lessee->lessor = drm_master_get(lessor);
+ list_add_tail(&lessee->lessee_list, &lessor->lessees);
+
+ /* Lock the mode object mutex to make the check and allocation atomic */
+ mutex_lock(&lessor->dev->mode_config.idr_mutex);
+ idr_for_each_entry(leases, entry, object) {
+ error = 0;
+ if (!idr_find(&dev->mode_config.crtc_idr, object))
+ error = -ENOENT;
+ else if (!_drm_lease_held_master(lessor, object))
+ error = -EACCES;
+ else if (_drm_has_leased(lessor, object))
+ error = -EBUSY;
+
+ if (error != 0) {
+ DRM_DEBUG_LEASE("object %d failed %d\n", object, error);
+ goto out_unlock;
+ }
+ }
+
+ /* Move the leases over */
+ lessee->leases = *leases;
+ mutex_unlock(&lessor->dev->mode_config.idr_mutex);
+ DRM_DEBUG_LEASE("new lessee %d %p, lessor %d %p\n", lessee->lessee_id, lessee, lessor->lessee_id, lessor);
+ return lessee;
+
+out_unlock:
+ mutex_unlock(&lessor->dev->mode_config.idr_mutex);
+
+out_lessee:
+ drm_master_put(&lessee);
+ return ERR_PTR(error);
+}
+
+/**
+ * drm_lease_destroy - a master is going away
+ * @master: the drm_master being destroyed
+ *
+ * All lessees will have been destroyed as they
+ * hold a reference on their lessor. Notify any
+ * lessor for this master so that it can check
+ * the list of lessees.
+ */
+void drm_lease_destroy(struct drm_master *master)
+{
+ struct drm_device *dev = master->dev;
+
+ lockdep_assert_held(&dev->master_mutex);
+
+ DRM_DEBUG_LEASE("drm_lease_destroy %d\n", master->lessee_id);
+
+ /* This master is referenced by all lessees, hence it cannot be destroyed
+ * until all of them have been
+ */
+ WARN_ON(!list_empty(&master->lessees));
+
+ /* Remove this master from the lessee idr in the owner */
+ if (master->lessee_id != 0) {
+ DRM_DEBUG_LEASE("remove master %d from device list of lessees\n", master->lessee_id);
+ idr_remove(&(drm_lease_owner(master)->lessee_idr), master->lessee_id);
+ }
+
+ /* Remove this master from any lessee list it may be on */
+ list_del(&master->lessee_list);
+ if (master->lessor) {
+ /* Tell the master to check the lessee list */
+ drm_sysfs_hotplug_event(dev);
+ drm_master_put(&master->lessor);
+ }
+
+ DRM_DEBUG_LEASE("drm_lease_destroy done %d\n", master->lessee_id);
+}
+
+/**
+ * _drm_lease_revoke - revoke access to all leased objects
+ * @master: the master losing its lease
+ */
+
+void _drm_lease_revoke(struct drm_master *top)
+{
+ int object;
+ void *entry;
+ struct drm_master *master = top;
+
+ /*
+ * Walk the tree starting at 'top' emptying all leases. Because
+ * the tree is fully connected, we can do this without recursing
+ */
+ for (;;) {
+ DRM_DEBUG_LEASE("revoke leases for %p %d\n", master, master->lessee_id);
+
+ /* Evacuate the lease */
+ idr_for_each_entry(&master->leases, entry, object)
+ idr_remove(&master->leases, object);
+
+ /* Depth-first list walk */
+
+ /* Down */
+ if (!list_empty(&master->lessees)) {
+ master = list_first_entry(&master->lessees, struct drm_master, lessee_list);
+ } else {
+ /* Up */
+ while (master != top && master == list_last_entry(&master->lessor->lessees, struct drm_master, lessee_list))
+ master = master->lessor;
+
+ if (master == top)
+ break;
+
+ /* Over */
+ master = list_entry(master->lessee_list.next, struct drm_master, lessee_list);
+ }
+ }
+}
diff --git a/include/drm/drm_auth.h b/include/drm/drm_auth.h
index 81a40c2a9a3e..4b7fc22d3fc9 100644
--- a/include/drm/drm_auth.h
+++ b/include/drm/drm_auth.h
@@ -52,6 +52,12 @@ struct drm_lock_data {
* @dev: Link back to the DRM device
* @lock: DRI1 lock information.
* @driver_priv: Pointer to driver-private information.
+ * @lessor: Lease holder
+ * @lessee_id: id for lessees. Owners always have id 0
+ * @lessee_list: other lessees of the same master
+ * @lessees: drm_masters leasing from this one
+ * @leases: Objects leased to this drm_master.
+ * @lessee_idr: All lessees under this owner (only used where lessor == NULL)
*
* Note that master structures are only relevant for the legacy/primary device
* nodes, hence there can only be one per device, not one per drm_minor.
@@ -76,10 +82,24 @@ struct drm_master {
struct idr magic_map;
struct drm_lock_data lock;
void *driver_priv;
+
+ /* Tree of display resource leases, each of which is a drm_master struct
+ * All of these get activated simultaneously, so drm_device master points
+ * at the top of the tree (for which lessor is NULL)
+ */
+
+ struct drm_master *lessor;
+ int lessee_id;
+ struct list_head lessee_list;
+ struct list_head lessees;
+ struct idr leases;
+ struct idr lessee_idr;
};
struct drm_master *drm_master_get(struct drm_master *master);
void drm_master_put(struct drm_master **master);
bool drm_is_current_master(struct drm_file *fpriv);
+struct drm_master *drm_master_create(struct drm_device *dev);
+
#endif
diff --git a/include/drm/drm_lease.h b/include/drm/drm_lease.h
new file mode 100644
index 000000000000..a49667db1d6d
--- /dev/null
+++ b/include/drm/drm_lease.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright © 2017 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+#ifndef _DRM_LEASE_H_
+#define _DRM_LEASE_H_
+
+struct drm_file;
+struct drm_device;
+struct drm_master;
+
+struct drm_master *drm_lease_owner(struct drm_master *master);
+
+void drm_lease_destroy(struct drm_master *lessee);
+
+bool drm_lease_held(struct drm_file *file_priv, int id);
+
+bool _drm_lease_held(struct drm_file *file_priv, int id);
+
+void _drm_lease_revoke(struct drm_master *master);
+
+uint32_t drm_lease_filter_crtcs(struct drm_file *file_priv, uint32_t crtcs);
+
+uint32_t drm_lease_filter_encoders(struct drm_file *file_priv, uint32_t encoders);
+
+#endif /* _DRM_LEASE_H_ */
diff --git a/include/drm/drm_mode_object.h b/include/drm/drm_mode_object.h
index b2f920b518e3..c8155cb5a932 100644
--- a/include/drm/drm_mode_object.h
+++ b/include/drm/drm_mode_object.h
@@ -24,6 +24,7 @@
#define __DRM_MODESET_H__
#include <linux/kref.h>
+#include <drm/drm_lease.h>
struct drm_object_properties;
struct drm_property;
struct drm_device;
--
2.13.3
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 4/6] drm: Add drm_object lease infrastructure [v4]
@ 2017-10-11 0:48 ` Keith Packard
0 siblings, 0 replies; 21+ messages in thread
From: Keith Packard @ 2017-10-11 0:48 UTC (permalink / raw)
To: linux-kernel, Dave Airlie, Daniel Vetter; +Cc: Keith Packard, dri-devel
This provides new data structures to hold "lease" information about
drm mode setting objects, and provides for creating new drm_masters
which have access to a subset of the available drm resources.
An 'owner' is a drm_master which is not leasing the objects from
another drm_master, and hence 'owns' them.
A 'lessee' is a drm_master which is leasing objects from some other
drm_master. Each lessee holds the set of objects which it is leasing
from the lessor.
A 'lessor' is a drm_master which is leasing objects to another
drm_master. This is the same as the owner in the current code.
The set of objects any drm_master 'controls' is limited to the set of
objects it leases (for lessees) or all objects (for owners).
Objects not controlled by a drm_master cannot be modified through the
various state manipulating ioctls, and any state reported back to user
space will be edited to make them appear idle and/or unusable. For
instance, connectors always report 'disconnected', while encoders
report no possible crtcs or clones.
The full list of lessees leasing objects from an owner (either
directly, or indirectly through another lessee), can be searched from
an idr in the drm_master of the owner.
Changes for v2 as suggested by Daniel Vetter <daniel.vetter@ffwll.ch>:
* Sub-leasing has been disabled.
* BUG_ON for lock checking replaced with lockdep_assert_held
* 'change' ioctl has been removed.
* Leased objects can always be controlled by the lessor; the
'mask_lease' flag has been removed
* Checking for leased status has been simplified, replacing
the drm_lease_check function with drm_lease_held.
Changes in v3, some suggested by Dave Airlie <airlied@gmail.com>
* Add revocation. This allows leases to be effectively revoked by
removing all of the objects they have access to. The lease itself
hangs around as it's hanging off a file.
* Free the leases IDR when the master is destroyed
* _drm_lease_held should look at lessees, not lessor
* Allow non-master files to check for lease status
Changes in v4, suggested by Dave Airlie <airlied@gmail.com>
* Formatting and whitespace changes
Signed-off-by: Keith Packard <keithp@keithp.com>
---
drivers/gpu/drm/Makefile | 2 +-
drivers/gpu/drm/drm_auth.c | 29 +++-
drivers/gpu/drm/drm_lease.c | 379 ++++++++++++++++++++++++++++++++++++++++++
include/drm/drm_auth.h | 20 +++
include/drm/drm_lease.h | 36 ++++
include/drm/drm_mode_object.h | 1 +
6 files changed, 465 insertions(+), 2 deletions(-)
create mode 100644 drivers/gpu/drm/drm_lease.c
create mode 100644 include/drm/drm_lease.h
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index a3fdc5a68dff..81ff79336623 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -17,7 +17,7 @@ drm-y := drm_auth.o drm_bufs.o drm_cache.o \
drm_encoder.o drm_mode_object.o drm_property.o \
drm_plane.o drm_color_mgmt.o drm_print.o \
drm_dumb_buffers.o drm_mode_config.o drm_vblank.o \
- drm_syncobj.o
+ drm_syncobj.o drm_lease.o
drm-$(CONFIG_DRM_LIB_RANDOM) += lib/drm_random.o
drm-$(CONFIG_DRM_VM) += drm_vm.o
diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c
index 7ff697389d74..541177c71d51 100644
--- a/drivers/gpu/drm/drm_auth.c
+++ b/drivers/gpu/drm/drm_auth.c
@@ -31,6 +31,7 @@
#include <drm/drmP.h>
#include "drm_internal.h"
#include "drm_legacy.h"
+#include <drm/drm_lease.h>
/**
* DOC: master and authentication
@@ -93,7 +94,7 @@ int drm_authmagic(struct drm_device *dev, void *data,
return file ? 0 : -EINVAL;
}
-static struct drm_master *drm_master_create(struct drm_device *dev)
+struct drm_master *drm_master_create(struct drm_device *dev)
{
struct drm_master *master;
@@ -107,6 +108,14 @@ static struct drm_master *drm_master_create(struct drm_device *dev)
idr_init(&master->magic_map);
master->dev = dev;
+ /* initialize the tree of output resource lessees */
+ master->lessor = NULL;
+ master->lessee_id = 0;
+ INIT_LIST_HEAD(&master->lessees);
+ INIT_LIST_HEAD(&master->lessee_list);
+ idr_init(&master->leases);
+ idr_init(&master->lessee_idr);
+
return master;
}
@@ -189,6 +198,12 @@ int drm_setmaster_ioctl(struct drm_device *dev, void *data,
goto out_unlock;
}
+ if (file_priv->master->lessor != NULL) {
+ DRM_DEBUG_LEASE("Attempt to set lessee %d as master\n", file_priv->master->lessee_id);
+ ret = -EINVAL;
+ goto out_unlock;
+ }
+
ret = drm_set_master(dev, file_priv, false);
out_unlock:
mutex_unlock(&dev->master_mutex);
@@ -270,6 +285,13 @@ void drm_master_release(struct drm_file *file_priv)
if (dev->master == file_priv->master)
drm_drop_master(dev, file_priv);
out:
+ if (file_priv->is_master) {
+ /* Revoke any leases held by this or lessees, but only if
+ * this is the "real" master
+ */
+ _drm_lease_revoke(master);
+ }
+
/* drop the master reference held by the file priv */
if (file_priv->master)
drm_master_put(&file_priv->master);
@@ -310,12 +332,17 @@ static void drm_master_destroy(struct kref *kref)
struct drm_master *master = container_of(kref, struct drm_master, refcount);
struct drm_device *dev = master->dev;
+ drm_lease_destroy(master);
+
if (dev->driver->master_destroy)
dev->driver->master_destroy(dev, master);
drm_legacy_master_rmmaps(dev, master);
idr_destroy(&master->magic_map);
+ idr_destroy(&master->leases);
+ idr_destroy(&master->lessee_idr);
+
kfree(master->unique);
kfree(master);
}
diff --git a/drivers/gpu/drm/drm_lease.c b/drivers/gpu/drm/drm_lease.c
new file mode 100644
index 000000000000..2ac404264d75
--- /dev/null
+++ b/drivers/gpu/drm/drm_lease.c
@@ -0,0 +1,379 @@
+/*
+ * Copyright © 2017 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+#include <drm/drmP.h>
+#include "drm_internal.h"
+#include "drm_legacy.h"
+#include "drm_crtc_internal.h"
+#include <drm/drm_lease.h>
+#include <drm/drm_auth.h>
+#include <drm/drm_crtc_helper.h>
+
+#define drm_for_each_lessee(lessee, lessor) \
+ list_for_each_entry((lessee), &(lessor)->lessees, lessee_list)
+
+/**
+ * drm_lease_owner - return ancestor owner drm_master
+ * @master: drm_master somewhere within tree of lessees and lessors
+ *
+ * RETURN:
+ *
+ * drm_master at the top of the tree (i.e, with lessor NULL
+ */
+struct drm_master *drm_lease_owner(struct drm_master *master)
+{
+ while (master->lessor != NULL)
+ master = master->lessor;
+ return master;
+}
+EXPORT_SYMBOL(drm_lease_owner);
+
+/**
+ * _drm_find_lessee - find lessee by id
+ * @master: drm_master of lessor
+ * @id: lessee_id
+ *
+ * RETURN:
+ *
+ * drm_master of the lessee if valid, NULL otherwise
+ */
+
+static struct drm_master*
+_drm_find_lessee(struct drm_master *master, int lessee_id)
+{
+ return idr_find(&drm_lease_owner(master)->lessee_idr, lessee_id);
+}
+
+/**
+ * _drm_lease_held_master - check to see if an object is leased (or owned) by master
+ * @master: the master to check the lease status of
+ * @id: the id to check
+ *
+ * Checks if the specified master holds a lease on the object. Return
+ * value:
+ *
+ * true 'master' holds a lease on (or owns) the object
+ * false 'master' does not hold a lease.
+ */
+static int _drm_lease_held_master(struct drm_master *master, int id)
+{
+ lockdep_assert_held(&master->dev->mode_config.idr_mutex);
+ if (master->lessor)
+ return idr_find(&master->leases, id) != NULL;
+ return true;
+}
+
+/**
+ * _drm_has_leased - check to see if an object has been leased
+ * @master: the master to check the lease status of
+ * @id: the id to check
+ *
+ * Checks if any lessee of 'master' holds a lease on 'id'. Return
+ * value:
+ *
+ * true Some lessee holds a lease on the object.
+ * false No lessee has a lease on the object.
+ */
+static bool _drm_has_leased(struct drm_master *master, int id)
+{
+ struct drm_master *lessee;
+
+ drm_for_each_lessee(lessee, master)
+ if (_drm_lease_held_master(lessee, id))
+ return true;
+ return false;
+}
+
+/**
+ * _drm_lease_held - check drm_mode_object lease status (idr_mutex held)
+ * @master: the drm_master
+ * @id: the object id
+ *
+ * Checks if the specified master holds a lease on the object. Return
+ * value:
+ *
+ * true 'master' holds a lease on (or owns) the object
+ * false 'master' does not hold a lease.
+ */
+bool _drm_lease_held(struct drm_file *file_priv, int id)
+{
+ if (file_priv == NULL || file_priv->master == NULL)
+ return true;
+
+ return _drm_lease_held_master(file_priv->master, id);
+}
+EXPORT_SYMBOL(_drm_lease_held);
+
+/**
+ * drm_lease_held - check drm_mode_object lease status (idr_mutex not held)
+ * @master: the drm_master
+ * @id: the object id
+ *
+ * Checks if the specified master holds a lease on the object. Return
+ * value:
+ *
+ * true 'master' holds a lease on (or owns) the object
+ * false 'master' does not hold a lease.
+ */
+bool drm_lease_held(struct drm_file *file_priv, int id)
+{
+ struct drm_master *master;
+ bool ret;
+
+ if (file_priv == NULL || file_priv->master == NULL)
+ return true;
+
+ master = file_priv->master;
+ mutex_lock(&master->dev->mode_config.idr_mutex);
+ ret = _drm_lease_held_master(master, id);
+ mutex_unlock(&master->dev->mode_config.idr_mutex);
+ return ret;
+}
+EXPORT_SYMBOL(drm_lease_held);
+
+/**
+ * drm_lease_filter_crtcs - restricted crtc set to leased values
+ * @file_priv: requestor file
+ * @crtcs: bitmask of crtcs to check
+ *
+ * Reconstructs a crtc mask based on the crtcs which are visible
+ * through the specified file.
+ */
+uint32_t drm_lease_filter_crtcs(struct drm_file *file_priv, uint32_t crtcs_in)
+{
+ struct drm_master *master;
+ struct drm_device *dev;
+ struct drm_crtc *crtc;
+ int count_in, count_out;
+ uint32_t crtcs_out = 0;
+
+ if (file_priv == NULL || file_priv->master == NULL)
+ return crtcs_in;
+
+ master = file_priv->master;
+ dev = master->dev;
+
+ count_in = count_out = 0;
+ mutex_lock(&master->dev->mode_config.idr_mutex);
+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+ if (_drm_lease_held_master(master, crtc->base.id)) {
+ uint32_t mask_in = 1ul << count_in;
+ if ((crtcs_in & mask_in) != 0) {
+ uint32_t mask_out = 1ul << count_out;
+ crtcs_out |= mask_out;
+ }
+ count_out++;
+ }
+ count_in++;
+ }
+ mutex_unlock(&master->dev->mode_config.idr_mutex);
+ return crtcs_out;
+}
+EXPORT_SYMBOL(drm_lease_filter_crtcs);
+
+/**
+ * drm_lease_filter_encoders - restrict encoder set to leased values
+ * @file_priv: requestor file
+ * @encoders: bitmask of encoders to check
+ *
+ * Reconstructs an encoder mask based on the encoders which are
+ * visible through the specified file.
+ */
+uint32_t drm_lease_filter_encoders(struct drm_file *file_priv, uint32_t encoders_in)
+{
+ struct drm_master *master;
+ struct drm_device *dev;
+ struct drm_encoder *encoder;
+ int count_in, count_out;
+ uint32_t encoders_out = 0;
+
+ count_in = count_out = 0;
+ if (file_priv == NULL || file_priv->master == NULL)
+ return encoders_in;
+
+ master = file_priv->master;
+ dev = master->dev;
+
+ mutex_lock(&master->dev->mode_config.idr_mutex);
+ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+ if (_drm_lease_held_master(master, encoder->base.id)) {
+ uint32_t mask_in = 1ul << count_in;
+ if ((encoders_in & mask_in) != 0) {
+ uint32_t mask_out = 1ul << count_out;
+ encoders_out |= mask_out;
+ }
+ count_out++;
+ }
+ count_in++;
+ }
+ mutex_unlock(&master->dev->mode_config.idr_mutex);
+ return encoders_out;
+}
+EXPORT_SYMBOL(drm_lease_filter_encoders);
+
+/*
+ * drm_lease_create - create a new drm_master with leased objects
+ * @lessor: lease holder (or owner) of objects
+ * @leases: objects to lease to the new drm_master
+ *
+ * Uses drm_master_create to allocate a new drm_master, then checks to
+ * make sure all of the desired objects can be leased, atomically
+ * leasing them to the new drmmaster.
+ *
+ * ERR_PTR(-EACCESS) some other master holds the title to any object
+ * ERR_PTR(-ENOENT) some object is not a valid DRM object for this device
+ * ERR_PTR(-EBUSY) some other lessee holds title to this object
+ * ERR_PTR(-EEXIST) same object specified more than once in the provided list
+ * ERR_PTR(-ENOMEM) allocation failed
+ */
+static struct drm_master *drm_lease_create(struct drm_master *lessor, struct idr *leases)
+{
+ struct drm_device *dev = lessor->dev;
+ int error;
+ struct drm_master *lessee;
+ int object;
+ int id;
+ void *entry;
+
+ DRM_DEBUG_LEASE("lessor %d\n", lessor->lessee_id);
+
+ lockdep_assert_held(&lessor->dev->master_mutex);
+
+ lessee = drm_master_create(lessor->dev);
+ if (!lessee) {
+ DRM_DEBUG_LEASE("drm_master_create failed\n");
+ return ERR_PTR(-ENOMEM);
+ }
+
+ /* Insert the new lessee into the tree */
+ id = idr_alloc(&(drm_lease_owner(lessor)->lessee_idr), lessee, 1, 0, GFP_KERNEL);
+ if (id < 0) {
+ error = id;
+ goto out_lessee;
+ }
+
+ lessee->lessee_id = id;
+ lessee->lessor = drm_master_get(lessor);
+ list_add_tail(&lessee->lessee_list, &lessor->lessees);
+
+ /* Lock the mode object mutex to make the check and allocation atomic */
+ mutex_lock(&lessor->dev->mode_config.idr_mutex);
+ idr_for_each_entry(leases, entry, object) {
+ error = 0;
+ if (!idr_find(&dev->mode_config.crtc_idr, object))
+ error = -ENOENT;
+ else if (!_drm_lease_held_master(lessor, object))
+ error = -EACCES;
+ else if (_drm_has_leased(lessor, object))
+ error = -EBUSY;
+
+ if (error != 0) {
+ DRM_DEBUG_LEASE("object %d failed %d\n", object, error);
+ goto out_unlock;
+ }
+ }
+
+ /* Move the leases over */
+ lessee->leases = *leases;
+ mutex_unlock(&lessor->dev->mode_config.idr_mutex);
+ DRM_DEBUG_LEASE("new lessee %d %p, lessor %d %p\n", lessee->lessee_id, lessee, lessor->lessee_id, lessor);
+ return lessee;
+
+out_unlock:
+ mutex_unlock(&lessor->dev->mode_config.idr_mutex);
+
+out_lessee:
+ drm_master_put(&lessee);
+ return ERR_PTR(error);
+}
+
+/**
+ * drm_lease_destroy - a master is going away
+ * @master: the drm_master being destroyed
+ *
+ * All lessees will have been destroyed as they
+ * hold a reference on their lessor. Notify any
+ * lessor for this master so that it can check
+ * the list of lessees.
+ */
+void drm_lease_destroy(struct drm_master *master)
+{
+ struct drm_device *dev = master->dev;
+
+ lockdep_assert_held(&dev->master_mutex);
+
+ DRM_DEBUG_LEASE("drm_lease_destroy %d\n", master->lessee_id);
+
+ /* This master is referenced by all lessees, hence it cannot be destroyed
+ * until all of them have been
+ */
+ WARN_ON(!list_empty(&master->lessees));
+
+ /* Remove this master from the lessee idr in the owner */
+ if (master->lessee_id != 0) {
+ DRM_DEBUG_LEASE("remove master %d from device list of lessees\n", master->lessee_id);
+ idr_remove(&(drm_lease_owner(master)->lessee_idr), master->lessee_id);
+ }
+
+ /* Remove this master from any lessee list it may be on */
+ list_del(&master->lessee_list);
+ if (master->lessor) {
+ /* Tell the master to check the lessee list */
+ drm_sysfs_hotplug_event(dev);
+ drm_master_put(&master->lessor);
+ }
+
+ DRM_DEBUG_LEASE("drm_lease_destroy done %d\n", master->lessee_id);
+}
+
+/**
+ * _drm_lease_revoke - revoke access to all leased objects
+ * @master: the master losing its lease
+ */
+
+void _drm_lease_revoke(struct drm_master *top)
+{
+ int object;
+ void *entry;
+ struct drm_master *master = top;
+
+ /*
+ * Walk the tree starting at 'top' emptying all leases. Because
+ * the tree is fully connected, we can do this without recursing
+ */
+ for (;;) {
+ DRM_DEBUG_LEASE("revoke leases for %p %d\n", master, master->lessee_id);
+
+ /* Evacuate the lease */
+ idr_for_each_entry(&master->leases, entry, object)
+ idr_remove(&master->leases, object);
+
+ /* Depth-first list walk */
+
+ /* Down */
+ if (!list_empty(&master->lessees)) {
+ master = list_first_entry(&master->lessees, struct drm_master, lessee_list);
+ } else {
+ /* Up */
+ while (master != top && master == list_last_entry(&master->lessor->lessees, struct drm_master, lessee_list))
+ master = master->lessor;
+
+ if (master == top)
+ break;
+
+ /* Over */
+ master = list_entry(master->lessee_list.next, struct drm_master, lessee_list);
+ }
+ }
+}
diff --git a/include/drm/drm_auth.h b/include/drm/drm_auth.h
index 81a40c2a9a3e..4b7fc22d3fc9 100644
--- a/include/drm/drm_auth.h
+++ b/include/drm/drm_auth.h
@@ -52,6 +52,12 @@ struct drm_lock_data {
* @dev: Link back to the DRM device
* @lock: DRI1 lock information.
* @driver_priv: Pointer to driver-private information.
+ * @lessor: Lease holder
+ * @lessee_id: id for lessees. Owners always have id 0
+ * @lessee_list: other lessees of the same master
+ * @lessees: drm_masters leasing from this one
+ * @leases: Objects leased to this drm_master.
+ * @lessee_idr: All lessees under this owner (only used where lessor == NULL)
*
* Note that master structures are only relevant for the legacy/primary device
* nodes, hence there can only be one per device, not one per drm_minor.
@@ -76,10 +82,24 @@ struct drm_master {
struct idr magic_map;
struct drm_lock_data lock;
void *driver_priv;
+
+ /* Tree of display resource leases, each of which is a drm_master struct
+ * All of these get activated simultaneously, so drm_device master points
+ * at the top of the tree (for which lessor is NULL)
+ */
+
+ struct drm_master *lessor;
+ int lessee_id;
+ struct list_head lessee_list;
+ struct list_head lessees;
+ struct idr leases;
+ struct idr lessee_idr;
};
struct drm_master *drm_master_get(struct drm_master *master);
void drm_master_put(struct drm_master **master);
bool drm_is_current_master(struct drm_file *fpriv);
+struct drm_master *drm_master_create(struct drm_device *dev);
+
#endif
diff --git a/include/drm/drm_lease.h b/include/drm/drm_lease.h
new file mode 100644
index 000000000000..a49667db1d6d
--- /dev/null
+++ b/include/drm/drm_lease.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright © 2017 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+#ifndef _DRM_LEASE_H_
+#define _DRM_LEASE_H_
+
+struct drm_file;
+struct drm_device;
+struct drm_master;
+
+struct drm_master *drm_lease_owner(struct drm_master *master);
+
+void drm_lease_destroy(struct drm_master *lessee);
+
+bool drm_lease_held(struct drm_file *file_priv, int id);
+
+bool _drm_lease_held(struct drm_file *file_priv, int id);
+
+void _drm_lease_revoke(struct drm_master *master);
+
+uint32_t drm_lease_filter_crtcs(struct drm_file *file_priv, uint32_t crtcs);
+
+uint32_t drm_lease_filter_encoders(struct drm_file *file_priv, uint32_t encoders);
+
+#endif /* _DRM_LEASE_H_ */
diff --git a/include/drm/drm_mode_object.h b/include/drm/drm_mode_object.h
index b2f920b518e3..c8155cb5a932 100644
--- a/include/drm/drm_mode_object.h
+++ b/include/drm/drm_mode_object.h
@@ -24,6 +24,7 @@
#define __DRM_MODESET_H__
#include <linux/kref.h>
+#include <drm/drm_lease.h>
struct drm_object_properties;
struct drm_property;
struct drm_device;
--
2.13.3
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 5/6] drm: Check mode object lease status in all master ioctl paths [v2]
2017-10-11 0:48 ` Keith Packard
@ 2017-10-11 0:48 ` Keith Packard
-1 siblings, 0 replies; 21+ messages in thread
From: Keith Packard @ 2017-10-11 0:48 UTC (permalink / raw)
To: linux-kernel, Dave Airlie, Daniel Vetter; +Cc: Keith Packard, dri-devel
Attempts to modify un-leased objects are rejected with an error.
Information returned about unleased objects is modified to make them
appear unusable and/or disconnected.
Changes for v2 as suggested by Daniel Vetter <daniel.vetter@ffwll.ch>:
With the change in the __drm_mode_object_find API to pass the
file_priv along, we can now centralize most of the lease-based access
checks in that function.
A few places skip that API and require in-line checks.
Signed-off-by: Keith Packard <keithp@keithp.com>
---
drivers/gpu/drm/drm_auth.c | 2 +-
drivers/gpu/drm/drm_connector.c | 5 +++--
drivers/gpu/drm/drm_encoder.c | 8 +++++---
drivers/gpu/drm/drm_mode_config.c | 32 +++++++++++++++++++-------------
drivers/gpu/drm/drm_mode_object.c | 22 ++++++++++++++++++++++
drivers/gpu/drm/drm_plane.c | 8 +++++---
drivers/gpu/drm/drm_vblank.c | 18 ++++++++++++++++--
7 files changed, 71 insertions(+), 24 deletions(-)
diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c
index 541177c71d51..bab26b477738 100644
--- a/drivers/gpu/drm/drm_auth.c
+++ b/drivers/gpu/drm/drm_auth.c
@@ -310,7 +310,7 @@ void drm_master_release(struct drm_file *file_priv)
*/
bool drm_is_current_master(struct drm_file *fpriv)
{
- return fpriv->is_master && fpriv->master == fpriv->minor->dev->master;
+ return fpriv->is_master && drm_lease_owner(fpriv->master) == fpriv->minor->dev->master;
}
EXPORT_SYMBOL(drm_is_current_master);
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 704fc8934616..0712c14cb57c 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -1315,7 +1315,8 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
return -ENOENT;
for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++)
- if (connector->encoder_ids[i] != 0)
+ if (connector->encoder_ids[i] != 0 &&
+ drm_lease_held(file_priv, connector->encoder_ids[i]))
encoders_count++;
if ((out_resp->count_encoders >= encoders_count) && encoders_count) {
@@ -1382,7 +1383,7 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
encoder = drm_connector_get_encoder(connector);
- if (encoder)
+ if (encoder && drm_lease_held(file_priv, encoder->base.id))
out_resp->encoder_id = encoder->base.id;
else
out_resp->encoder_id = 0;
diff --git a/drivers/gpu/drm/drm_encoder.c b/drivers/gpu/drm/drm_encoder.c
index 43f644844b83..6ad6416f2ede 100644
--- a/drivers/gpu/drm/drm_encoder.c
+++ b/drivers/gpu/drm/drm_encoder.c
@@ -226,7 +226,7 @@ int drm_mode_getencoder(struct drm_device *dev, void *data,
drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
crtc = drm_encoder_get_crtc(encoder);
- if (crtc)
+ if (crtc && drm_lease_held(file_priv, crtc->base.id))
enc_resp->crtc_id = crtc->base.id;
else
enc_resp->crtc_id = 0;
@@ -234,8 +234,10 @@ int drm_mode_getencoder(struct drm_device *dev, void *data,
enc_resp->encoder_type = encoder->encoder_type;
enc_resp->encoder_id = encoder->base.id;
- enc_resp->possible_crtcs = encoder->possible_crtcs;
- enc_resp->possible_clones = encoder->possible_clones;
+ enc_resp->possible_crtcs = drm_lease_filter_crtcs(file_priv,
+ encoder->possible_crtcs);
+ enc_resp->possible_clones = drm_lease_filter_encoders(file_priv,
+ encoder->possible_clones);
return 0;
}
diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c
index 74f6ff5df656..fad6646b38d3 100644
--- a/drivers/gpu/drm/drm_mode_config.c
+++ b/drivers/gpu/drm/drm_mode_config.c
@@ -122,20 +122,24 @@ int drm_mode_getresources(struct drm_device *dev, void *data,
count = 0;
crtc_id = u64_to_user_ptr(card_res->crtc_id_ptr);
drm_for_each_crtc(crtc, dev) {
- if (count < card_res->count_crtcs &&
- put_user(crtc->base.id, crtc_id + count))
- return -EFAULT;
- count++;
+ if (drm_lease_held(file_priv, crtc->base.id)) {
+ if (count < card_res->count_crtcs &&
+ put_user(crtc->base.id, crtc_id + count))
+ return -EFAULT;
+ count++;
+ }
}
card_res->count_crtcs = count;
count = 0;
encoder_id = u64_to_user_ptr(card_res->encoder_id_ptr);
drm_for_each_encoder(encoder, dev) {
- if (count < card_res->count_encoders &&
- put_user(encoder->base.id, encoder_id + count))
- return -EFAULT;
- count++;
+ if (drm_lease_held(file_priv, encoder->base.id)) {
+ if (count < card_res->count_encoders &&
+ put_user(encoder->base.id, encoder_id + count))
+ return -EFAULT;
+ count++;
+ }
}
card_res->count_encoders = count;
@@ -143,12 +147,14 @@ int drm_mode_getresources(struct drm_device *dev, void *data,
count = 0;
connector_id = u64_to_user_ptr(card_res->connector_id_ptr);
drm_for_each_connector_iter(connector, &conn_iter) {
- if (count < card_res->count_connectors &&
- put_user(connector->base.id, connector_id + count)) {
- drm_connector_list_iter_end(&conn_iter);
- return -EFAULT;
+ if (drm_lease_held(file_priv, connector->base.id)) {
+ if (count < card_res->count_connectors &&
+ put_user(connector->base.id, connector_id + count)) {
+ drm_connector_list_iter_end(&conn_iter);
+ return -EFAULT;
+ }
+ count++;
}
- count++;
}
card_res->count_connectors = count;
drm_connector_list_iter_end(&conn_iter);
diff --git a/drivers/gpu/drm/drm_mode_object.c b/drivers/gpu/drm/drm_mode_object.c
index 240a05d91a53..ef8befe34bdf 100644
--- a/drivers/gpu/drm/drm_mode_object.c
+++ b/drivers/gpu/drm/drm_mode_object.c
@@ -104,6 +104,25 @@ void drm_mode_object_unregister(struct drm_device *dev,
mutex_unlock(&dev->mode_config.idr_mutex);
}
+/**
+ * drm_lease_required - check types which must be leased to be used
+ * @type: type of object
+ *
+ * Returns whether the provided type of drm_mode_object must
+ * be owned or leased to be used by a process.
+ */
+static bool drm_lease_required(uint32_t type)
+{
+ switch(type) {
+ case DRM_MODE_OBJECT_CRTC:
+ case DRM_MODE_OBJECT_CONNECTOR:
+ case DRM_MODE_OBJECT_ENCODER:
+ return true;
+ default:
+ return false;
+ }
+}
+
struct drm_mode_object *__drm_mode_object_find(struct drm_device *dev,
struct drm_file *file_priv,
uint32_t id, uint32_t type)
@@ -117,6 +136,9 @@ struct drm_mode_object *__drm_mode_object_find(struct drm_device *dev,
if (obj && obj->id != id)
obj = NULL;
+ if (obj && drm_lease_required(obj->type) && !_drm_lease_held(file_priv, obj->id))
+ obj = NULL;
+
if (obj && obj->free_cb) {
if (!kref_get_unless_zero(&obj->refcount))
obj = NULL;
diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c
index 574fd1475214..e0bb14ad0312 100644
--- a/drivers/gpu/drm/drm_plane.c
+++ b/drivers/gpu/drm/drm_plane.c
@@ -518,9 +518,9 @@ int drm_mode_getplane(struct drm_device *dev, void *data,
return -ENOENT;
drm_modeset_lock(&plane->mutex, NULL);
- if (plane->state && plane->state->crtc)
+ if (plane->state && plane->state->crtc && drm_lease_held(file_priv, plane->state->crtc->base.id))
plane_resp->crtc_id = plane->state->crtc->base.id;
- else if (!plane->state && plane->crtc)
+ else if (!plane->state && plane->crtc && drm_lease_held(file_priv, plane->crtc->base.id))
plane_resp->crtc_id = plane->crtc->base.id;
else
plane_resp->crtc_id = 0;
@@ -534,7 +534,9 @@ int drm_mode_getplane(struct drm_device *dev, void *data,
drm_modeset_unlock(&plane->mutex);
plane_resp->plane_id = plane->base.id;
- plane_resp->possible_crtcs = plane->possible_crtcs;
+ plane_resp->possible_crtcs = drm_lease_filter_crtcs(file_priv,
+ plane->possible_crtcs);
+
plane_resp->gamma_size = 0;
/*
diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
index 45ac2efd5078..583a17a212a9 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -1459,10 +1459,12 @@ static u64 widen_32_to_64(u32 narrow, u64 near)
int drm_wait_vblank_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
+ struct drm_crtc *crtc;
struct drm_vblank_crtc *vblank;
union drm_wait_vblank *vblwait = data;
int ret;
u64 req_seq;
+ unsigned int pipe_index;
unsigned int flags, seq, pipe, high_pipe;
if (!dev->irq_enabled)
@@ -1484,9 +1486,21 @@ int drm_wait_vblank_ioctl(struct drm_device *dev, void *data,
flags = vblwait->request.type & _DRM_VBLANK_FLAGS_MASK;
high_pipe = (vblwait->request.type & _DRM_VBLANK_HIGH_CRTC_MASK);
if (high_pipe)
- pipe = high_pipe >> _DRM_VBLANK_HIGH_CRTC_SHIFT;
+ pipe_index = high_pipe >> _DRM_VBLANK_HIGH_CRTC_SHIFT;
else
- pipe = flags & _DRM_VBLANK_SECONDARY ? 1 : 0;
+ pipe_index = flags & _DRM_VBLANK_SECONDARY ? 1 : 0;
+
+ /* Convert lease-relative crtc index into global crtc index */
+ pipe = 0;
+ drm_for_each_crtc(crtc, dev) {
+ if (drm_lease_held(file_priv, crtc->base.id)) {
+ if (pipe_index == 0)
+ break;
+ pipe_index--;
+ }
+ pipe++;
+ }
+
if (pipe >= dev->num_crtcs)
return -EINVAL;
--
2.13.3
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 5/6] drm: Check mode object lease status in all master ioctl paths [v2]
@ 2017-10-11 0:48 ` Keith Packard
0 siblings, 0 replies; 21+ messages in thread
From: Keith Packard @ 2017-10-11 0:48 UTC (permalink / raw)
To: linux-kernel, Dave Airlie, Daniel Vetter; +Cc: Keith Packard, dri-devel
Attempts to modify un-leased objects are rejected with an error.
Information returned about unleased objects is modified to make them
appear unusable and/or disconnected.
Changes for v2 as suggested by Daniel Vetter <daniel.vetter@ffwll.ch>:
With the change in the __drm_mode_object_find API to pass the
file_priv along, we can now centralize most of the lease-based access
checks in that function.
A few places skip that API and require in-line checks.
Signed-off-by: Keith Packard <keithp@keithp.com>
---
drivers/gpu/drm/drm_auth.c | 2 +-
drivers/gpu/drm/drm_connector.c | 5 +++--
drivers/gpu/drm/drm_encoder.c | 8 +++++---
drivers/gpu/drm/drm_mode_config.c | 32 +++++++++++++++++++-------------
drivers/gpu/drm/drm_mode_object.c | 22 ++++++++++++++++++++++
drivers/gpu/drm/drm_plane.c | 8 +++++---
drivers/gpu/drm/drm_vblank.c | 18 ++++++++++++++++--
7 files changed, 71 insertions(+), 24 deletions(-)
diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c
index 541177c71d51..bab26b477738 100644
--- a/drivers/gpu/drm/drm_auth.c
+++ b/drivers/gpu/drm/drm_auth.c
@@ -310,7 +310,7 @@ void drm_master_release(struct drm_file *file_priv)
*/
bool drm_is_current_master(struct drm_file *fpriv)
{
- return fpriv->is_master && fpriv->master == fpriv->minor->dev->master;
+ return fpriv->is_master && drm_lease_owner(fpriv->master) == fpriv->minor->dev->master;
}
EXPORT_SYMBOL(drm_is_current_master);
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 704fc8934616..0712c14cb57c 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -1315,7 +1315,8 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
return -ENOENT;
for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++)
- if (connector->encoder_ids[i] != 0)
+ if (connector->encoder_ids[i] != 0 &&
+ drm_lease_held(file_priv, connector->encoder_ids[i]))
encoders_count++;
if ((out_resp->count_encoders >= encoders_count) && encoders_count) {
@@ -1382,7 +1383,7 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
encoder = drm_connector_get_encoder(connector);
- if (encoder)
+ if (encoder && drm_lease_held(file_priv, encoder->base.id))
out_resp->encoder_id = encoder->base.id;
else
out_resp->encoder_id = 0;
diff --git a/drivers/gpu/drm/drm_encoder.c b/drivers/gpu/drm/drm_encoder.c
index 43f644844b83..6ad6416f2ede 100644
--- a/drivers/gpu/drm/drm_encoder.c
+++ b/drivers/gpu/drm/drm_encoder.c
@@ -226,7 +226,7 @@ int drm_mode_getencoder(struct drm_device *dev, void *data,
drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
crtc = drm_encoder_get_crtc(encoder);
- if (crtc)
+ if (crtc && drm_lease_held(file_priv, crtc->base.id))
enc_resp->crtc_id = crtc->base.id;
else
enc_resp->crtc_id = 0;
@@ -234,8 +234,10 @@ int drm_mode_getencoder(struct drm_device *dev, void *data,
enc_resp->encoder_type = encoder->encoder_type;
enc_resp->encoder_id = encoder->base.id;
- enc_resp->possible_crtcs = encoder->possible_crtcs;
- enc_resp->possible_clones = encoder->possible_clones;
+ enc_resp->possible_crtcs = drm_lease_filter_crtcs(file_priv,
+ encoder->possible_crtcs);
+ enc_resp->possible_clones = drm_lease_filter_encoders(file_priv,
+ encoder->possible_clones);
return 0;
}
diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c
index 74f6ff5df656..fad6646b38d3 100644
--- a/drivers/gpu/drm/drm_mode_config.c
+++ b/drivers/gpu/drm/drm_mode_config.c
@@ -122,20 +122,24 @@ int drm_mode_getresources(struct drm_device *dev, void *data,
count = 0;
crtc_id = u64_to_user_ptr(card_res->crtc_id_ptr);
drm_for_each_crtc(crtc, dev) {
- if (count < card_res->count_crtcs &&
- put_user(crtc->base.id, crtc_id + count))
- return -EFAULT;
- count++;
+ if (drm_lease_held(file_priv, crtc->base.id)) {
+ if (count < card_res->count_crtcs &&
+ put_user(crtc->base.id, crtc_id + count))
+ return -EFAULT;
+ count++;
+ }
}
card_res->count_crtcs = count;
count = 0;
encoder_id = u64_to_user_ptr(card_res->encoder_id_ptr);
drm_for_each_encoder(encoder, dev) {
- if (count < card_res->count_encoders &&
- put_user(encoder->base.id, encoder_id + count))
- return -EFAULT;
- count++;
+ if (drm_lease_held(file_priv, encoder->base.id)) {
+ if (count < card_res->count_encoders &&
+ put_user(encoder->base.id, encoder_id + count))
+ return -EFAULT;
+ count++;
+ }
}
card_res->count_encoders = count;
@@ -143,12 +147,14 @@ int drm_mode_getresources(struct drm_device *dev, void *data,
count = 0;
connector_id = u64_to_user_ptr(card_res->connector_id_ptr);
drm_for_each_connector_iter(connector, &conn_iter) {
- if (count < card_res->count_connectors &&
- put_user(connector->base.id, connector_id + count)) {
- drm_connector_list_iter_end(&conn_iter);
- return -EFAULT;
+ if (drm_lease_held(file_priv, connector->base.id)) {
+ if (count < card_res->count_connectors &&
+ put_user(connector->base.id, connector_id + count)) {
+ drm_connector_list_iter_end(&conn_iter);
+ return -EFAULT;
+ }
+ count++;
}
- count++;
}
card_res->count_connectors = count;
drm_connector_list_iter_end(&conn_iter);
diff --git a/drivers/gpu/drm/drm_mode_object.c b/drivers/gpu/drm/drm_mode_object.c
index 240a05d91a53..ef8befe34bdf 100644
--- a/drivers/gpu/drm/drm_mode_object.c
+++ b/drivers/gpu/drm/drm_mode_object.c
@@ -104,6 +104,25 @@ void drm_mode_object_unregister(struct drm_device *dev,
mutex_unlock(&dev->mode_config.idr_mutex);
}
+/**
+ * drm_lease_required - check types which must be leased to be used
+ * @type: type of object
+ *
+ * Returns whether the provided type of drm_mode_object must
+ * be owned or leased to be used by a process.
+ */
+static bool drm_lease_required(uint32_t type)
+{
+ switch(type) {
+ case DRM_MODE_OBJECT_CRTC:
+ case DRM_MODE_OBJECT_CONNECTOR:
+ case DRM_MODE_OBJECT_ENCODER:
+ return true;
+ default:
+ return false;
+ }
+}
+
struct drm_mode_object *__drm_mode_object_find(struct drm_device *dev,
struct drm_file *file_priv,
uint32_t id, uint32_t type)
@@ -117,6 +136,9 @@ struct drm_mode_object *__drm_mode_object_find(struct drm_device *dev,
if (obj && obj->id != id)
obj = NULL;
+ if (obj && drm_lease_required(obj->type) && !_drm_lease_held(file_priv, obj->id))
+ obj = NULL;
+
if (obj && obj->free_cb) {
if (!kref_get_unless_zero(&obj->refcount))
obj = NULL;
diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c
index 574fd1475214..e0bb14ad0312 100644
--- a/drivers/gpu/drm/drm_plane.c
+++ b/drivers/gpu/drm/drm_plane.c
@@ -518,9 +518,9 @@ int drm_mode_getplane(struct drm_device *dev, void *data,
return -ENOENT;
drm_modeset_lock(&plane->mutex, NULL);
- if (plane->state && plane->state->crtc)
+ if (plane->state && plane->state->crtc && drm_lease_held(file_priv, plane->state->crtc->base.id))
plane_resp->crtc_id = plane->state->crtc->base.id;
- else if (!plane->state && plane->crtc)
+ else if (!plane->state && plane->crtc && drm_lease_held(file_priv, plane->crtc->base.id))
plane_resp->crtc_id = plane->crtc->base.id;
else
plane_resp->crtc_id = 0;
@@ -534,7 +534,9 @@ int drm_mode_getplane(struct drm_device *dev, void *data,
drm_modeset_unlock(&plane->mutex);
plane_resp->plane_id = plane->base.id;
- plane_resp->possible_crtcs = plane->possible_crtcs;
+ plane_resp->possible_crtcs = drm_lease_filter_crtcs(file_priv,
+ plane->possible_crtcs);
+
plane_resp->gamma_size = 0;
/*
diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
index 45ac2efd5078..583a17a212a9 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -1459,10 +1459,12 @@ static u64 widen_32_to_64(u32 narrow, u64 near)
int drm_wait_vblank_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
+ struct drm_crtc *crtc;
struct drm_vblank_crtc *vblank;
union drm_wait_vblank *vblwait = data;
int ret;
u64 req_seq;
+ unsigned int pipe_index;
unsigned int flags, seq, pipe, high_pipe;
if (!dev->irq_enabled)
@@ -1484,9 +1486,21 @@ int drm_wait_vblank_ioctl(struct drm_device *dev, void *data,
flags = vblwait->request.type & _DRM_VBLANK_FLAGS_MASK;
high_pipe = (vblwait->request.type & _DRM_VBLANK_HIGH_CRTC_MASK);
if (high_pipe)
- pipe = high_pipe >> _DRM_VBLANK_HIGH_CRTC_SHIFT;
+ pipe_index = high_pipe >> _DRM_VBLANK_HIGH_CRTC_SHIFT;
else
- pipe = flags & _DRM_VBLANK_SECONDARY ? 1 : 0;
+ pipe_index = flags & _DRM_VBLANK_SECONDARY ? 1 : 0;
+
+ /* Convert lease-relative crtc index into global crtc index */
+ pipe = 0;
+ drm_for_each_crtc(crtc, dev) {
+ if (drm_lease_held(file_priv, crtc->base.id)) {
+ if (pipe_index == 0)
+ break;
+ pipe_index--;
+ }
+ pipe++;
+ }
+
if (pipe >= dev->num_crtcs)
return -EINVAL;
--
2.13.3
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 6/6] drm: Add four ioctls for managing drm mode object leases [v5]
2017-10-11 0:48 ` Keith Packard
@ 2017-10-11 0:48 ` Keith Packard
-1 siblings, 0 replies; 21+ messages in thread
From: Keith Packard @ 2017-10-11 0:48 UTC (permalink / raw)
To: linux-kernel, Dave Airlie, Daniel Vetter; +Cc: Keith Packard, dri-devel
drm_mode_create_lease
Creates a lease for a list of drm mode objects, returning an
fd for the new drm_master and a 64-bit identifier for the lessee
drm_mode_list_lesees
List the identifiers of the lessees for a master file
drm_mode_get_lease
List the leased objects for a master file
drm_mode_revoke_lease
Erase the set of objects managed by a lease.
This should suffice to at least create and query leases.
Changes for v2 as suggested by Daniel Vetter <daniel.vetter@ffwll.ch>:
* query ioctls only query the master associated with
the provided file.
* 'mask_lease' value has been removed
* change ioctl has been removed.
Changes for v3 suggested in part by Dave Airlie <airlied@gmail.com>
* Add revoke ioctl.
Changes for v4 suggested by Dave Airlie <airlied@gmail.com>
* Expand on the comment about the magic use of &drm_lease_idr_object
* Pad lease ioctl structures to align on 64-bit boundaries
Changes for v5 suggested by Dave Airlie <airlied@gmail.com>
* Check for non-negative object_id in create_lease to avoid debug
output from the kernel.
Signed-off-by: Keith Packard <keithp@keithp.com>
---
drivers/gpu/drm/drm_ioctl.c | 4 +
drivers/gpu/drm/drm_lease.c | 282 +++++++++++++++++++++++++++++++++++++++++++
drivers/gpu/drm/drm_vblank.c | 4 +-
include/drm/drm_lease.h | 12 ++
include/uapi/drm/drm.h | 5 +
include/uapi/drm/drm_mode.h | 66 ++++++++++
6 files changed, 371 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index 78a0d6996e12..c37dc4478d83 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -665,6 +665,10 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
DRM_UNLOCKED|DRM_RENDER_ALLOW),
DRM_IOCTL_DEF(DRM_IOCTL_CRTC_GET_SEQUENCE, drm_crtc_get_sequence_ioctl, DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_CRTC_QUEUE_SEQUENCE, drm_crtc_queue_sequence_ioctl, DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_CREATE_LEASE, drm_mode_create_lease_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_LIST_LESSEES, drm_mode_list_lessees_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_GET_LEASE, drm_mode_get_lease_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_REVOKE_LEASE, drm_mode_revoke_lease_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
};
#define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls )
diff --git a/drivers/gpu/drm/drm_lease.c b/drivers/gpu/drm/drm_lease.c
index 2ac404264d75..69b54cb557ce 100644
--- a/drivers/gpu/drm/drm_lease.c
+++ b/drivers/gpu/drm/drm_lease.c
@@ -23,6 +23,8 @@
#define drm_for_each_lessee(lessee, lessor) \
list_for_each_entry((lessee), &(lessor)->lessees, lessee_list)
+static uint64_t drm_lease_idr_object;
+
/**
* drm_lease_owner - return ancestor owner drm_master
* @master: drm_master somewhere within tree of lessees and lessors
@@ -377,3 +379,283 @@ void _drm_lease_revoke(struct drm_master *top)
}
}
}
+
+/**
+ * drm_mode_create_lease_ioctl - create a new lease
+ * @dev: the drm device
+ * @data: pointer to struct drm_mode_create_lease
+ * @file_priv: the file being manipulated
+ *
+ * The master associated with the specified file will have a lease
+ * created containing the objects specified in the ioctl structure.
+ * A file descriptor will be allocated for that and returned to the
+ * application.
+ */
+int drm_mode_create_lease_ioctl(struct drm_device *dev,
+ void *data, struct drm_file *lessor_priv)
+{
+ struct drm_mode_create_lease *cl = data;
+ size_t object_count;
+ size_t o;
+ int ret = 0;
+ struct idr leases;
+ struct drm_master *lessor = lessor_priv->master;
+ struct drm_master *lessee = NULL;
+ struct file *lessee_file = NULL;
+ struct file *lessor_file = lessor_priv->filp;
+ struct drm_file *lessee_priv;
+ int fd = -1;
+
+ /* Do not allow sub-leases */
+ if (lessor->lessor)
+ return -EINVAL;
+
+ object_count = cl->object_count;
+ idr_init(&leases);
+
+ /* Allocate a file descriptor for the lease */
+ fd = get_unused_fd_flags(cl->flags & (O_CLOEXEC | O_NONBLOCK));
+
+ DRM_DEBUG_LEASE("Creating new lease\n");
+
+ /* Lookup the mode objects and add their IDs to the lease request */
+ for (o = 0; o < object_count; o++) {
+ __u32 object_id;
+
+ if (copy_from_user(&object_id,
+ u64_to_user_ptr(cl->object_ids) + o * sizeof (__u32),
+ sizeof (__u32))) {
+ ret = -EFAULT;
+ goto out_leases;
+ }
+ DRM_DEBUG_LEASE("Adding object %d to lease\n", object_id);
+
+ if ((int) object_id < 0) {
+ ret = -EINVAL;
+ goto out_leases;
+ }
+
+ /*
+ * We're using an IDR to hold the set of leased
+ * objects, but we don't need to point at the object's
+ * data structure from the lease as the main crtc_idr
+ * will be used to actually find that. Instead, all we
+ * really want is a 'leased/not-leased' result, for
+ * which any non-NULL pointer will work fine.
+ */
+ ret = idr_alloc(&leases, &drm_lease_idr_object , object_id, object_id + 1, GFP_KERNEL);
+ if (ret < 0) {
+ DRM_DEBUG_LEASE("Object %d cannot be inserted into leases (%d)\n",
+ object_id, ret);
+ goto out_leases;
+ }
+ }
+
+ mutex_lock(&dev->master_mutex);
+
+ DRM_DEBUG_LEASE("Creating lease\n");
+ lessee = drm_lease_create(lessor, &leases);
+
+ if (IS_ERR(lessee)) {
+ ret = PTR_ERR(lessee);
+ mutex_unlock(&dev->master_mutex);
+ goto out_leases;
+ }
+
+ /* Clone the lessor file to create a new file for us */
+ DRM_DEBUG_LEASE("Allocating lease file\n");
+ path_get(&lessor_file->f_path);
+ lessee_file = alloc_file(&lessor_file->f_path,
+ lessor_file->f_mode,
+ fops_get(lessor_file->f_inode->i_fop));
+ mutex_unlock(&dev->master_mutex);
+
+ if (IS_ERR(lessee_file)) {
+ ret = PTR_ERR(lessee_file);
+ goto out_lessee;
+ }
+
+ /* Initialize the new file for DRM */
+ DRM_DEBUG_LEASE("Initializing the file with %p\n", lessee_file->f_op->open);
+ ret = lessee_file->f_op->open(lessee_file->f_inode, lessee_file);
+ if (ret)
+ goto out_lessee_file;
+
+ lessee_priv = lessee_file->private_data;
+
+ /* Change the file to a master one */
+ drm_master_put(&lessee_priv->master);
+ lessee_priv->master = lessee;
+ lessee_priv->is_master = 1;
+ lessee_priv->authenticated = 1;
+
+ /* Hook up the fd */
+ fd_install(fd, lessee_file);
+
+ /* Pass fd back to userspace */
+ DRM_DEBUG_LEASE("Returning fd %d id %d\n", fd, lessee->lessee_id);
+ cl->fd = fd;
+ cl->lessee_id = lessee->lessee_id;
+
+ DRM_DEBUG_LEASE("drm_mode_create_lease_ioctl succeeded\n");
+ return 0;
+
+out_lessee_file:
+ fput(lessee_file);
+
+out_lessee:
+ drm_master_put(&lessee);
+
+out_leases:
+ idr_destroy(&leases);
+ put_unused_fd(fd);
+
+ DRM_DEBUG_LEASE("drm_mode_create_lease_ioctl failed: %d\n", ret);
+ return ret;
+}
+
+/**
+ * drm_mode_list_lessees_ioctl - list lessee ids
+ * @dev: the drm device
+ * @data: pointer to struct drm_mode_list_lessees
+ * @lessor_priv: the file being manipulated
+ *
+ * Starting from the master associated with the specified file,
+ * the master with the provided lessee_id is found, and then
+ * an array of lessee ids associated with leases from that master
+ * are returned.
+ */
+
+int drm_mode_list_lessees_ioctl(struct drm_device *dev,
+ void *data, struct drm_file *lessor_priv)
+{
+ struct drm_mode_list_lessees *arg = data;
+ __u32 __user *lessee_ids = (__u32 __user *) (uintptr_t) (arg->lessees_ptr);
+ __u32 count_lessees = arg->count_lessees;
+ struct drm_master *lessor = lessor_priv->master, *lessee;
+ int count;
+ int ret = 0;
+
+ DRM_DEBUG_LEASE("List lessees for %d\n", lessor->lessee_id);
+
+ mutex_lock(&dev->master_mutex);
+
+ count = 0;
+ drm_for_each_lessee(lessee, lessor) {
+ /* Only list un-revoked leases */
+ if (!idr_is_empty(&lessee->leases)) {
+ if (count_lessees > count) {
+ DRM_DEBUG_LEASE("Add lessee %d\n", lessee->lessee_id);
+ ret = put_user(lessee->lessee_id, lessee_ids + count);
+ if (ret)
+ break;
+ }
+ count++;
+ }
+ }
+
+ DRM_DEBUG_LEASE("Lessor leases to %d\n", count);
+ if (ret == 0)
+ arg->count_lessees = count;
+
+ mutex_unlock(&dev->master_mutex);
+
+ return ret;
+}
+
+/**
+ * drm_mode_get_lease_ioctl - list leased objects
+ * @dev: the drm device
+ * @data: pointer to struct drm_mode_get_lease
+ * @file_priv: the file being manipulated
+ *
+ * Return the list of leased objects for the specified lessee
+ */
+
+int drm_mode_get_lease_ioctl(struct drm_device *dev,
+ void *data, struct drm_file *lessee_priv)
+{
+ struct drm_mode_get_lease *arg = data;
+ __u32 __user *object_ids = (__u32 __user *) (uintptr_t) (arg->objects_ptr);
+ __u32 count_objects = arg->count_objects;
+ struct drm_master *lessee = lessee_priv->master;
+ struct idr *object_idr;
+ int count;
+ void *entry;
+ int object;
+ int ret = 0;
+
+ DRM_DEBUG_LEASE("get lease for %d\n", lessee->lessee_id);
+
+ mutex_lock(&dev->master_mutex);
+
+ if (lessee->lessor == NULL)
+ /* owner can use all objects */
+ object_idr = &lessee->dev->mode_config.crtc_idr;
+ else
+ /* lessee can only use allowed object */
+ object_idr = &lessee->leases;
+
+ count = 0;
+ idr_for_each_entry(object_idr, entry, object) {
+ if (count_objects > count) {
+ DRM_DEBUG_LEASE("adding object %d\n", object);
+ ret = put_user(object, object_ids + count);
+ if (ret)
+ break;
+ }
+ count++;
+ }
+
+ DRM_DEBUG("lease holds %d objects\n", count);
+ if (ret == 0)
+ arg->count_objects = count;
+
+ mutex_unlock(&dev->master_mutex);
+
+ return ret;
+}
+
+/**
+ * drm_mode_revoke_lease_ioctl - revoke lease
+ * @dev: the drm device
+ * @data: pointer to struct drm_mode_revoke_lease
+ * @file_priv: the file being manipulated
+ *
+ * This removes all of the objects from the lease without
+ * actually getting rid of the lease itself; that way all
+ * references to it still work correctly
+ */
+int drm_mode_revoke_lease_ioctl(struct drm_device *dev,
+ void *data, struct drm_file *lessor_priv)
+{
+ struct drm_mode_revoke_lease *arg = data;
+ struct drm_master *lessor = lessor_priv->master;
+ struct drm_master *lessee;
+ int ret = 0;
+
+ DRM_DEBUG_LEASE("revoke lease for %d\n", arg->lessee_id);
+
+ mutex_lock(&dev->master_mutex);
+
+ lessee = _drm_find_lessee(lessor, arg->lessee_id);
+
+ /* No such lessee */
+ if (!lessee) {
+ ret = -ENOENT;
+ goto fail;
+ }
+
+ /* Lease is not held by lessor */
+ if (lessee->lessor != lessor) {
+ ret = -EACCES;
+ goto fail;
+ }
+
+ _drm_lease_revoke(lessee);
+
+fail:
+ mutex_unlock(&dev->master_mutex);
+
+ return ret;
+}
diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
index 583a17a212a9..4f3af22b1181 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -1720,7 +1720,7 @@ int drm_crtc_get_sequence_ioctl(struct drm_device *dev, void *data,
if (!dev->irq_enabled)
return -EINVAL;
- crtc = drm_crtc_find(dev, get_seq->crtc_id);
+ crtc = drm_crtc_find(dev, file_priv, get_seq->crtc_id);
if (!crtc)
return -ENOENT;
@@ -1778,7 +1778,7 @@ int drm_crtc_queue_sequence_ioctl(struct drm_device *dev, void *data,
if (!dev->irq_enabled)
return -EINVAL;
- crtc = drm_crtc_find(dev, queue_seq->crtc_id);
+ crtc = drm_crtc_find(dev, file_priv, queue_seq->crtc_id);
if (!crtc)
return -ENOENT;
diff --git a/include/drm/drm_lease.h b/include/drm/drm_lease.h
index a49667db1d6d..53ffcee2617e 100644
--- a/include/drm/drm_lease.h
+++ b/include/drm/drm_lease.h
@@ -33,4 +33,16 @@ uint32_t drm_lease_filter_crtcs(struct drm_file *file_priv, uint32_t crtcs);
uint32_t drm_lease_filter_encoders(struct drm_file *file_priv, uint32_t encoders);
+int drm_mode_create_lease_ioctl(struct drm_device *dev,
+ void *data, struct drm_file *file_priv);
+
+int drm_mode_list_lessees_ioctl(struct drm_device *dev,
+ void *data, struct drm_file *file_priv);
+
+int drm_mode_get_lease_ioctl(struct drm_device *dev,
+ void *data, struct drm_file *file_priv);
+
+int drm_mode_revoke_lease_ioctl(struct drm_device *dev,
+ void *data, struct drm_file *file_priv);
+
#endif /* _DRM_LEASE_H_ */
diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h
index a106f6a7a0f9..9c02d2125d07 100644
--- a/include/uapi/drm/drm.h
+++ b/include/uapi/drm/drm.h
@@ -888,6 +888,11 @@ extern "C" {
#define DRM_IOCTL_SYNCOBJ_RESET DRM_IOWR(0xC4, struct drm_syncobj_array)
#define DRM_IOCTL_SYNCOBJ_SIGNAL DRM_IOWR(0xC5, struct drm_syncobj_array)
+#define DRM_IOCTL_MODE_CREATE_LEASE DRM_IOWR(0xC6, struct drm_mode_create_lease)
+#define DRM_IOCTL_MODE_LIST_LESSEES DRM_IOWR(0xC7, struct drm_mode_list_lessees)
+#define DRM_IOCTL_MODE_GET_LEASE DRM_IOWR(0xC8, struct drm_mode_get_lease)
+#define DRM_IOCTL_MODE_REVOKE_LEASE DRM_IOWR(0xC9, struct drm_mode_revoke_lease)
+
/**
* Device specific ioctls should only be in their respective headers
* The device specific ioctl range is from 0x40 to 0x9f.
diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
index 34b6bb34b002..5597a87154e5 100644
--- a/include/uapi/drm/drm_mode.h
+++ b/include/uapi/drm/drm_mode.h
@@ -782,6 +782,72 @@ struct drm_mode_destroy_blob {
__u32 blob_id;
};
+/**
+ * Lease mode resources, creating another drm_master.
+ */
+struct drm_mode_create_lease {
+ /** Pointer to array of object ids (__u32) */
+ __u64 object_ids;
+ /** Number of object ids */
+ __u32 object_count;
+ /** flags for new FD (O_CLOEXEC, etc) */
+ __u32 flags;
+
+ /** Return: unique identifier for lessee. */
+ __u32 lessee_id;
+ /** Return: file descriptor to new drm_master file */
+ __u32 fd;
+};
+
+/**
+ * List lesses from a drm_master
+ */
+struct drm_mode_list_lessees {
+ /** Number of lessees.
+ * On input, provides length of the array.
+ * On output, provides total number. No
+ * more than the input number will be written
+ * back, so two calls can be used to get
+ * the size and then the data.
+ */
+ __u32 count_lessees;
+ __u32 pad;
+
+ /** Pointer to lessees.
+ * pointer to __u64 array of lessee ids
+ */
+ __u64 lessees_ptr;
+};
+
+/**
+ * Get leased objects
+ */
+struct drm_mode_get_lease {
+ /** Number of leased objects.
+ * On input, provides length of the array.
+ * On output, provides total number. No
+ * more than the input number will be written
+ * back, so two calls can be used to get
+ * the size and then the data.
+ */
+ __u32 count_objects;
+ __u32 pad;
+
+ /** Pointer to objects.
+ * pointer to __u32 array of object ids
+ */
+ __u64 objects_ptr;
+};
+
+/**
+ * Revoke lease
+ */
+struct drm_mode_revoke_lease {
+ /** Unique ID of lessee
+ */
+ __u32 lessee_id;
+};
+
#if defined(__cplusplus)
}
#endif
--
2.13.3
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 6/6] drm: Add four ioctls for managing drm mode object leases [v5]
@ 2017-10-11 0:48 ` Keith Packard
0 siblings, 0 replies; 21+ messages in thread
From: Keith Packard @ 2017-10-11 0:48 UTC (permalink / raw)
To: linux-kernel, Dave Airlie, Daniel Vetter; +Cc: Keith Packard, dri-devel
drm_mode_create_lease
Creates a lease for a list of drm mode objects, returning an
fd for the new drm_master and a 64-bit identifier for the lessee
drm_mode_list_lesees
List the identifiers of the lessees for a master file
drm_mode_get_lease
List the leased objects for a master file
drm_mode_revoke_lease
Erase the set of objects managed by a lease.
This should suffice to at least create and query leases.
Changes for v2 as suggested by Daniel Vetter <daniel.vetter@ffwll.ch>:
* query ioctls only query the master associated with
the provided file.
* 'mask_lease' value has been removed
* change ioctl has been removed.
Changes for v3 suggested in part by Dave Airlie <airlied@gmail.com>
* Add revoke ioctl.
Changes for v4 suggested by Dave Airlie <airlied@gmail.com>
* Expand on the comment about the magic use of &drm_lease_idr_object
* Pad lease ioctl structures to align on 64-bit boundaries
Changes for v5 suggested by Dave Airlie <airlied@gmail.com>
* Check for non-negative object_id in create_lease to avoid debug
output from the kernel.
Signed-off-by: Keith Packard <keithp@keithp.com>
---
drivers/gpu/drm/drm_ioctl.c | 4 +
drivers/gpu/drm/drm_lease.c | 282 +++++++++++++++++++++++++++++++++++++++++++
drivers/gpu/drm/drm_vblank.c | 4 +-
include/drm/drm_lease.h | 12 ++
include/uapi/drm/drm.h | 5 +
include/uapi/drm/drm_mode.h | 66 ++++++++++
6 files changed, 371 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index 78a0d6996e12..c37dc4478d83 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -665,6 +665,10 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
DRM_UNLOCKED|DRM_RENDER_ALLOW),
DRM_IOCTL_DEF(DRM_IOCTL_CRTC_GET_SEQUENCE, drm_crtc_get_sequence_ioctl, DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_CRTC_QUEUE_SEQUENCE, drm_crtc_queue_sequence_ioctl, DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_CREATE_LEASE, drm_mode_create_lease_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_LIST_LESSEES, drm_mode_list_lessees_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_GET_LEASE, drm_mode_get_lease_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_REVOKE_LEASE, drm_mode_revoke_lease_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
};
#define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls )
diff --git a/drivers/gpu/drm/drm_lease.c b/drivers/gpu/drm/drm_lease.c
index 2ac404264d75..69b54cb557ce 100644
--- a/drivers/gpu/drm/drm_lease.c
+++ b/drivers/gpu/drm/drm_lease.c
@@ -23,6 +23,8 @@
#define drm_for_each_lessee(lessee, lessor) \
list_for_each_entry((lessee), &(lessor)->lessees, lessee_list)
+static uint64_t drm_lease_idr_object;
+
/**
* drm_lease_owner - return ancestor owner drm_master
* @master: drm_master somewhere within tree of lessees and lessors
@@ -377,3 +379,283 @@ void _drm_lease_revoke(struct drm_master *top)
}
}
}
+
+/**
+ * drm_mode_create_lease_ioctl - create a new lease
+ * @dev: the drm device
+ * @data: pointer to struct drm_mode_create_lease
+ * @file_priv: the file being manipulated
+ *
+ * The master associated with the specified file will have a lease
+ * created containing the objects specified in the ioctl structure.
+ * A file descriptor will be allocated for that and returned to the
+ * application.
+ */
+int drm_mode_create_lease_ioctl(struct drm_device *dev,
+ void *data, struct drm_file *lessor_priv)
+{
+ struct drm_mode_create_lease *cl = data;
+ size_t object_count;
+ size_t o;
+ int ret = 0;
+ struct idr leases;
+ struct drm_master *lessor = lessor_priv->master;
+ struct drm_master *lessee = NULL;
+ struct file *lessee_file = NULL;
+ struct file *lessor_file = lessor_priv->filp;
+ struct drm_file *lessee_priv;
+ int fd = -1;
+
+ /* Do not allow sub-leases */
+ if (lessor->lessor)
+ return -EINVAL;
+
+ object_count = cl->object_count;
+ idr_init(&leases);
+
+ /* Allocate a file descriptor for the lease */
+ fd = get_unused_fd_flags(cl->flags & (O_CLOEXEC | O_NONBLOCK));
+
+ DRM_DEBUG_LEASE("Creating new lease\n");
+
+ /* Lookup the mode objects and add their IDs to the lease request */
+ for (o = 0; o < object_count; o++) {
+ __u32 object_id;
+
+ if (copy_from_user(&object_id,
+ u64_to_user_ptr(cl->object_ids) + o * sizeof (__u32),
+ sizeof (__u32))) {
+ ret = -EFAULT;
+ goto out_leases;
+ }
+ DRM_DEBUG_LEASE("Adding object %d to lease\n", object_id);
+
+ if ((int) object_id < 0) {
+ ret = -EINVAL;
+ goto out_leases;
+ }
+
+ /*
+ * We're using an IDR to hold the set of leased
+ * objects, but we don't need to point at the object's
+ * data structure from the lease as the main crtc_idr
+ * will be used to actually find that. Instead, all we
+ * really want is a 'leased/not-leased' result, for
+ * which any non-NULL pointer will work fine.
+ */
+ ret = idr_alloc(&leases, &drm_lease_idr_object , object_id, object_id + 1, GFP_KERNEL);
+ if (ret < 0) {
+ DRM_DEBUG_LEASE("Object %d cannot be inserted into leases (%d)\n",
+ object_id, ret);
+ goto out_leases;
+ }
+ }
+
+ mutex_lock(&dev->master_mutex);
+
+ DRM_DEBUG_LEASE("Creating lease\n");
+ lessee = drm_lease_create(lessor, &leases);
+
+ if (IS_ERR(lessee)) {
+ ret = PTR_ERR(lessee);
+ mutex_unlock(&dev->master_mutex);
+ goto out_leases;
+ }
+
+ /* Clone the lessor file to create a new file for us */
+ DRM_DEBUG_LEASE("Allocating lease file\n");
+ path_get(&lessor_file->f_path);
+ lessee_file = alloc_file(&lessor_file->f_path,
+ lessor_file->f_mode,
+ fops_get(lessor_file->f_inode->i_fop));
+ mutex_unlock(&dev->master_mutex);
+
+ if (IS_ERR(lessee_file)) {
+ ret = PTR_ERR(lessee_file);
+ goto out_lessee;
+ }
+
+ /* Initialize the new file for DRM */
+ DRM_DEBUG_LEASE("Initializing the file with %p\n", lessee_file->f_op->open);
+ ret = lessee_file->f_op->open(lessee_file->f_inode, lessee_file);
+ if (ret)
+ goto out_lessee_file;
+
+ lessee_priv = lessee_file->private_data;
+
+ /* Change the file to a master one */
+ drm_master_put(&lessee_priv->master);
+ lessee_priv->master = lessee;
+ lessee_priv->is_master = 1;
+ lessee_priv->authenticated = 1;
+
+ /* Hook up the fd */
+ fd_install(fd, lessee_file);
+
+ /* Pass fd back to userspace */
+ DRM_DEBUG_LEASE("Returning fd %d id %d\n", fd, lessee->lessee_id);
+ cl->fd = fd;
+ cl->lessee_id = lessee->lessee_id;
+
+ DRM_DEBUG_LEASE("drm_mode_create_lease_ioctl succeeded\n");
+ return 0;
+
+out_lessee_file:
+ fput(lessee_file);
+
+out_lessee:
+ drm_master_put(&lessee);
+
+out_leases:
+ idr_destroy(&leases);
+ put_unused_fd(fd);
+
+ DRM_DEBUG_LEASE("drm_mode_create_lease_ioctl failed: %d\n", ret);
+ return ret;
+}
+
+/**
+ * drm_mode_list_lessees_ioctl - list lessee ids
+ * @dev: the drm device
+ * @data: pointer to struct drm_mode_list_lessees
+ * @lessor_priv: the file being manipulated
+ *
+ * Starting from the master associated with the specified file,
+ * the master with the provided lessee_id is found, and then
+ * an array of lessee ids associated with leases from that master
+ * are returned.
+ */
+
+int drm_mode_list_lessees_ioctl(struct drm_device *dev,
+ void *data, struct drm_file *lessor_priv)
+{
+ struct drm_mode_list_lessees *arg = data;
+ __u32 __user *lessee_ids = (__u32 __user *) (uintptr_t) (arg->lessees_ptr);
+ __u32 count_lessees = arg->count_lessees;
+ struct drm_master *lessor = lessor_priv->master, *lessee;
+ int count;
+ int ret = 0;
+
+ DRM_DEBUG_LEASE("List lessees for %d\n", lessor->lessee_id);
+
+ mutex_lock(&dev->master_mutex);
+
+ count = 0;
+ drm_for_each_lessee(lessee, lessor) {
+ /* Only list un-revoked leases */
+ if (!idr_is_empty(&lessee->leases)) {
+ if (count_lessees > count) {
+ DRM_DEBUG_LEASE("Add lessee %d\n", lessee->lessee_id);
+ ret = put_user(lessee->lessee_id, lessee_ids + count);
+ if (ret)
+ break;
+ }
+ count++;
+ }
+ }
+
+ DRM_DEBUG_LEASE("Lessor leases to %d\n", count);
+ if (ret == 0)
+ arg->count_lessees = count;
+
+ mutex_unlock(&dev->master_mutex);
+
+ return ret;
+}
+
+/**
+ * drm_mode_get_lease_ioctl - list leased objects
+ * @dev: the drm device
+ * @data: pointer to struct drm_mode_get_lease
+ * @file_priv: the file being manipulated
+ *
+ * Return the list of leased objects for the specified lessee
+ */
+
+int drm_mode_get_lease_ioctl(struct drm_device *dev,
+ void *data, struct drm_file *lessee_priv)
+{
+ struct drm_mode_get_lease *arg = data;
+ __u32 __user *object_ids = (__u32 __user *) (uintptr_t) (arg->objects_ptr);
+ __u32 count_objects = arg->count_objects;
+ struct drm_master *lessee = lessee_priv->master;
+ struct idr *object_idr;
+ int count;
+ void *entry;
+ int object;
+ int ret = 0;
+
+ DRM_DEBUG_LEASE("get lease for %d\n", lessee->lessee_id);
+
+ mutex_lock(&dev->master_mutex);
+
+ if (lessee->lessor == NULL)
+ /* owner can use all objects */
+ object_idr = &lessee->dev->mode_config.crtc_idr;
+ else
+ /* lessee can only use allowed object */
+ object_idr = &lessee->leases;
+
+ count = 0;
+ idr_for_each_entry(object_idr, entry, object) {
+ if (count_objects > count) {
+ DRM_DEBUG_LEASE("adding object %d\n", object);
+ ret = put_user(object, object_ids + count);
+ if (ret)
+ break;
+ }
+ count++;
+ }
+
+ DRM_DEBUG("lease holds %d objects\n", count);
+ if (ret == 0)
+ arg->count_objects = count;
+
+ mutex_unlock(&dev->master_mutex);
+
+ return ret;
+}
+
+/**
+ * drm_mode_revoke_lease_ioctl - revoke lease
+ * @dev: the drm device
+ * @data: pointer to struct drm_mode_revoke_lease
+ * @file_priv: the file being manipulated
+ *
+ * This removes all of the objects from the lease without
+ * actually getting rid of the lease itself; that way all
+ * references to it still work correctly
+ */
+int drm_mode_revoke_lease_ioctl(struct drm_device *dev,
+ void *data, struct drm_file *lessor_priv)
+{
+ struct drm_mode_revoke_lease *arg = data;
+ struct drm_master *lessor = lessor_priv->master;
+ struct drm_master *lessee;
+ int ret = 0;
+
+ DRM_DEBUG_LEASE("revoke lease for %d\n", arg->lessee_id);
+
+ mutex_lock(&dev->master_mutex);
+
+ lessee = _drm_find_lessee(lessor, arg->lessee_id);
+
+ /* No such lessee */
+ if (!lessee) {
+ ret = -ENOENT;
+ goto fail;
+ }
+
+ /* Lease is not held by lessor */
+ if (lessee->lessor != lessor) {
+ ret = -EACCES;
+ goto fail;
+ }
+
+ _drm_lease_revoke(lessee);
+
+fail:
+ mutex_unlock(&dev->master_mutex);
+
+ return ret;
+}
diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
index 583a17a212a9..4f3af22b1181 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -1720,7 +1720,7 @@ int drm_crtc_get_sequence_ioctl(struct drm_device *dev, void *data,
if (!dev->irq_enabled)
return -EINVAL;
- crtc = drm_crtc_find(dev, get_seq->crtc_id);
+ crtc = drm_crtc_find(dev, file_priv, get_seq->crtc_id);
if (!crtc)
return -ENOENT;
@@ -1778,7 +1778,7 @@ int drm_crtc_queue_sequence_ioctl(struct drm_device *dev, void *data,
if (!dev->irq_enabled)
return -EINVAL;
- crtc = drm_crtc_find(dev, queue_seq->crtc_id);
+ crtc = drm_crtc_find(dev, file_priv, queue_seq->crtc_id);
if (!crtc)
return -ENOENT;
diff --git a/include/drm/drm_lease.h b/include/drm/drm_lease.h
index a49667db1d6d..53ffcee2617e 100644
--- a/include/drm/drm_lease.h
+++ b/include/drm/drm_lease.h
@@ -33,4 +33,16 @@ uint32_t drm_lease_filter_crtcs(struct drm_file *file_priv, uint32_t crtcs);
uint32_t drm_lease_filter_encoders(struct drm_file *file_priv, uint32_t encoders);
+int drm_mode_create_lease_ioctl(struct drm_device *dev,
+ void *data, struct drm_file *file_priv);
+
+int drm_mode_list_lessees_ioctl(struct drm_device *dev,
+ void *data, struct drm_file *file_priv);
+
+int drm_mode_get_lease_ioctl(struct drm_device *dev,
+ void *data, struct drm_file *file_priv);
+
+int drm_mode_revoke_lease_ioctl(struct drm_device *dev,
+ void *data, struct drm_file *file_priv);
+
#endif /* _DRM_LEASE_H_ */
diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h
index a106f6a7a0f9..9c02d2125d07 100644
--- a/include/uapi/drm/drm.h
+++ b/include/uapi/drm/drm.h
@@ -888,6 +888,11 @@ extern "C" {
#define DRM_IOCTL_SYNCOBJ_RESET DRM_IOWR(0xC4, struct drm_syncobj_array)
#define DRM_IOCTL_SYNCOBJ_SIGNAL DRM_IOWR(0xC5, struct drm_syncobj_array)
+#define DRM_IOCTL_MODE_CREATE_LEASE DRM_IOWR(0xC6, struct drm_mode_create_lease)
+#define DRM_IOCTL_MODE_LIST_LESSEES DRM_IOWR(0xC7, struct drm_mode_list_lessees)
+#define DRM_IOCTL_MODE_GET_LEASE DRM_IOWR(0xC8, struct drm_mode_get_lease)
+#define DRM_IOCTL_MODE_REVOKE_LEASE DRM_IOWR(0xC9, struct drm_mode_revoke_lease)
+
/**
* Device specific ioctls should only be in their respective headers
* The device specific ioctl range is from 0x40 to 0x9f.
diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
index 34b6bb34b002..5597a87154e5 100644
--- a/include/uapi/drm/drm_mode.h
+++ b/include/uapi/drm/drm_mode.h
@@ -782,6 +782,72 @@ struct drm_mode_destroy_blob {
__u32 blob_id;
};
+/**
+ * Lease mode resources, creating another drm_master.
+ */
+struct drm_mode_create_lease {
+ /** Pointer to array of object ids (__u32) */
+ __u64 object_ids;
+ /** Number of object ids */
+ __u32 object_count;
+ /** flags for new FD (O_CLOEXEC, etc) */
+ __u32 flags;
+
+ /** Return: unique identifier for lessee. */
+ __u32 lessee_id;
+ /** Return: file descriptor to new drm_master file */
+ __u32 fd;
+};
+
+/**
+ * List lesses from a drm_master
+ */
+struct drm_mode_list_lessees {
+ /** Number of lessees.
+ * On input, provides length of the array.
+ * On output, provides total number. No
+ * more than the input number will be written
+ * back, so two calls can be used to get
+ * the size and then the data.
+ */
+ __u32 count_lessees;
+ __u32 pad;
+
+ /** Pointer to lessees.
+ * pointer to __u64 array of lessee ids
+ */
+ __u64 lessees_ptr;
+};
+
+/**
+ * Get leased objects
+ */
+struct drm_mode_get_lease {
+ /** Number of leased objects.
+ * On input, provides length of the array.
+ * On output, provides total number. No
+ * more than the input number will be written
+ * back, so two calls can be used to get
+ * the size and then the data.
+ */
+ __u32 count_objects;
+ __u32 pad;
+
+ /** Pointer to objects.
+ * pointer to __u32 array of object ids
+ */
+ __u64 objects_ptr;
+};
+
+/**
+ * Revoke lease
+ */
+struct drm_mode_revoke_lease {
+ /** Unique ID of lessee
+ */
+ __u32 lessee_id;
+};
+
#if defined(__cplusplus)
}
#endif
--
2.13.3
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply related [flat|nested] 21+ messages in thread