All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/6] drm: Add mode object leases [v3]
@ 2017-07-05 22:24 ` Keith Packard
  0 siblings, 0 replies; 26+ messages in thread
From: Keith Packard @ 2017-07-05 22:24 UTC (permalink / raw)
  To: linux-kernel, Dave Airlie, Daniel Vetter; +Cc: Keith Packard, dri-devel

Here's a third version of my DRM mode object leases series. Since v2:

    * 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.
    
    * Allow non-master files to look at all DRM mode objects. This
      lets the Vulkan code provide information about the display
      environment before the lease is created.

    * Free the leases IDR when the master is destroyed. Just a bug fix.
    
    * _drm_lease_held should look at lessees, not lessor. Just a bug fix.
    
I've also rebased it to a more recent version of Dave's drm-next
branch.

With this and my CRTC-id based vblank series (posted separately), I'm
now running "real" applications on a leased output and can fully
support the following Vulkan extensions:

	EXT_direct_mode_display
	EXT_acquire_xlib_display
	EXT_display_surface_counter
	KEITHP_kms_display

-keith

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 0/6] drm: Add mode object leases [v3]
@ 2017-07-05 22:24 ` Keith Packard
  0 siblings, 0 replies; 26+ messages in thread
From: Keith Packard @ 2017-07-05 22:24 UTC (permalink / raw)
  To: linux-kernel, Dave Airlie, Daniel Vetter; +Cc: Keith Packard, dri-devel

Here's a third version of my DRM mode object leases series. Since v2:

    * 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.
    
    * Allow non-master files to look at all DRM mode objects. This
      lets the Vulkan code provide information about the display
      environment before the lease is created.

    * Free the leases IDR when the master is destroyed. Just a bug fix.
    
    * _drm_lease_held should look at lessees, not lessor. Just a bug fix.
    
I've also rebased it to a more recent version of Dave's drm-next
branch.

With this and my CRTC-id based vblank series (posted separately), I'm
now running "real" applications on a leased output and can fully
support the following Vulkan extensions:

	EXT_direct_mode_display
	EXT_acquire_xlib_display
	EXT_display_surface_counter
	KEITHP_kms_display

-keith

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 1/6] drm: Pass struct drm_file * to  __drm_mode_object_find
  2017-07-05 22:24 ` Keith Packard
@ 2017-07-05 22:24   ` Keith Packard
  -1 siblings, 0 replies; 26+ messages in thread
From: Keith Packard @ 2017-07-05 22:24 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.

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 +-
 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 ++-
 36 files changed, 84 insertions(+), 72 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
index 8d1cf2d3e663..a6c17353e57d 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;
@@ -374,7 +374,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;
 }
 
@@ -1079,7 +1079,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;
 
@@ -1136,7 +1136,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;
 
@@ -1155,7 +1155,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;
 }
 
@@ -1296,7 +1296,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;
@@ -1325,7 +1325,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 90bb08309a53..16dc8bf17a43 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
@@ -367,7 +367,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;
 
@@ -377,7 +377,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 aaef0a652f10..a1f1be9cf3d2 100644
--- a/drivers/gpu/drm/ast/ast_mode.c
+++ b/drivers/gpu/drm/ast/ast_mode.c
@@ -711,7 +711,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 53f6f0f84206..74d63b874443 100644
--- a/drivers/gpu/drm/cirrus/cirrus_mode.c
+++ b/drivers/gpu/drm/cirrus/cirrus_mode.c
@@ -496,7 +496,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 c0f336d23f9c..cf349f37dcb2 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -747,7 +747,7 @@ 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);
@@ -763,7 +763,7 @@ 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);
@@ -1143,7 +1143,7 @@ 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
@@ -2221,7 +2221,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 93b0221d5d0f..90cde25b39cd 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -3145,7 +3145,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 3eda500fc005..290ef3ebb84e 100644
--- a/drivers/gpu/drm/drm_color_mgmt.c
+++ b/drivers/gpu/drm/drm_color_mgmt.c
@@ -227,7 +227,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;
 
@@ -305,7 +305,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 5cd61aff7857..cd3c106dc5e2 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -1289,7 +1289,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 5af25ce5bf7c..5dd2d28dd221 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 d077c5490041..140752f13bc1 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 fc8ef42203ec..712c2a5ba468 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 da9a9adbcc98..ccc3a35d2de2 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);
@@ -347,7 +349,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;
@@ -395,7 +397,7 @@ int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,
 
 	drm_modeset_lock_all(dev);
 
-	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) {
 		ret = -ENOENT;
 		goto out;
diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c
index 5dc8c4350602..462c244498e2 100644
--- a/drivers/gpu/drm/drm_plane.c
+++ b/drivers/gpu/drm/drm_plane.c
@@ -395,7 +395,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;
 
@@ -584,7 +584,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);
@@ -592,14 +592,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_DEBUG_KMS("Unknown crtc ID %d\n",
 				      plane_req->crtc_id);
@@ -709,7 +709,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;
@@ -823,7 +823,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;
 
