Commit 6b855f7b authored by Harish Kasiviswanathan's avatar Harish Kasiviswanathan Committed by Alex Deucher

drm/amdkfd: Check against device cgroup

Participate in device cgroup. All kfd devices are exposed via /dev/kfd.
So use /dev/dri/renderN node.

Before exposing the device to a task check if it has permission to
access it. If the task (based on its cgroup) can access /dev/dri/renderN
then expose the device via kfd node.

If the task cannot access /dev/dri/renderN then process device data
(pdd) is not created. This will ensure that task cannot use the device.

In sysfs topology, all device nodes are visible irrespective of the task
cgroup. The sysfs node directories are created at driver load time and
cannot be changed dynamically. However, access to information inside
nodes is controlled based on the task's cgroup permissions.
Signed-off-by: default avatarHarish Kasiviswanathan <Harish.Kasiviswanathan@amd.com>
Reviewed-by: default avatarFelix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 4b7d4d45
...@@ -369,8 +369,13 @@ int kfd_init_apertures(struct kfd_process *process) ...@@ -369,8 +369,13 @@ int kfd_init_apertures(struct kfd_process *process)
/*Iterating over all devices*/ /*Iterating over all devices*/
while (kfd_topology_enum_kfd_devices(id, &dev) == 0) { while (kfd_topology_enum_kfd_devices(id, &dev) == 0) {
if (!dev) { if (!dev || kfd_devcgroup_check_permission(dev)) {
id++; /* Skip non GPU devices */ /* Skip non GPU devices and devices to which the
* current process have no access to. Access can be
* limited by placing the process in a specific
* cgroup hierarchy
*/
id++;
continue; continue;
} }
......
...@@ -36,6 +36,8 @@ ...@@ -36,6 +36,8 @@
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include <linux/kref.h> #include <linux/kref.h>
#include <linux/sysfs.h> #include <linux/sysfs.h>
#include <linux/device_cgroup.h>
#include <drm/drmP.h>
#include <kgd_kfd_interface.h> #include <kgd_kfd_interface.h>
#include "amd_shared.h" #include "amd_shared.h"
...@@ -1042,6 +1044,21 @@ bool kfd_is_locked(void); ...@@ -1042,6 +1044,21 @@ bool kfd_is_locked(void);
void kfd_inc_compute_active(struct kfd_dev *dev); void kfd_inc_compute_active(struct kfd_dev *dev);
void kfd_dec_compute_active(struct kfd_dev *dev); void kfd_dec_compute_active(struct kfd_dev *dev);
/* Cgroup Support */
/* Check with device cgroup if @kfd device is accessible */
static inline int kfd_devcgroup_check_permission(struct kfd_dev *kfd)
{
#if defined(CONFIG_CGROUP_DEVICE)
struct drm_device *ddev = kfd->ddev;
return devcgroup_check_permission(DEVCG_DEV_CHAR, ddev->driver->major,
ddev->render->index,
DEVCG_ACC_WRITE | DEVCG_ACC_READ);
#else
return 0;
#endif
}
/* Debugfs */ /* Debugfs */
#if defined(CONFIG_DEBUG_FS) #if defined(CONFIG_DEBUG_FS)
......
...@@ -269,6 +269,8 @@ static ssize_t iolink_show(struct kobject *kobj, struct attribute *attr, ...@@ -269,6 +269,8 @@ static ssize_t iolink_show(struct kobject *kobj, struct attribute *attr,
buffer[0] = 0; buffer[0] = 0;
iolink = container_of(attr, struct kfd_iolink_properties, attr); iolink = container_of(attr, struct kfd_iolink_properties, attr);
if (iolink->gpu && kfd_devcgroup_check_permission(iolink->gpu))
return -EPERM;
sysfs_show_32bit_prop(buffer, "type", iolink->iolink_type); sysfs_show_32bit_prop(buffer, "type", iolink->iolink_type);
sysfs_show_32bit_prop(buffer, "version_major", iolink->ver_maj); sysfs_show_32bit_prop(buffer, "version_major", iolink->ver_maj);
sysfs_show_32bit_prop(buffer, "version_minor", iolink->ver_min); sysfs_show_32bit_prop(buffer, "version_minor", iolink->ver_min);
...@@ -305,6 +307,8 @@ static ssize_t mem_show(struct kobject *kobj, struct attribute *attr, ...@@ -305,6 +307,8 @@ static ssize_t mem_show(struct kobject *kobj, struct attribute *attr,
buffer[0] = 0; buffer[0] = 0;
mem = container_of(attr, struct kfd_mem_properties, attr); mem = container_of(attr, struct kfd_mem_properties, attr);
if (mem->gpu && kfd_devcgroup_check_permission(mem->gpu))
return -EPERM;
sysfs_show_32bit_prop(buffer, "heap_type", mem->heap_type); sysfs_show_32bit_prop(buffer, "heap_type", mem->heap_type);
sysfs_show_64bit_prop(buffer, "size_in_bytes", mem->size_in_bytes); sysfs_show_64bit_prop(buffer, "size_in_bytes", mem->size_in_bytes);
sysfs_show_32bit_prop(buffer, "flags", mem->flags); sysfs_show_32bit_prop(buffer, "flags", mem->flags);
...@@ -334,6 +338,8 @@ static ssize_t kfd_cache_show(struct kobject *kobj, struct attribute *attr, ...@@ -334,6 +338,8 @@ static ssize_t kfd_cache_show(struct kobject *kobj, struct attribute *attr,
buffer[0] = 0; buffer[0] = 0;
cache = container_of(attr, struct kfd_cache_properties, attr); cache = container_of(attr, struct kfd_cache_properties, attr);
if (cache->gpu && kfd_devcgroup_check_permission(cache->gpu))
return -EPERM;
sysfs_show_32bit_prop(buffer, "processor_id_low", sysfs_show_32bit_prop(buffer, "processor_id_low",
cache->processor_id_low); cache->processor_id_low);
sysfs_show_32bit_prop(buffer, "level", cache->cache_level); sysfs_show_32bit_prop(buffer, "level", cache->cache_level);
...@@ -414,6 +420,8 @@ static ssize_t node_show(struct kobject *kobj, struct attribute *attr, ...@@ -414,6 +420,8 @@ static ssize_t node_show(struct kobject *kobj, struct attribute *attr,
if (strcmp(attr->name, "gpu_id") == 0) { if (strcmp(attr->name, "gpu_id") == 0) {
dev = container_of(attr, struct kfd_topology_device, dev = container_of(attr, struct kfd_topology_device,
attr_gpuid); attr_gpuid);
if (dev->gpu && kfd_devcgroup_check_permission(dev->gpu))
return -EPERM;
return sysfs_show_32bit_val(buffer, dev->gpu_id); return sysfs_show_32bit_val(buffer, dev->gpu_id);
} }
...@@ -421,11 +429,15 @@ static ssize_t node_show(struct kobject *kobj, struct attribute *attr, ...@@ -421,11 +429,15 @@ static ssize_t node_show(struct kobject *kobj, struct attribute *attr,
dev = container_of(attr, struct kfd_topology_device, dev = container_of(attr, struct kfd_topology_device,
attr_name); attr_name);
if (dev->gpu && kfd_devcgroup_check_permission(dev->gpu))
return -EPERM;
return sysfs_show_str_val(buffer, dev->node_props.name); return sysfs_show_str_val(buffer, dev->node_props.name);
} }
dev = container_of(attr, struct kfd_topology_device, dev = container_of(attr, struct kfd_topology_device,
attr_props); attr_props);
if (dev->gpu && kfd_devcgroup_check_permission(dev->gpu))
return -EPERM;
sysfs_show_32bit_prop(buffer, "cpu_cores_count", sysfs_show_32bit_prop(buffer, "cpu_cores_count",
dev->node_props.cpu_cores_count); dev->node_props.cpu_cores_count);
sysfs_show_32bit_prop(buffer, "simd_count", sysfs_show_32bit_prop(buffer, "simd_count",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment