diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index dd5ae67f8e2b..351f3817bc27 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -30,6 +30,7 @@ drm-$(CONFIG_OF) += drm_of.o
 drm-$(CONFIG_AGP) += drm_agpsupport.o
 drm-$(CONFIG_DEBUG_FS) += drm_debugfs.o drm_debugfs_crc.o
 drm-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o
+drm-$(CONFIG_CGROUPS) += drm_cgroup.o
 
 drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_probe_helper.o \
 		drm_plane_helper.o drm_dp_mst_topology.o drm_atomic_helper.o \
diff --git a/drivers/gpu/drm/drm_cgroup.c b/drivers/gpu/drm/drm_cgroup.c
new file mode 100644
index 000000000000..0d9187ee435d
--- /dev/null
+++ b/drivers/gpu/drm/drm_cgroup.c
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no representations
+ * about the suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include <drm/drmP.h>
+#include <drm/drm_cgroup.h>
+
+/**
+ * DOC: cgroup handling
+ *
+ * cgroups are a core kernel mechanism for organizing OS processes into logical
+ * groupings to which policy configuration or resource management may be
+ * applied.  Some DRM drivers may control resources or have policy settings
+ * that a system integrator would wish to configure according to the system
+ * cgroups hierarchy.  To support such use cases, the DRM framework allows
+ * drivers to track 'parameters' on a per-cgroup basis.  Parameters are a (u64
+ * key, s64 value) pair which would generally be set on specific cgroups
+ * during system configuration (e.g., by a sysv init script or systemd service)
+ * and then used by the driver at runtime to manage GPU-specific resources or
+ * control driver-specific policy.
+ */
+
+/**
+ * drm_cgroup_setparam_ioctl
+ * @dev: DRM device
+ * @data: data pointer for the ioctl
+ * @file_priv: DRM file handle for the ioctl call
+ *
+ * Set DRM-specific parameters for a cgroup
+ */
+int
+drm_cgroup_setparam_ioctl(struct drm_device *dev, void *data,
+			  struct drm_file *file_priv)
+{
+	struct drm_cgroup_setparam *req = data;
+	struct cgroup *cgrp;
+	struct file *f;
+	struct inode *inode = NULL;
+	int ret;
+
+	/*
+	 * We'll let drivers create their own parameters with ID's from
+	 * 0-0xFFFFFF.  We'll reserve parameter ID's above that range for
+	 * anything the DRM core wants to control directly; today we don't
+	 * have any such core-managed parameters, so just reject attempts
+	 * to set a cgroup parameter in this range.
+	 */
+	if (req->param > DRM_CGROUP_MAX_DRIVER_PARAM) {
+		DRM_DEBUG("Invalid cgroup parameter ID\n");
+		return -EINVAL;
+	}
+
+	if (!dev->cgroup) {
+		DRM_DEBUG("Invalid cgroup parameter ID\n");
+		return -EINVAL;
+	}
+
+	/* Make sure the file descriptor really is a cgroup fd */
+	cgrp = cgroup_get_from_fd(req->cgroup_fd);
+	if (IS_ERR(cgrp)) {
+		DRM_DEBUG("Invalid cgroup file descriptor\n");
+		return PTR_ERR(cgrp);
+	}
+
+	/*
+	 * Restrict this functionality to cgroups on the cgroups-v2
+	 * (i.e., default) hierarchy.
+	 */
+	if (!cgroup_on_dfl(cgrp)) {
+		DRM_DEBUG("setparam only supported on cgroup-v2 hierarchy\n");
+		return -EINVAL;
+	}
+
+	/*
+	 * Access control:  The strategy for using cgroups in a given
+	 * environment is generally determined by the system integrator
+	 * and/or OS vendor, so the specific policy about who can/can't
+	 * manipulate them tends to be domain-specific (and may vary
+	 * depending on the location in the cgroup hierarchy).  Rather than
+	 * trying to tie permission on this ioctl to a DRM-specific concepts
+	 * like DRM master, we'll allow cgroup parameters to be set by any
+	 * process that has been granted write access on the cgroup's
+	 * virtual file system (i.e., the same permissions that would
+	 * generally be needed to update the virtual files provided by
+	 * cgroup controllers).
+	 */
+	f = fget_raw(req->cgroup_fd);
+	if (WARN_ON(!f))
+		return -EBADF;
+
+	inode = kernfs_get_inode(f->f_path.dentry->d_sb, cgrp->kn);
+	if (inode)
+		ret = inode_permission(inode, MAY_WRITE);
+	else
+		ret = -ENOMEM;
+
+	iput(inode);
+	fput(f);
+
+	return ret ?: dev->cgroup->set_param(dev, cgrp, req->param,
+					     req->value);
+}
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index b1e96fb68ea8..d457a012427c 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -31,6 +31,7 @@
 #include <drm/drm_ioctl.h>
 #include <drm/drmP.h>
 #include <drm/drm_auth.h>