@@ -884,7 +884,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 00e6832a8c1a..b9bce1aed4d9 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 3e88fa24eab3..ee88198cac92 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;
@@ -874,7 +874,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 12a18557c5fd..ffb7a731572e 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 92cfcae7b3d8..472a02524231 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -14027,7 +14027,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 2e0c56ed22bb..074da645e74c 100644
--- a/drivers/gpu/drm/i915/intel_overlay.c
+++ b/drivers/gpu/drm/i915/intel_overlay.c
@@ -1128,7 +1128,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 c4bf19364e49..a80788e72602 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -974,7 +974,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 adb411a078e8..f7cefb9d1f38 100644
--- a/drivers/gpu/drm/mgag200/mgag200_mode.c
+++ b/drivers/gpu/drm/mgag200/mgag200_mode.c
@@ -1695,7 +1695,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 f802bcd94457..81308a477941 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 27affbde058c..5d4b6d46575e 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;
 }
 
@@ -1365,7 +1365,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;
@@ -1451,7 +1451,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;
 
@@ -1470,7 +1470,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;
 }
 
@@ -1617,7 +1617,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;
 
@@ -1646,7 +1646,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 d2f57c52f7db..59de243e5ffc 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 a8876b070168..8a74db2a40d5 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -1811,7 +1811,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/include/drm/drm_connector.h b/include/drm/drm_connector.h
index ae5b7dc316c8..7bb173f49087 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -903,10 +903,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 629a5fe075b3..a9c1d0ee35c2 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -951,10 +951,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 5244f059d23a..a7719e0029bd 100644
--- a/include/drm/drm_framebuffer.h
+++ b/include/drm/drm_framebuffer.h
@@ -198,6 +198,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 9ab3e7044812..4a7c93b00e4f 100644
--- a/include/drm/drm_plane.h
+++ b/include/drm/drm_plane.h
@@ -571,10 +571,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 619868dc08d8..5dd5b82855b3 100644
--- a/include/drm/drm_property.h
+++ b/include/drm/drm_property.h
@@ -310,10 +310,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.11.0

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 1/6] drm: Pass struct drm_file * to  __drm_mode_object_find
@ 2017-07-05 22:24   ` Keith Packard
  0 siblings, 0 replies; 26+ messages in thread
From: Keith Packard @ 2017-07-05 22:24 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.

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 +-
 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 ++-
 36 files changed, 84 insertions(+), 72 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
index 8d1cf2d3e663..a6c17353e57d 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;
@@ -374,7 +374,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;
 }
 
@@ -1079,7 +1079,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;
 
@@ -1136,7 +1136,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;
 
@@ -1155,7 +1155,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;
 }
 
@@ -1296,7 +1296,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;
@@ -1325,7 +1325,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 90bb08309a53..16dc8bf17a43 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
@@ -367,7 +367,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;
 
@@ -377,7 +377,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 aaef0a652f10..a1f1be9cf3d2 100644
--- a/drivers/gpu/drm/ast/ast_mode.c
+++ b/drivers/gpu/drm/ast/ast_mode.c
@@ -711,7 +711,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 53f6f0f84206..74d63b874443 100644
--- a/drivers/gpu/drm/cirrus/cirrus_mode.c
+++ b/drivers/gpu/drm/cirrus/cirrus_mode.c
@@ -496,7 +496,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 c0f336d23f9c..cf349f37dcb2 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -747,7 +747,7 @@ 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);
@@ -763,7 +763,7 @@ 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);
@@ -1143,7 +1143,7 @@ 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
@@ -2221,7 +2221,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 93b0221d5d0f..90cde25b39cd 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -3145,7 +3145,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 3eda500fc005..290ef3ebb84e 100644
--- a/drivers/gpu/drm/drm_color_mgmt.c
+++ b/drivers/gpu/drm/drm_color_mgmt.c
@@ -227,7 +227,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;
 
@@ -305,7 +305,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 5cd61aff7857..cd3c106dc5e2 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -1289,7 +1289,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 5af25ce5bf7c..5dd2d28dd221 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 d077c5490041..140752f13bc1 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 fc8ef42203ec..712c2a5ba468 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 da9a9adbcc98..ccc3a35d2de2 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);
@@ -347,7 +349,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;
@@ -395,7 +397,7 @@ int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,
 
 	drm_modeset_lock_all(dev);
 
-	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) {
 		ret = -ENOENT;
 		goto out;
diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c
index 5dc8c4350602..462c244498e2 100644
--- a/drivers/gpu/drm/drm_plane.c
+++ b/drivers/gpu/drm/drm_plane.c
@@ -395,7 +395,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;
 
@@ -584,7 +584,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);
@@ -592,14 +592,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_DEBUG_KMS("Unknown crtc ID %d\n",
 				      plane_req->crtc_id);
@@ -709,7 +709,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;
@@ -823,7 +823,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;
 
@@ -884,7 +884,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 00e6832a8c1a..b9bce1aed4d9 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 3e88fa24eab3..ee88198cac92 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;
@@ -874,7 +874,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 12a18557c5fd..ffb7a731572e 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 92cfcae7b3d8..472a02524231 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -14027,7 +14027,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 2e0c56ed22bb..074da645e74c 100644
--- a/drivers/gpu/drm/i915/intel_overlay.c
+++ b/drivers/gpu/drm/i915/intel_overlay.c
@@ -1128,7 +1128,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 c4bf19364e49..a80788e72602 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -974,7 +974,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 adb411a078e8..f7cefb9d1f38 100644
--- a/drivers/gpu/drm/mgag200/mgag200_mode.c
+++ b/drivers/gpu/drm/mgag200/mgag200_mode.c
@@ -1695,7 +1695,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 f802bcd94457..81308a477941 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 27affbde058c..5d4b6d46575e 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;
 }
 
@@ -1365,7 +1365,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;
@@ -1451,7 +1451,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;
 
@@ -1470,7 +1470,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;
 }
 
@@ -1617,7 +1617,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;
 
@@ -1646,7 +1646,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 d2f57c52f7db..59de243e5ffc 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 a8876b070168..8a74db2a40d5 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -1811,7 +1811,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/include/drm/drm_connector.h b/include/drm/drm_connector.h
index ae5b7dc316c8..7bb173f49087 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -903,10 +903,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 629a5fe075b3..a9c1d0ee35c2 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -951,10 +951,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 5244f059d23a..a7719e0029bd 100644
--- a/include/drm/drm_framebuffer.h
+++ b/include/drm/drm_framebuffer.h
@@ -198,6 +198,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 9ab3e7044812..4a7c93b00e4f 100644
--- a/include/drm/drm_plane.h
+++ b/include/drm/drm_plane.h
@@ -571,10 +571,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 619868dc08d8..5dd5b82855b3 100644
--- a/include/drm/drm_property.h
+++ b/include/drm/drm_property.h
@@ -310,10 +310,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.11.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 2/6] drm: Allow render nodes to query display objects
  2017-07-05 22:24 ` Keith Packard
@ 2017-07-05 22:24   ` Keith Packard
  -1 siblings, 0 replies; 26+ messages in thread
From: Keith Packard @ 2017-07-05 22:24 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 f1e568176da9..a5a259964c7d 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.11.0

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 2/6] drm: Allow render nodes to query display objects
@ 2017-07-05 22:24   ` Keith Packard
  0 siblings, 0 replies; 26+ messages in thread
From: Keith Packard @ 2017-07-05 22:24 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 f1e568176da9..a5a259964c7d 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.11.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 3/6] drm: Add new LEASE debug level
  2017-07-05 22:24 ` Keith Packard
@ 2017-07-05 22:24   ` Keith Packard
  -1 siblings, 0 replies; 26+ messages in thread
From: Keith Packard @ 2017-07-05 22:24 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 b5c6bb46a425..b65308a278ca 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 39df16af7a4a..c3b6343557f4 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -145,6 +145,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 */
@@ -259,6 +260,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.11.0

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 3/6] drm: Add new LEASE debug level
@ 2017-07-05 22:24   ` Keith Packard
  0 siblings, 0 replies; 26+ messages in thread
From: Keith Packard @ 2017-07-05 22:24 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 b5c6bb46a425..b65308a278ca 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 39df16af7a4a..c3b6343557f4 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -145,6 +145,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 */
@@ -259,6 +260,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.11.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 4/6] drm: Add drm_object lease infrastructure [v3]
  2017-07-05 22:24 ` Keith Packard
                   ` (3 preceding siblings ...)
  (?)
@ 2017-07-05 22:24 ` Keith Packard
  2017-10-05  3:55     ` Dave Airlie
  -1 siblings, 1 reply; 26+ messages in thread
From: Keith Packard @ 2017-07-05 22:24 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

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   | 376 ++++++++++++++++++++++++++++++++++++++++++
 include/drm/drm_auth.h        |  20 +++
 include/drm/drm_lease.h       |  36 ++++
 include/drm/drm_mode_object.h |   1 +
 6 files changed, 462 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 24a066e1841c..3a47f5ae6f16 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..a8bd4bdd2977
--- /dev/null
+++ b/drivers/gpu/drm/drm_lease.c
@@ -0,0 +1,376 @@
+/*
+ * 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.11.0

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 5/6] drm: Check mode object lease status in all master ioctl paths [v2]
  2017-07-05 22:24 ` Keith Packard
@ 2017-07-05 22:24   ` Keith Packard
  -1 siblings, 0 replies; 26+ messages in thread
From: Keith Packard @ 2017-07-05 22:24 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 cd3c106dc5e2..436e99a2d5eb 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -1295,7 +1295,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;
@@ -1309,7 +1309,8 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
 		goto out_unref;
 
 	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) {
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 d9862259a2a7..f7ceee2ae340 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 ccc3a35d2de2..dbc280ddef9b 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 462c244498e2..9a7306a912b6 100644
--- a/drivers/gpu/drm/drm_plane.c
+++ b/drivers/gpu/drm/drm_plane.c
@@ -400,9 +400,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;
@@ -416,7 +416,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 463e4d81fb0d..66fe329e7d2b 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -1436,9 +1436,11 @@ static bool drm_wait_vblank_is_query(union drm_wait_vblank *vblwait)
 int drm_wait_vblank(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;
+	unsigned int pipe_index;
 	unsigned int flags, seq, pipe, high_pipe;
 
 	if (!dev->irq_enabled)
@@ -1460,9 +1462,21 @@ int drm_wait_vblank(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.11.0

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 5/6] drm: Check mode object lease status in all master ioctl paths [v2]
@ 2017-07-05 22:24   ` Keith Packard
  0 siblings, 0 replies; 26+ messages in thread
