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

Commit 3204638f authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: kgsl: Enable guard page for GPUOBJ_IMPORT ioctl"

parents c650b665 a4c4bff1
Loading
Loading
Loading
Loading
+4 −0
Original line number Original line Diff line number Diff line
@@ -2252,6 +2252,7 @@ long kgsl_ioctl_gpuobj_import(struct kgsl_device_private *dev_priv,
	struct kgsl_gpuobj_import *param = data;
	struct kgsl_gpuobj_import *param = data;
	struct kgsl_mem_entry *entry;
	struct kgsl_mem_entry *entry;
	int ret, fd = -1;
	int ret, fd = -1;
	struct kgsl_mmu *mmu = &dev_priv->device->mmu;


	entry = kgsl_mem_entry_create();
	entry = kgsl_mem_entry_create();
	if (entry == NULL)
	if (entry == NULL)
@@ -2266,6 +2267,9 @@ long kgsl_ioctl_gpuobj_import(struct kgsl_device_private *dev_priv,


	entry->memdesc.flags = param->flags;
	entry->memdesc.flags = param->flags;


	if (MMU_FEATURE(mmu, KGSL_MMU_NEED_GUARD_PAGE))
		entry->memdesc.priv |= KGSL_MEMDESC_GUARD_PAGE;

	if (param->type == KGSL_USER_MEM_TYPE_ADDR)
	if (param->type == KGSL_USER_MEM_TYPE_ADDR)
		ret = _gpuobj_map_useraddr(dev_priv->device, private->pagetable,
		ret = _gpuobj_map_useraddr(dev_priv->device, private->pagetable,
			entry, param);
			entry, param);
+12 −26
Original line number Original line Diff line number Diff line
@@ -390,11 +390,10 @@ static void _get_entries(struct kgsl_process_private *private,
}
}


static void _find_mem_entries(struct kgsl_mmu *mmu, uint64_t faultaddr,
static void _find_mem_entries(struct kgsl_mmu *mmu, uint64_t faultaddr,
	phys_addr_t ptbase, struct _mem_entry *preventry,
		struct _mem_entry *preventry, struct _mem_entry *nextentry,
	struct _mem_entry *nextentry)
		struct kgsl_context *context)
{
{
	struct kgsl_process_private *private = NULL, *p;
	struct kgsl_process_private *private;
	int id = kgsl_mmu_get_ptname_from_ptbase(mmu, ptbase);


	memset(preventry, 0, sizeof(*preventry));
	memset(preventry, 0, sizeof(*preventry));
	memset(nextentry, 0, sizeof(*nextentry));
	memset(nextentry, 0, sizeof(*nextentry));
@@ -402,22 +401,11 @@ static void _find_mem_entries(struct kgsl_mmu *mmu, uint64_t faultaddr,
	/* Set the maximum possible size as an initial value */
	/* Set the maximum possible size as an initial value */
	nextentry->gpuaddr = (uint64_t) -1;
	nextentry->gpuaddr = (uint64_t) -1;


	mutex_lock(&kgsl_driver.process_mutex);
	if (context) {
	list_for_each_entry(p, &kgsl_driver.process_list, list) {
		private = context->proc_priv;
		if (p->pagetable && (p->pagetable->name == id)) {
			if (kgsl_process_private_get(p))
				private = p;
			break;
		}
	}
	mutex_unlock(&kgsl_driver.process_mutex);

	if (private != NULL) {
		spin_lock(&private->mem_lock);
		spin_lock(&private->mem_lock);
		_get_entries(private, faultaddr, preventry, nextentry);
		_get_entries(private, faultaddr, preventry, nextentry);
		spin_unlock(&private->mem_lock);
		spin_unlock(&private->mem_lock);

		kgsl_process_private_put(private);
	}
	}
}
}


@@ -467,6 +455,7 @@ static int kgsl_iommu_fault_handler(struct iommu_domain *domain,
	struct kgsl_iommu_context *ctx;
	struct kgsl_iommu_context *ctx;
	u64 ptbase;
	u64 ptbase;
	u32 contextidr;
	u32 contextidr;
	pid_t tid = 0;
	pid_t ptname;
	pid_t ptname;
	struct _mem_entry prev, next;
	struct _mem_entry prev, next;
	int write;
	int write;
@@ -507,9 +496,7 @@ static int kgsl_iommu_fault_handler(struct iommu_domain *domain,
	if (context != NULL) {
	if (context != NULL) {
		/* save pagefault timestamp for GFT */
		/* save pagefault timestamp for GFT */
		set_bit(KGSL_CONTEXT_PRIV_PAGEFAULT, &context->priv);
		set_bit(KGSL_CONTEXT_PRIV_PAGEFAULT, &context->priv);

		tid = context->tid;
		kgsl_context_put(context);
		context = NULL;
	}
	}


	ctx->fault = 1;
	ctx->fault = 1;
@@ -535,7 +522,8 @@ static int kgsl_iommu_fault_handler(struct iommu_domain *domain,
	ptbase = KGSL_IOMMU_GET_CTX_REG_Q(ctx, TTBR0);
	ptbase = KGSL_IOMMU_GET_CTX_REG_Q(ctx, TTBR0);
	contextidr = KGSL_IOMMU_GET_CTX_REG(ctx, CONTEXTIDR);
	contextidr = KGSL_IOMMU_GET_CTX_REG(ctx, CONTEXTIDR);


	ptname = kgsl_mmu_get_ptname_from_ptbase(mmu, ptbase);
	ptname = MMU_FEATURE(mmu, KGSL_MMU_GLOBAL_PAGETABLE) ?
		KGSL_MMU_GLOBAL_PT : tid;


	if (test_bit(KGSL_FT_PAGEFAULT_LOG_ONE_PER_PAGE,
	if (test_bit(KGSL_FT_PAGEFAULT_LOG_ONE_PER_PAGE,
		&adreno_dev->ft_pf_policy))
		&adreno_dev->ft_pf_policy))
@@ -556,8 +544,7 @@ static int kgsl_iommu_fault_handler(struct iommu_domain *domain,
			KGSL_LOG_DUMP(ctx->kgsldev,
			KGSL_LOG_DUMP(ctx->kgsldev,
				"---- nearby memory ----\n");
				"---- nearby memory ----\n");


			_find_mem_entries(mmu, addr, ptbase, &prev, &next);
			_find_mem_entries(mmu, addr, &prev, &next, context);

			if (prev.gpuaddr)
			if (prev.gpuaddr)
				_print_entry(ctx->kgsldev, &prev);
				_print_entry(ctx->kgsldev, &prev);
			else
			else
@@ -570,13 +557,11 @@ static int kgsl_iommu_fault_handler(struct iommu_domain *domain,
				_print_entry(ctx->kgsldev, &next);
				_print_entry(ctx->kgsldev, &next);
			else
			else
				KGSL_LOG_DUMP(ctx->kgsldev, "*EMPTY*\n");
				KGSL_LOG_DUMP(ctx->kgsldev, "*EMPTY*\n");

		}
		}
	}
	}


	trace_kgsl_mmu_pagefault(ctx->kgsldev, addr,
	trace_kgsl_mmu_pagefault(ctx->kgsldev, addr,
			kgsl_mmu_get_ptname_from_ptbase(mmu, ptbase),
			ptname, write ? "write" : "read");
			write ? "write" : "read");


	/*
	/*
	 * We do not want the h/w to resume fetching data from an iommu
	 * We do not want the h/w to resume fetching data from an iommu
@@ -602,6 +587,7 @@ static int kgsl_iommu_fault_handler(struct iommu_domain *domain,
		adreno_dispatcher_schedule(device);
		adreno_dispatcher_schedule(device);
	}
	}


	kgsl_context_put(context);
	return ret;
	return ret;
}
}


+0 −22
Original line number Original line Diff line number Diff line
@@ -217,28 +217,6 @@ kgsl_mmu_detach_pagetable(struct kgsl_pagetable *pagetable)
	pagetable_remove_sysfs_objects(pagetable);
	pagetable_remove_sysfs_objects(pagetable);
}
}


int
kgsl_mmu_get_ptname_from_ptbase(struct kgsl_mmu *mmu, u64 pt_base)
{
	struct kgsl_pagetable *pt;
	int ptid = -1;

	if (!MMU_OP_VALID(mmu, mmu_pt_equal))
		return KGSL_MMU_GLOBAL_PT;

	spin_lock(&kgsl_driver.ptlock);
	list_for_each_entry(pt, &kgsl_driver.pagetable_list, list) {
		if (mmu->mmu_ops->mmu_pt_equal(mmu, pt, pt_base)) {
			ptid = (int) pt->name;
			break;
		}
	}
	spin_unlock(&kgsl_driver.ptlock);

	return ptid;
}
EXPORT_SYMBOL(kgsl_mmu_get_ptname_from_ptbase);

struct kgsl_pagetable *kgsl_mmu_get_pt_from_ptname(struct kgsl_mmu *mmu,
struct kgsl_pagetable *kgsl_mmu_get_pt_from_ptname(struct kgsl_mmu *mmu,
						int ptname)
						int ptname)
{
{
+0 −1
Original line number Original line Diff line number Diff line
@@ -166,7 +166,6 @@ int kgsl_mmu_unmap(struct kgsl_pagetable *pagetable,
void kgsl_mmu_put_gpuaddr(struct kgsl_pagetable *pagetable,
void kgsl_mmu_put_gpuaddr(struct kgsl_pagetable *pagetable,
		 struct kgsl_memdesc *memdesc);
		 struct kgsl_memdesc *memdesc);
unsigned int kgsl_virtaddr_to_physaddr(void *virtaddr);
unsigned int kgsl_virtaddr_to_physaddr(void *virtaddr);
int kgsl_mmu_get_ptname_from_ptbase(struct kgsl_mmu *mmu, u64 pt_base);
unsigned int kgsl_mmu_log_fault_addr(struct kgsl_mmu *mmu,
unsigned int kgsl_mmu_log_fault_addr(struct kgsl_mmu *mmu,
		u64 ttbr0, uint64_t addr);
		u64 ttbr0, uint64_t addr);
enum kgsl_mmutype kgsl_mmu_get_mmutype(struct kgsl_device *device);
enum kgsl_mmutype kgsl_mmu_get_mmutype(struct kgsl_device *device);
+9 −9
Original line number Original line Diff line number Diff line
@@ -129,11 +129,10 @@ static size_t snapshot_os(struct kgsl_device *device,
{
{
	struct kgsl_snapshot_linux *header = (struct kgsl_snapshot_linux *)buf;
	struct kgsl_snapshot_linux *header = (struct kgsl_snapshot_linux *)buf;
	struct kgsl_pwrctrl *pwr = &device->pwrctrl;
	struct kgsl_pwrctrl *pwr = &device->pwrctrl;
	struct task_struct *task;
	pid_t pid;
	int ctxtcount = 0;
	int ctxtcount = 0;
	size_t size = sizeof(*header);
	size_t size = sizeof(*header);
	u64 temp_ptbase;
	u64 temp_ptbase;
	struct kgsl_context *context;


	/* Figure out how many active contexts there are - these will
	/* Figure out how many active contexts there are - these will
	 * be appended on the end of the structure */
	 * be appended on the end of the structure */
@@ -176,19 +175,20 @@ static size_t snapshot_os(struct kgsl_device *device,
	kgsl_sharedmem_readl(&device->memstore, &header->current_context,
	kgsl_sharedmem_readl(&device->memstore, &header->current_context,
		KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL, current_context));
		KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL, current_context));


	context = kgsl_context_get(device, header->current_context);


	/* Get the current PT base */
	/* Get the current PT base */
	temp_ptbase = kgsl_mmu_get_current_ttbr0(&device->mmu);
	temp_ptbase = kgsl_mmu_get_current_ttbr0(&device->mmu);
	/* Truncate to 32 bits in case LPAE is used */
	/* Truncate to 32 bits in case LPAE is used */
	header->ptbase = (__u32)temp_ptbase;
	header->ptbase = (__u32)temp_ptbase;
	/* And the PID for the task leader */
	/* And the PID for the task leader */
	pid = header->pid = kgsl_mmu_get_ptname_from_ptbase(&device->mmu,
	if (context) {
								temp_ptbase);
		header->pid = context->tid;

		strlcpy(header->comm, context->proc_priv->comm,
	task = find_task_by_vpid(pid);
				sizeof(header->comm));

		kgsl_context_put(context);
	if (task)
		context = NULL;
		get_task_comm(header->comm, task);
	}


	header->ctxtcount = ctxtcount;
	header->ctxtcount = ctxtcount;