+#include <drm/drm_cgroup.h>
 #include "drm_legacy.h"
 #include "drm_internal.h"
 #include "drm_crtc_internal.h"
@@ -549,6 +550,10 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
 	DRM_IOCTL_DEF(DRM_IOCTL_GET_CAP, drm_getcap, DRM_UNLOCKED|DRM_RENDER_ALLOW),
 	DRM_IOCTL_DEF(DRM_IOCTL_SET_CLIENT_CAP, drm_setclientcap, DRM_UNLOCKED),
 	DRM_IOCTL_DEF(DRM_IOCTL_SET_VERSION, drm_setversion, DRM_UNLOCKED | DRM_MASTER),
+#if IS_ENABLED(CONFIG_CGROUPS)
+	DRM_IOCTL_DEF(DRM_IOCTL_CGROUP_SETPARAM, drm_cgroup_setparam_ioctl,
+		      DRM_UNLOCKED|DRM_RENDER_ALLOW),
+#endif
 
 	DRM_IOCTL_DEF(DRM_IOCTL_SET_UNIQUE, drm_invalid_op, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
 	DRM_IOCTL_DEF(DRM_IOCTL_BLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
diff --git a/include/drm/drm_cgroup.h b/include/drm/drm_cgroup.h
new file mode 100644
index 000000000000..b43b6e5b4222
--- /dev/null
+++ b/include/drm/drm_cgroup.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no representations
+ * about the suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#ifndef __DRM_CGROUP_H__
+
+#include <linux/cgroup.h>
+#include <drm/drm_file.h>
+
+struct drm_cgroup_funcs {
+	int (*set_param)(struct drm_device *dev,
+			 struct cgroup *cgrp,
+			 uint64_t param,
+			 int64_t val);
+};
+
+int drm_cgroup_setparam_ioctl(struct drm_device *dev, void *data,
+			      struct drm_file *file_priv);
+
+#endif
diff --git a/include/drm/drm_device.h b/include/drm/drm_device.h
index 7c4fa32f3fc6..6eee7bbee602 100644
--- a/include/drm/drm_device.h
+++ b/include/drm/drm_device.h
@@ -18,6 +18,7 @@ struct drm_sg_mem;
 struct drm_local_map;
 struct drm_vma_offset_manager;
 struct drm_fb_helper;
+struct drm_cgroup_funcs;
 
 struct inode;
 
@@ -194,6 +195,13 @@ struct drm_device {
 	 * Set by drm_fb_helper_init() and cleared by drm_fb_helper_fini().
 	 */
 	struct drm_fb_helper *fb_helper;
+
+#ifdef CONFIG_CGROUPS
+	/**
+	 * @cgroup: Per-driver cgroup handlers.
+	 */
+	struct drm_cgroup_funcs *cgroup;
+#endif /* CONFIG_CGROUPS */
 };
 
 #endif
diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h
index 6fdff5945c8a..1caa1ce446e7 100644
--- a/include/uapi/drm/drm.h
+++ b/include/uapi/drm/drm.h
@@ -686,6 +686,15 @@ struct drm_set_client_cap {
 	__u64 value;
 };
 
+/** DRM_IOCTL_CGROUP_SETPARAM ioctl argument type */
+struct drm_cgroup_setparam {
+	__s32 cgroup_fd;
+	__u32 reserved;
+	__u64 param;
+	__s64 value;
+};
+#define DRM_CGROUP_MAX_DRIVER_PARAM  0xFFFFFF
+
 #define DRM_RDWR O_RDWR
 #define DRM_CLOEXEC O_CLOEXEC
 struct drm_prime_handle {
@@ -789,6 +798,7 @@ extern "C" {
 #define DRM_IOCTL_GEM_OPEN		DRM_IOWR(0x0b, struct drm_gem_open)
 #define DRM_IOCTL_GET_CAP		DRM_IOWR(0x0c, struct drm_get_cap)
 #define DRM_IOCTL_SET_CLIENT_CAP	DRM_IOW( 0x0d, struct drm_set_client_cap)
+#define DRM_IOCTL_CGROUP_SETPARAM	DRM_IOW( 0x0e, struct drm_cgroup_setparam)
 
 #define DRM_IOCTL_SET_UNIQUE		DRM_IOW( 0x10, struct drm_unique)
 #define DRM_IOCTL_AUTH_MAGIC		DRM_IOW( 0x11, struct drm_auth)