From: Keith Packard @ 2017-07-05 22:24 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 cd3c106dc5e2..436e99a2d5eb 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -1295,7 +1295,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;
@@ -1309,7 +1309,8 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
 		goto out_unref;
 
 	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) {
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 d9862259a2a7..f7ceee2ae340 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 ccc3a35d2de2..dbc280ddef9b 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 462c244498e2..9a7306a912b6 100644
--- a/drivers/gpu/drm/drm_plane.c
+++ b/drivers/gpu/drm/drm_plane.c
@@ -400,9 +400,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;
@@ -416,7 +416,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 463e4d81fb0d..66fe329e7d2b 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -1436,9 +1436,11 @@ static bool drm_wait_vblank_is_query(union drm_wait_vblank *vblwait)
 int drm_wait_vblank(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;
+	unsigned int pipe_index;
 	unsigned int flags, seq, pipe, high_pipe;
 
 	if (!dev->irq_enabled)
@@ -1460,9 +1462,21 @@ int drm_wait_vblank(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.11.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 6/6] drm: Add four ioctls for managing drm mode object leases [v3]
  2017-07-05 22:24 ` Keith Packard
@ 2017-07-05 22:24   ` Keith Packard
  -1 siblings, 0 replies; 26+ messages in thread
From: Keith Packard @ 2017-07-05 22:24 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.

Signed-off-by: Keith Packard <keithp@keithp.com>
---
 drivers/gpu/drm/drm_ioctl.c |   4 +
 drivers/gpu/drm/drm_lease.c | 270 ++++++++++++++++++++++++++++++++++++++++++++
 include/drm/drm_lease.h     |  12 ++
 include/uapi/drm/drm.h      |   5 +
 include/uapi/drm/drm_mode.h |  64 +++++++++++
 5 files changed, 355 insertions(+)

diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index a5a259964c7d..0a43e82d3f06 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -657,6 +657,10 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
 		      DRM_UNLOCKED|DRM_RENDER_ALLOW),
 	DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE, drm_syncobj_fd_to_handle_ioctl,
 		      DRM_UNLOCKED|DRM_RENDER_ALLOW),
+	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 a8bd4bdd2977..f233d8b488f2 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
@@ -374,3 +376,271 @@ 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);
+
+		/* Just need to have something non-NULL here, it doesn't matter what */
+		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/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 101593ab10ac..dd350bf0ad75 100644
--- a/include/uapi/drm/drm.h
+++ b/include/uapi/drm/drm.h
@@ -841,6 +841,11 @@ extern "C" {
 #define DRM_IOCTL_SYNCOBJ_HANDLE_TO_FD	DRM_IOWR(0xC1, struct drm_syncobj_handle)
 #define DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE	DRM_IOWR(0xC2, struct drm_syncobj_handle)
 
+#define DRM_IOCTL_MODE_CREATE_LEASE	DRM_IOWR(0xC3, struct drm_mode_create_lease)
+#define DRM_IOCTL_MODE_LIST_LESSEES	DRM_IOWR(0xC4, struct drm_mode_list_lessees)
+#define DRM_IOCTL_MODE_GET_LEASE	DRM_IOWR(0xC5, struct drm_mode_get_lease)
+#define DRM_IOCTL_MODE_REVOKE_LEASE	DRM_IOWR(0xC6, 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 403339f98a92..184948bdd4b4 100644
--- a/include/uapi/drm/drm_mode.h
+++ b/include/uapi/drm/drm_mode.h
@@ -732,6 +732,70 @@ 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;
+
+	/** 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;
+
+	/** 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.11.0

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 6/6] drm: Add four ioctls for managing drm mode object leases [v3]
@ 2017-07-05 22:24   ` Keith Packard
  0 siblings, 0 replies; 26+ messages in thread
From: Keith Packard @ 2017-07-05 22:24 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.

Signed-off-by: Keith Packard <keithp@keithp.com>
---
 drivers/gpu/drm/drm_ioctl.c |   4 +
 drivers/gpu/drm/drm_lease.c | 270 ++++++++++++++++++++++++++++++++++++++++++++
 include/drm/drm_lease.h     |  12 ++
 include/uapi/drm/drm.h      |   5 +
 include/uapi/drm/drm_mode.h |  64 +++++++++++
 5 files changed, 355 insertions(+)

diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index a5a259964c7d..0a43e82d3f06 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -657,6 +657,10 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
 		      DRM_UNLOCKED|DRM_RENDER_ALLOW),
 	DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE, drm_syncobj_fd_to_handle_ioctl,
 		      DRM_UNLOCKED|DRM_RENDER_ALLOW),
+	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 a8bd4bdd2977..f233d8b488f2 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
@@ -374,3 +376,271 @@ 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);
+
+		/* Just need to have something non-NULL here, it doesn't matter what */
+		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/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 101593ab10ac..dd350bf0ad75 100644
--- a/include/uapi/drm/drm.h
+++ b/include/uapi/drm/drm.h
@@ -841,6 +841,11 @@ extern "C" {
 #define DRM_IOCTL_SYNCOBJ_HANDLE_TO_FD	DRM_IOWR(0xC1, struct drm_syncobj_handle)
 #define DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE	DRM_IOWR(0xC2, struct drm_syncobj_handle)
 
+#define DRM_IOCTL_MODE_CREATE_LEASE	DRM_IOWR(0xC3, struct drm_mode_create_lease)
+#define DRM_IOCTL_MODE_LIST_LESSEES	DRM_IOWR(0xC4, struct drm_mode_list_lessees)
+#define DRM_IOCTL_MODE_GET_LEASE	DRM_IOWR(0xC5, struct drm_mode_get_lease)
+#define DRM_IOCTL_MODE_REVOKE_LEASE	DRM_IOWR(0xC6, 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 403339f98a92..184948bdd4b4 100644
--- a/include/uapi/drm/drm_mode.h
+++ b/include/uapi/drm/drm_mode.h
@@ -732,6 +732,70 @@ 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;
+
+	/** 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;
+
+	/** 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.11.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* Re: [PATCH 6/6] drm: Add four ioctls for managing drm mode object leases [v3]
  2017-07-05 22:24   ` Keith Packard
@ 2017-07-06  0:42     ` Dave Airlie
  -1 siblings, 0 replies; 26+ messages in thread
From: Dave Airlie @ 2017-07-06  0:42 UTC (permalink / raw)
  To: Keith Packard; +Cc: LKML, Dave Airlie, Daniel Vetter, dri-devel

> +/**
> + * 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;
> +
> +       /** Pointer to lessees.
> +        * pointer to __u64 array of lessee ids
> +        */
> +       __u64 lessees_ptr;
> +};

I think this needs a pad ^.

> +
> +/**
> + * 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;
> +
> +       /** Pointer to objects.
> +        * pointer to __u32 array of object ids
> +        */
> +       __u64 objects_ptr;

And this.

> +};
> +
> +/**
> + * Revoke lease
> + */
> +struct drm_mode_revoke_lease {
> +       /** Unique ID of lessee
> +        */
> +       __u32 lessee_id;

And this.

Dave.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 6/6] drm: Add four ioctls for managing drm mode object leases [v3]
@ 2017-07-06  0:42     ` Dave Airlie
  0 siblings, 0 replies; 26+ messages in thread
From: Dave Airlie @ 2017-07-06  0:42 UTC (permalink / raw)
  To: Keith Packard; +Cc: Dave Airlie, dri-devel, LKML

> +/**
> + * 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;
> +
> +       /** Pointer to lessees.
> +        * pointer to __u64 array of lessee ids
> +        */
> +       __u64 lessees_ptr;
> +};

I think this needs a pad ^.

> +
> +/**
> + * 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;
> +
> +       /** Pointer to objects.
> +        * pointer to __u32 array of object ids
> +        */
> +       __u64 objects_ptr;

And this.

> +};
> +
> +/**
> + * Revoke lease
> + */
> +struct drm_mode_revoke_lease {
> +       /** Unique ID of lessee
> +        */
> +       __u32 lessee_id;

And this.

Dave.
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 6/6] drm: Add four ioctls for managing drm mode object leases [v3]
  2017-07-06  0:42     ` Dave Airlie
@ 2017-07-06  3:38       ` Keith Packard
  -1 siblings, 0 replies; 26+ messages in thread
From: Keith Packard @ 2017-07-06  3:38 UTC (permalink / raw)
  To: Dave Airlie; +Cc: LKML, Dave Airlie, Daniel Vetter, dri-devel

[-- Attachment #1: Type: text/plain, Size: 406 bytes --]

Dave Airlie <airlied@gmail.com> writes:

> I think this needs a pad ^.

> And this.

Yup. Thanks!

>> +struct drm_mode_revoke_lease {
>> +       /** Unique ID of lessee
>> +        */
>> +       __u32 lessee_id;
>
> And this.

None of the other bare 32-bit ioctl structures are padded; I think
that's probably fine as they'll be 4 bytes on both 64-bit and 32-bit
machines.

-- 
-keith

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 6/6] drm: Add four ioctls for managing drm mode object leases [v3]
@ 2017-07-06  3:38       ` Keith Packard
  0 siblings, 0 replies; 26+ messages in thread
From: Keith Packard @ 2017-07-06  3:38 UTC (permalink / raw)
  To: Dave Airlie; +Cc: Dave Airlie, dri-devel, LKML


[-- Attachment #1.1: Type: text/plain, Size: 406 bytes --]

Dave Airlie <airlied@gmail.com> writes:

> I think this needs a pad ^.

> And this.

Yup. Thanks!

>> +struct drm_mode_revoke_lease {
>> +       /** Unique ID of lessee
>> +        */
>> +       __u32 lessee_id;
>
> And this.

None of the other bare 32-bit ioctl structures are padded; I think
that's probably fine as they'll be 4 bytes on both 64-bit and 32-bit
machines.

-- 
-keith

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 6/6] drm: Add four ioctls for managing drm mode object leases [v3]
  2017-07-05 22:24   ` Keith Packard
  (?)
  (?)
@ 2017-10-05  3:17   ` Dave Airlie
  2017-10-05  3:24       ` Dave Airlie
  -1 siblings, 1 reply; 26+ messages in thread
From: Dave Airlie @ 2017-10-05  3:17 UTC (permalink / raw)
  To: Keith Packard; +Cc: LKML, Dave Airlie, Daniel Vetter, dri-devel

> ---
>  drivers/gpu/drm/drm_ioctl.c |   4 +
>  drivers/gpu/drm/drm_lease.c | 270 ++++++++++++++++++++++++++++++++++++++++++++
>  include/drm/drm_lease.h     |  12 ++
>  include/uapi/drm/drm.h      |   5 +
>  include/uapi/drm/drm_mode.h |  64 +++++++++++
>  5 files changed, 355 insertions(+)
>
> diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
> index a5a259964c7d..0a43e82d3f06 100644
> --- a/drivers/gpu/drm/drm_ioctl.c
> +++ b/drivers/gpu/drm/drm_ioctl.c
> @@ -657,6 +657,10 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
>                       DRM_UNLOCKED|DRM_RENDER_ALLOW),
>         DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE, drm_syncobj_fd_to_handle_ioctl,
>                       DRM_UNLOCKED|DRM_RENDER_ALLOW),
> +       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 a8bd4bdd2977..f233d8b488f2 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;

What is this for? ^^

> +               ret = idr_alloc(&leases, &drm_lease_idr_object , object_id, object_id + 1, GFP_KERNEL);

You can just pass NULL here.

Dave.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 6/6] drm: Add four ioctls for managing drm mode object leases [v3]
  2017-10-05  3:17   ` Dave Airlie
@ 2017-10-05  3:24       ` Dave Airlie
  0 siblings, 0 replies; 26+ messages in thread
From: Dave Airlie @ 2017-10-05  3:24 UTC (permalink / raw)
  To: Keith Packard; +Cc: LKML, Dave Airlie, Daniel Vetter, dri-devel

On 5 October 2017 at 13:17, Dave Airlie <airlied@gmail.com> wrote:
>> ---
>>  drivers/gpu/drm/drm_ioctl.c |   4 +
>>  drivers/gpu/drm/drm_lease.c | 270 ++++++++++++++++++++++++++++++++++++++++++++
>>  include/drm/drm_lease.h     |  12 ++
>>  include/uapi/drm/drm.h      |   5 +
>>  include/uapi/drm/drm_mode.h |  64 +++++++++++
>>  5 files changed, 355 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
>> index a5a259964c7d..0a43e82d3f06 100644
>> --- a/drivers/gpu/drm/drm_ioctl.c
>> +++ b/drivers/gpu/drm/drm_ioctl.c
>> @@ -657,6 +657,10 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
>>                       DRM_UNLOCKED|DRM_RENDER_ALLOW),
>>         DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE, drm_syncobj_fd_to_handle_ioctl,
>>                       DRM_UNLOCKED|DRM_RENDER_ALLOW),
>> +       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 a8bd4bdd2977..f233d8b488f2 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;
>
> What is this for? ^^
>
>> +               ret = idr_alloc(&leases, &drm_lease_idr_object , object_id, object_id + 1, GFP_KERNEL);
>
> You can just pass NULL here.
>

Just read the comment, this smells a bit of black magic, I'll spend
some time staring at it :-)

Dave.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 6/6] drm: Add four ioctls for managing drm mode object leases [v3]
@ 2017-10-05  3:24       ` Dave Airlie
  0 siblings, 0 replies; 26+ messages in thread
From: Dave Airlie @ 2017-10-05  3:24 UTC (permalink / raw)
  To: Keith Packard; +Cc: Dave Airlie, dri-devel, LKML

On 5 October 2017 at 13:17, Dave Airlie <airlied@gmail.com> wrote:
>> ---
>>  drivers/gpu/drm/drm_ioctl.c |   4 +
>>  drivers/gpu/drm/drm_lease.c | 270 ++++++++++++++++++++++++++++++++++++++++++++
>>  include/drm/drm_lease.h     |  12 ++
>>  include/uapi/drm/drm.h      |   5 +
>>  include/uapi/drm/drm_mode.h |  64 +++++++++++
>>  5 files changed, 355 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
>> index a5a259964c7d..0a43e82d3f06 100644
>> --- a/drivers/gpu/drm/drm_ioctl.c
>> +++ b/drivers/gpu/drm/drm_ioctl.c
>> @@ -657,6 +657,10 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
>>                       DRM_UNLOCKED|DRM_RENDER_ALLOW),
>>         DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE, drm_syncobj_fd_to_handle_ioctl,
>>                       DRM_UNLOCKED|DRM_RENDER_ALLOW),
>> +       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 a8bd4bdd2977..f233d8b488f2 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;
>
> What is this for? ^^
>
>> +               ret = idr_alloc(&leases, &drm_lease_idr_object , object_id, object_id + 1, GFP_KERNEL);
>
> You can just pass NULL here.
>

