Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2df93458 authored by Jordan Crouse's avatar Jordan Crouse
Browse files

msm: kgsl: Add user specified GPU object metadata



Allow the user to optionally specify up to 64 bytes of metadata
to describe the memory object. The strings for each object are
printed in the /d/kgsl/<proc>/mem file.  The user may specify
anything they wish but we strip out non-printable characters
to avoid any evil intent.

Change-Id: Ic0dedbad2c5d80aacd3a2292346a9075bc7f543b
Signed-off-by: default avatarJordan Crouse <jcrouse@codeaurora.org>
parent 4dc6f9f3
Loading
Loading
Loading
Loading
+51 −0
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@
#include <linux/sort.h>
#include <linux/security.h>
#include <linux/compat.h>
#include <linux/ctype.h>

#include "kgsl.h"
#include "kgsl_debugfs.h"
@@ -2970,6 +2971,28 @@ err:
	return ERR_PTR(ret);
}

static void copy_metadata(struct kgsl_mem_entry *entry, uint64_t metadata,
		unsigned int len)
{
	unsigned int i, size;

	if (len == 0)
		return;

	size = min_t(unsigned int, len, sizeof(entry->metadata) - 1);

	if (copy_from_user(entry->metadata, to_user_ptr(metadata), size)) {
		memset(entry->metadata, 0, sizeof(entry->metadata));
		return;
	}

	/* Clean up non printable characters in the string */
	for (i = 0; i < size && entry->metadata[i] != 0; i++) {
		if (!isprint(entry->metadata[i]))
			entry->metadata[i] = '?';
	}
}

long kgsl_ioctl_gpuobj_alloc(struct kgsl_device_private *dev_priv,
		unsigned int cmd, void *data)
{
@@ -2982,6 +3005,8 @@ long kgsl_ioctl_gpuobj_alloc(struct kgsl_device_private *dev_priv,
	if (IS_ERR(entry))
		return PTR_ERR(entry);

	copy_metadata(entry, param->metadata, param->metadata_len);

	param->size = entry->memdesc.size;
	param->flags = entry->memdesc.flags;
	param->mmapsize = kgsl_memdesc_mmapsize(&entry->memdesc);
@@ -3102,6 +3127,32 @@ long kgsl_ioctl_gpuobj_info(struct kgsl_device_private *dev_priv,
	return 0;
}

long kgsl_ioctl_gpuobj_set_info(struct kgsl_device_private *dev_priv,
		unsigned int cmd, void *data)
{
	struct kgsl_process_private *private = dev_priv->process_priv;
	struct kgsl_gpuobj_set_info *param = data;
	struct kgsl_mem_entry *entry;

	if (param->id == 0)
		return -EINVAL;

	entry = kgsl_sharedmem_find_id(private, param->id);
	if (entry == NULL)
		return -EINVAL;

	if (param->flags & KGSL_GPUOBJ_SET_INFO_METADATA)
		copy_metadata(entry, param->metadata, param->metadata_len);

	if (param->flags & KGSL_GPUOBJ_SET_INFO_TYPE) {
		entry->memdesc.flags &= ~KGSL_MEMTYPE_MASK;
		entry->memdesc.flags |= param->type << KGSL_MEMTYPE_SHIFT;
	}

	kgsl_mem_entry_put(entry);
	return 0;
}

long kgsl_ioctl_cff_syncmem(struct kgsl_device_private *dev_priv,
					unsigned int cmd, void *data)
{
+4 −0
Original line number Diff line number Diff line
@@ -189,6 +189,7 @@ struct kgsl_memdesc {
 * @pending_free: if !0, userspace requested that his memory be freed, but there
 *  are still references to it.
 * @dev_priv: back pointer to the device file that created this entry.
 * @metadata: String containing user specified metadata for the entry
 */
struct kgsl_mem_entry {
	struct kref refcount;
@@ -198,6 +199,7 @@ struct kgsl_mem_entry {
	unsigned int id;
	struct kgsl_process_private *priv;
	int pending_free;
	char metadata[KGSL_GPUOBJ_ALLOC_METADATA_MAX + 1];
};

struct kgsl_device_private;
@@ -326,6 +328,8 @@ long kgsl_ioctl_gpuobj_sync(struct kgsl_device_private *dev_priv,
					unsigned int cmd, void *data);
long kgsl_ioctl_gpu_command(struct kgsl_device_private *dev_priv,
				unsigned int cmd, void *data);
long kgsl_ioctl_gpuobj_set_info(struct kgsl_device_private *dev_priv,
				unsigned int cmd, void *data);

void kgsl_mem_entry_destroy(struct kref *kref);

+2 −0
Original line number Diff line number Diff line
@@ -370,6 +370,8 @@ static const struct kgsl_ioctl kgsl_compat_ioctl_funcs[] = {
			kgsl_ioctl_gpuobj_sync),
	KGSL_IOCTL_FUNC(IOCTL_KGSL_GPU_COMMAND,
			kgsl_ioctl_gpu_command),
	KGSL_IOCTL_FUNC(IOCTL_KGSL_GPUOBJ_SET_INFO,
			kgsl_ioctl_gpuobj_set_info),
};

long kgsl_compat_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
+6 −1
Original line number Diff line number Diff line
@@ -130,13 +130,18 @@ static int print_mem_entry(int id, void *ptr, void *data)

	kgsl_get_memory_usage(usage, sizeof(usage), m->flags);

	seq_printf(s, "%pK %pK %16llu %5d %8s %10s %16s %5d\n",
	seq_printf(s, "%pK %pK %16llu %5d %8s %10s %16s %5d",
			(uint64_t *)(uintptr_t) m->gpuaddr,
			(unsigned long *) m->useraddr,
			m->size, entry->id, flags,
			memtype_str(kgsl_memdesc_usermem_type(m)),
			usage, m->sgt->nents);

	if (entry->metadata[0] != 0)
		seq_printf(s, " %s", entry->metadata);

	seq_putc(s, '\n');

	return 0;
}

+2 −0
Original line number Diff line number Diff line
@@ -88,6 +88,8 @@ static const struct kgsl_ioctl kgsl_ioctl_funcs[] = {
			kgsl_ioctl_gpuobj_sync),
	KGSL_IOCTL_FUNC(IOCTL_KGSL_GPU_COMMAND,
			kgsl_ioctl_gpu_command),
	KGSL_IOCTL_FUNC(IOCTL_KGSL_GPUOBJ_SET_INFO,
			kgsl_ioctl_gpuobj_set_info),
};

long kgsl_ioctl_copy_in(unsigned int kernel_cmd, unsigned int user_cmd,
Loading