Just read the comment, this smells a bit of black magic, I'll spend
some time staring at it :-)

Dave.
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 6/6] drm: Add four ioctls for managing drm mode object leases [v3]
  2017-10-05  3:24       ` Dave Airlie
@ 2017-10-05  3:37         ` Dave Airlie
  -1 siblings, 0 replies; 26+ messages in thread
From: Dave Airlie @ 2017-10-05  3:37 UTC (permalink / raw)
  To: Keith Packard; +Cc: LKML, Dave Airlie, Daniel Vetter, dri-devel

On 5 October 2017 at 13:24, Dave Airlie <airlied@gmail.com> wrote:
> On 5 October 2017 at 13:17, Dave Airlie <airlied@gmail.com> wrote:
>>> ---
>>>  drivers/gpu/drm/drm_ioctl.c |   4 +
>>>  drivers/gpu/drm/drm_lease.c | 270 ++++++++++++++++++++++++++++++++++++++++++++
>>>  include/drm/drm_lease.h     |  12 ++
>>>  include/uapi/drm/drm.h      |   5 +
>>>  include/uapi/drm/drm_mode.h |  64 +++++++++++
>>>  5 files changed, 355 insertions(+)
>>>
>>> diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
>>> index a5a259964c7d..0a43e82d3f06 100644
>>> --- a/drivers/gpu/drm/drm_ioctl.c
>>> +++ b/drivers/gpu/drm/drm_ioctl.c
>>> @@ -657,6 +657,10 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
>>>                       DRM_UNLOCKED|DRM_RENDER_ALLOW),
>>>         DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE, drm_syncobj_fd_to_handle_ioctl,
>>>                       DRM_UNLOCKED|DRM_RENDER_ALLOW),
>>> +       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 a8bd4bdd2977..f233d8b488f2 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;
>>
>> What is this for? ^^
>>
>>> +               ret = idr_alloc(&leases, &drm_lease_idr_object , object_id, object_id + 1, GFP_KERNEL);
>>
>> You can just pass NULL here.
>>
>
> Just read the comment, this smells a bit of black magic, I'll spend
> some time staring at it :-)

I think a comment in here is definitely warranted with what you expect
from the idr interface here.

You seem to be storing the object ids in it from the user, and failing
if you get a duplicate, then later dequeuing the idr.

I'm not sure this an intended use of idr :-), my brain is saying a
bitmap would work just as well, or even why we want/need
deduplication here. If userspace does something stupid does it matter?

Because otherwise you could just memdup_user the array of ids, and
pass that in without the idr stuff.

Dave.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 6/6] drm: Add four ioctls for managing drm mode object leases [v3]
@ 2017-10-05  3:37         ` Dave Airlie
  0 siblings, 0 replies; 26+ messages in thread
From: Dave Airlie @ 2017-10-05  3:37 UTC (permalink / raw)
  To: Keith Packard; +Cc: Dave Airlie, dri-devel, LKML

On 5 October 2017 at 13:24, Dave Airlie <airlied@gmail.com> wrote:
> On 5 October 2017 at 13:17, Dave Airlie <airlied@gmail.com> wrote:
>>> ---
>>>  drivers/gpu/drm/drm_ioctl.c |   4 +
>>>  drivers/gpu/drm/drm_lease.c | 270 ++++++++++++++++++++++++++++++++++++++++++++
>>>  include/drm/drm_lease.h     |  12 ++
>>>  include/uapi/drm/drm.h      |   5 +
>>>  include/uapi/drm/drm_mode.h |  64 +++++++++++
>>>  5 files changed, 355 insertions(+)
>>>
>>> diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
>>> index a5a259964c7d..0a43e82d3f06 100644
>>> --- a/drivers/gpu/drm/drm_ioctl.c
>>> +++ b/drivers/gpu/drm/drm_ioctl.c
>>> @@ -657,6 +657,10 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
>>>                       DRM_UNLOCKED|DRM_RENDER_ALLOW),
>>>         DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE, drm_syncobj_fd_to_handle_ioctl,
>>>                       DRM_UNLOCKED|DRM_RENDER_ALLOW),
>>> +       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 a8bd4bdd2977..f233d8b488f2 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;
>>
>> What is this for? ^^
>>
>>> +               ret = idr_alloc(&leases, &drm_lease_idr_object , object_id, object_id + 1, GFP_KERNEL);
>>
>> You can just pass NULL here.
>>
>
> Just read the comment, this smells a bit of black magic, I'll spend
> some time staring at it :-)

I think a comment in here is definitely warranted with what you expect
from the idr interface here.

You seem to be storing the object ids in it from the user, and failing
if you get a duplicate, then later dequeuing the idr.

I'm not sure this an intended use of idr :-), my brain is saying a
bitmap would work just as well, or even why we want/need
deduplication here. If userspace does something stupid does it matter?

Because otherwise you could just memdup_user the array of ids, and
pass that in without the idr stuff.

Dave.
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 4/6] drm: Add drm_object lease infrastructure [v3]
  2017-07-05 22:24 ` [PATCH 4/6] drm: Add drm_object lease infrastructure [v3] Keith Packard
@ 2017-10-05  3:55     ` Dave Airlie
  0 siblings, 0 replies; 26+ messages in thread
From: Dave Airlie @ 2017-10-05  3:55 UTC (permalink / raw)
  To: Keith Packard; +Cc: LKML, Dave Airlie, Daniel Vetter, dri-devel

> + *
> + * drm_master at the top of the tree (i.e, with lessor NULL
> + */
> +struct drm_master *drm_lease_owner(struct drm_master *master) {

^ there's a couple of misplaced braces around. start of next line please.


> +       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) {

^^ here as well.

> +       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) {

^^ here as well


> +}
> +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;

There are a couple of stray tab chars in here ^

> +       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;

And here ^

Dave.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 4/6] drm: Add drm_object lease infrastructure [v3]
@ 2017-10-05  3:55     ` Dave Airlie
  0 siblings, 0 replies; 26+ messages in thread
From: Dave Airlie @ 2017-10-05  3:55 UTC (permalink / raw)
  To: Keith Packard; +Cc: Dave Airlie, dri-devel, LKML

> + *
> + * drm_master at the top of the tree (i.e, with lessor NULL
> + */
> +struct drm_master *drm_lease_owner(struct drm_master *master) {

^ there's a couple of misplaced braces around. start of next line please.


> +       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) {

^^ here as well.

> +       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) {

^^ here as well


> +}
> +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;

There are a couple of stray tab chars in here ^

> +       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;

And here ^

Dave.
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 6/6] drm: Add four ioctls for managing drm mode object leases [v3]
  2017-10-05  3:37         ` Dave Airlie
@ 2017-10-05  6:23           ` Keith Packard
  -1 siblings, 0 replies; 26+ messages in thread
From: Keith Packard @ 2017-10-05  6:23 UTC (permalink / raw)
  To: Dave Airlie; +Cc: LKML, Dave Airlie, Daniel Vetter, dri-devel

[-- Attachment #1: Type: text/plain, Size: 1125 bytes --]

Dave Airlie <airlied@gmail.com> writes:

> I think a comment in here is definitely warranted with what you expect
> from the idr interface here.

I've added a longer comment where this value is used; I tried replacing
the IDR with a sorted array and the result wasn't any easier to use or
understand. I'm pretty sure it would be more efficient, but as leases
contain only a few objects in the cases we're considering, it's hard to
get worked up about performance when the code is larger and mostly not
any easier to understand. Feel free to take a look at that:

        git://people.freedesktop.org/~keithp/linux drm-lease-array

> Because otherwise you could just memdup_user the array of ids, and
> pass that in without the idr stuff.

Yeah, that part was more efficient. The rest of the places using this
data were longer. I guess I could bail on sorting the array, but I fear
someone would come up with a place needing a huge lease list, and then
we'd find performance issues.

Thanks for your review; I've sent out a new series and pushed it to my
repo in the drm-lease-v4 branch

-- 
-keith

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 6/6] drm: Add four ioctls for managing drm mode object leases [v3]
@ 2017-10-05  6:23           ` Keith Packard
  0 siblings, 0 replies; 26+ messages in thread
From: Keith Packard @ 2017-10-05  6:23 UTC (permalink / raw)
  To: Dave Airlie; +Cc: Dave Airlie, dri-devel, LKML


[-- Attachment #1.1: Type: text/plain, Size: 1125 bytes --]

Dave Airlie <airlied@gmail.com> writes:

> I think a comment in here is definitely warranted with what you expect
> from the idr interface here.

I've added a longer comment where this value is used; I tried replacing
the IDR with a sorted array and the result wasn't any easier to use or
understand. I'm pretty sure it would be more efficient, but as leases
contain only a few objects in the cases we're considering, it's hard to
get worked up about performance when the code is larger and mostly not
any easier to understand. Feel free to take a look at that:

        git://people.freedesktop.org/~keithp/linux drm-lease-array

> Because otherwise you could just memdup_user the array of ids, and
> pass that in without the idr stuff.

Yeah, that part was more efficient. The rest of the places using this
data were longer. I guess I could bail on sorting the array, but I fear
someone would come up with a place needing a huge lease list, and then
we'd find performance issues.

Thanks for your review; I've sent out a new series and pushed it to my
repo in the drm-lease-v4 branch

-- 
-keith

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 26+ messages in thread

end of thread, other threads:[~2017-10-05  6:23 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-07-05 22:24 [PATCH 0/6] drm: Add mode object leases [v3] Keith Packard
2017-07-05 22:24 ` Keith Packard
2017-07-05 22:24 ` [PATCH 1/6] drm: Pass struct drm_file * to __drm_mode_object_find Keith Packard
2017-07-05 22:24   ` Keith Packard
2017-07-05 22:24 ` [PATCH 2/6] drm: Allow render nodes to query display objects Keith Packard
2017-07-05 22:24   ` Keith Packard
2017-07-05 22:24 ` [PATCH 3/6] drm: Add new LEASE debug level Keith Packard
2017-07-05 22:24   ` Keith Packard
2017-07-05 22:24 ` [PATCH 4/6] drm: Add drm_object lease infrastructure [v3] Keith Packard
2017-10-05  3:55   ` Dave Airlie
2017-10-05  3:55     ` Dave Airlie
2017-07-05 22:24 ` [PATCH 5/6] drm: Check mode object lease status in all master ioctl paths [v2] Keith Packard
2017-07-05 22:24   ` Keith Packard
2017-07-05 22:24 ` [PATCH 6/6] drm: Add four ioctls for managing drm mode object leases [v3] Keith Packard
2017-07-05 22:24   ` Keith Packard
2017-07-06  0:42   ` Dave Airlie
2017-07-06  0:42     ` Dave Airlie
2017-07-06  3:38     ` Keith Packard
2017-07-06  3:38       ` Keith Packard
2017-10-05  3:17   ` Dave Airlie
2017-10-05  3:24     ` Dave Airlie
2017-10-05  3:24       ` Dave Airlie
2017-10-05  3:37       ` Dave Airlie
2017-10-05  3:37         ` Dave Airlie
2017-10-05  6:23         ` Keith Packard
2017-10-05  6:23           ` Keith Packard

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.